--- /dev/null
+#
+# Parts of the development effort for this project have been
+# sponsored by SIEMENS AG, Austria. Thanks to SIEMENS for
+# supporting an Open Source project!
+#
+#
+# This is at least a partial credits-file of individual people that
+# have contributed to the U-Boot project. It is sorted by name and
+# formatted to allow easy grepping and beautification by scripts.
+# The fields are: name (N), email (E), web-address (W), PGP key ID
+# and fingerprint (P), description (D), and snail-mail address (S).
+# Thanks,
+#
+# Wolfgang Denk
+#----------
+
+N: Dr. Bruno Achauer
+E: bruno@exet-ag.de
+D: Support for NetBSD (both as host and target system)
+
+N: Swen Anderson
+E: sand@peppercon.de
+D: ERIC Support
+
+N: Guillaume Alexandre
+E: guillaume.alexandre@gespac.ch
+D: Add PCIPPC6 configuration
+
+N: Pierre Aubert
+E: <p.aubert@staubli.com>
+D: Support for RPXClassic board
+
+N: Andre Beaudin
+E: <andre.beaudin@colubris.com>
+D: PCMCIA, Ethernet, TFTP
+
+N: Jerry van Baren
+E: <vanbaren@cideas.com>
+D: BedBug port to 603e core (MPC82xx). Code for enhanced memory test.
+
+N: Raphael Bossek
+E: raphael.bossek@solutions4linux.de
+D: 8xxrom-0.3.0
+
+N: David Brown
+E: DBrown03@harris.com
+D: Extensions to 8xxrom-0.3.0
+
+N: Oliver Brown
+E: obrown@adventnetworks.com
+D: Port to the gw8260 board
+
+N: Jonathan De Bruyne
+E: jonathan.debruyne@siemens.atea.be
+D: Port to Siemens IAD210 board
+
+N: Conn Clark
+E: clark@esteem.com
+D: ESTEEM192E support
+
+N: Magnus Damm
+E: eramdam@kieray1.p.y.ki.era.ericsson.se
+D: 8xxrom
+
+N: Kári DavÃðsson
+E: kd@flaga.is
+D: FLAGA DM Support
+
+N: Wolfgang Denk
+E: wd@denx.de
+D: U-Boot initial version, continuing maintenance, ARMBoot merge
+W: http://www.denx.de
+
+N: Dan A. Dickey
+E: ddickey@charter.net
+D: FADS Support
+
+N: James F. Dougherty
+E: jfd@GigabitNetworks.COM
+D: Port to the MOUSSE board
+
+N: Dave Ellis
+E: DGE@sixnetio.com
+D: EEPROM Speedup, SXNI855T port
+
+N: Dr. Wolfgang Grandegger
+E: wg@denx.de
+D: Support for Interphase 4539 T1/E1/J1 PMC, PN62, CCM, SCM boards
+W: www.denx.de
+
+N: Frank Gottschling
+E: fgottschling@eltec.de
+D: Support for ELTEC MHPC/BAB7xx/ELPPC boards, cfb-console, i8042, SMI LynxEM
+W: www.eltec.de
+
+N: Marius Groeger
+E: mgroeger@sysgo.de
+D: MBX Support, board specific function interface, EST SBC8260 support; initial support for StrongARM (LART), ARM720TDMI (implementa A7)
+W: www.elinos.com
+
+N: Kirk Haderlie
+E: khaderlie@vividimage.com
+D: Added TFTP to 8xxrom (-> 0.3.1)
+
+N: Chris Hallinan
+E: clh@net1plus.com
+D: DHCP Support
+
+N: Anne-Sophie Harnois
+E: Anne-Sophie.Harnois@nextream.fr
+D: Port to Walnut405 board
+
+N: Andreas Heppel
+E: aheppel@sysgo.de
+D: CPU Support for MPC 75x; board support for Eltec BAB750 [obsolete!]
+
+N: Josh Huber
+E: huber@alum.wpi.edu
+D: Port to the Galileo Evaluation Board, and the MPC74xx cpu series.
+W: http://www.mclx.com/
+
+H: Stuart Hughes
+E: stuarth@lineo.com
+D: Port to MPC8260ADS board
+
+H: Rich Ireland
+E: r.ireland@computer.org
+D: FPGA device configuration driver
+
+N: Gary Jennejohn
+E: garyj@jennejohn.org, gj@denx.de
+D: Support for Samsung ARM920T S3C2400X, ARM920T "TRAB"
+W: www.denx.de
+
+N: Murray Jensen
+E: Murray.Jensen@cmst.csiro.au
+D: Initial 8260 support; GDB support
+D: Port to Cogent+Hymod boards; Hymod Board Database
+W: http://www.msa.cmst.csiro.au/ourstaff/MurrayJensen/mjj.html
+
+N: Yoo. Jonghoon
+E: yooth@ipone.co.kr
+D: Added port to the RPXlite board
+
+N: Brad Kemp
+E: Brad.Kemp@seranoa.com
+D: Port to Windriver ppmc8260 board
+
+N: Thomas Koeller
+E: tkoeller@gmx.net
+D: Port to Motorola Sandpoint 3 (MPC8240)
+
+N: Thomas Lange
+E: thomas@corelatus.com
+D: Support for GTH board; lots of PCMCIA fixes
+
+N: Raymond Lo
+E: lo@routefree.com
+D: Support for DOS partitions
+
+N: Dan Malek
+E: dan@netx4.com
+D: FADSROM, the grandfather of all of this
+
+N: Jay Monkman
+E: jtm@smoothsmoothie.com
+D: EST SBC8260 support
+
+N: Frank Morauf
+E: frank.morauf@salzbrenner.com
+D: Support for Embedded Planet RPX Super Board
+
+N: David Müller
+E: d.mueller@elsoft.ch
+D: Support for Samsung ARM920T SMDK2410 eval board
+
+N: Rolf Offermanns
+E: rof@sysgo.de
+D: Initial support for SSV-DNP1110, SMC91111 driver
+W: www.elinos.com
+
+N: Keith Outwater
+E: Keith_Outwater@mvis.com
+D: Support for GEN860T board
+
+N: Keith Outwater
+E: keith_outwater@mvis.com
+D: Support for generic/custom MPC860T board (GEN860T)
+
+N: Frank Panno
+E: fpanno@delphintech.com
+D: Support for Embedded Planet EP8260 Board
+
+N: Denis Peter
+E: d.peter@mpl.ch
+D: Support for 4xx SCSI, floppy, CDROM, CT69000 video, ...
+D: Support for PIP405 board
+D: Support for MIP405 board
+
+N: Bill Pitts
+E: wlp@mindspring.com
+D: BedBug embedded debugger code
+
+N: Stefan Roese
+E: stefan.roese@esd-electronics.com
+D: IBM PPC401/403/405GP Support; Windows environment support
+
+N: Neil Russell
+E: caret@c-side.com
+D: Author of LiMon-1.4.2, which contributed some ideas
+
+N: Paolo Scaffardi
+E: arsenio@tin.it
+D: FADS823 configuration, MPC823 video support, I2C, wireless keyboard, lots more
+
+N: Robert Schwebel
+E: r.schwebel@pengutronix.de
+D: Support for csb226 board (xscale)
+N: Rob Taylor
+E: robt@flyingpig.com
+D: Port to MBX860T and Sandpoint8240
+
+N: Erik Theisen
+E: etheisen@mindspring.com
+D: MBX8xx and many other patches
+
+N: Jim Thompson
+E: jim@musenki.com
+D: Support for MUSENKI board
+
+N: David Updegraff
+E: dave@cray.com
+D: Port to Cray L1 board; DHCP vendor extensions
+
+N: Christian Vejlbo
+E: christian.vejlbo@tellabs.com
+D: FADS860T ethernet support
+
+N: Alex Zuepke
+E: azu@sysgo.de
+D: Overall improvements on StrongARM, ARM720TDMI; Support for Tuxscreen; initial PCMCIA support for ARM
+W: www.elinos.com
--- /dev/null
+#
+# (C) Copyright 2000 - 2002
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+Summary:
+========
+
+This directory contains the source code for U-Boot, a monitor for
+Embedded PowerPC boards, which can be installed in a boot ROM and
+used to test the hardware or download and run application code.
+
+The development of U-Boot is closely related to Linux: some parts of
+the source code originate in the Linux source tree, we still have
+some header files in common, and special provision has been made to
+support booting of Linux images.
+
+Some attention has been paid to make this software easily
+configurable and extendable. For instance, all monitor commands are
+implemented with the same call interface, so that it's very easy to
+add new commands. Also, instead of permanently adding rarely used
+code (for instance hardware test utilities) to the monitor, you can
+load and run it dynamically.
+
+
+Status:
+=======
+
+In general, all boards for which a configuration option exists in the
+Makefile have been tested to some extent and can be considered
+"working". In fact, many of them are used in production systems.
+
+In case of problems see the CHANGELOG and CREDITS files to find out
+who contributed the specific port.
+
+Exception from this rule: the port to the Sandpoint 8240 has not been
+completed yet.
+
+
+Where to get help:
+==================
+
+In case you have questions about, problems with or contributions for
+U-Boot you should send a message to the U-Boot mailing list at
+<u-boot-users@lists.sourceforge.net>. There is also an archive of
+previous traffic on the mailing list - please search the archive
+before asking FAQ's. Please see
+http://lists.sourceforge.net/lists/listinfo/u-boot-users/
+
+
+Where we come from:
+===================
+
+- start from 8xxrom sources
+- clean up code
+- make it easier to add custom boards
+- make it possible to add other [PowerPC] CPUs
+- extend functions, especially:
+ * Provide extended interface to Linux boot loader
+ * S-Record download
+ * network boot
+ * PCMCIA / CompactFLash / ATA disk / SCSI ... boot
+- add other CPU families (starting with ARM)
+
+
+Directory Hierarchy:
+====================
+
+- board Board dependend files
+- common Misc architecture independend functions
+- cpu CPU specific files
+- disk Code for disk drive partition handling
+- doc Documentation (don't expect too much)
+- drivers Common used device drivers
+- dtt Digital Thermometer and Thermostat drivers
+- examples Example code for standalone applications, etc.
+- include Header Files
+- disk Harddisk interface code
+- net Networking code
+- ppc Files generic to PowerPC architecture
+- post Power On Self Test
+- post/arch Symlink to architecture specific Power On Self Test
+- post/arch-ppc PowerPC architecture specific Power On Self Test
+- post/cpu/mpc8260 MPC8260 CPU specific Power On Self Test
+- post/cpu/mpc8xx MPC8xx CPU specific Power On Self Test
+- rtc Real Time Clock drivers
+- tools Tools to build S-Record or U-Boot images, etc.
+
+- cpu/74xx_7xx Files specific to Motorola MPC74xx and 7xx CPUs
+- cpu/mpc8xx Files specific to Motorola MPC8xx CPUs
+- cpu/mpc824x Files specific to Motorola MPC824x CPUs
+- cpu/mpc8260 Files specific to Motorola MPC8260 CPU
+- cpu/ppc4xx Files specific to IBM 4xx CPUs
+
+- board/RPXClassic
+ Files specific to RPXClassic boards
+- board/RPXlite Files specific to RPXlite boards
+- board/c2mon Files specific to c2mon boards
+- board/cogent Files specific to Cogent boards
+ (need further configuration)
+ Files specific to CPCIISER4 boards
+- board/cpu86 Files specific to CPU86 boards
+- board/cray/ Files specific to boards manufactured by Cray
+- board/cray/L1 Files specific to L1 boards
+- board/cu824 Files specific to CU824 boards
+- board/ebony Files specific to IBM Ebony board
+- board/eric Files specific to ERIC boards
+- board/esd/ Files specific to boards manufactured by ESD
+- board/esd/adciop Files specific to ADCIOP boards
+- board/esd/ar405 Files specific to AR405 boards
+- board/esd/canbt Files specific to CANBT boards
+- board/esd/cpci405 Files specific to CPCI405 boards
+- board/esd/cpciiser4 Files specific to CPCIISER4 boards
+- board/esd/common Common files for ESD boards
+- board/esd/dasa_sim Files specific to DASA_SIM boards
+- board/esd/du405 Files specific to DU405 boards
+- board/esd/ocrtc Files specific to OCRTC boards
+- board/esd/pci405 Files specific to PCI405 boards
+- board/esteem192e
+ Files specific to ESTEEM192E boards
+- board/etx094 Files specific to ETX_094 boards
+- board/evb64260
+ Files specific to EVB64260 boards
+- board/fads Files specific to FADS boards
+- board/flagadm Files specific to FLAGADM boards
+- board/gen860t Files specific to GEN860T boards
+- board/genietv Files specific to GENIETV boards
+- board/gth Files specific to GTH boards
+- board/hermes Files specific to HERMES boards
+- board/hymod Files specific to HYMOD boards
+- board/icu862 Files specific to ICU862 boards
+- board/ip860 Files specific to IP860 boards
+- board/iphase4539
+ Files specific to Interphase4539 boards
+- board/ivm Files specific to IVMS8/IVML24 boards
+- board/lantec Files specific to LANTEC boards
+- board/lwmon Files specific to LWMON boards
+- board/mbx8xx Files specific to MBX boards
+- board/mpc8260ads
+ Files specific to MMPC8260ADS boards
+- board/mpl/ Files specific to boards manufactured by MPL
+- board/mpl/common Common files for MPL boards
+- board/mpl/pip405 Files specific to PIP405 boards
+- board/mpl/mip405 Files specific to MIP405 boards
+- board/musenki Files specific to MUSEKNI boards
+- board/mvs1 Files specific to MVS1 boards
+- board/nx823 Files specific to NX823 boards
+- board/oxc Files specific to OXC boards
+- board/pcippc2 Files specific to PCIPPC2/PCIPPC6 boards
+- board/pm826 Files specific to PM826 boards
+- board/ppmc8260
+ Files specific to PPMC8260 boards
+- board/rpxsuper
+ Files specific to RPXsuper boards
+- board/rsdproto
+ Files specific to RSDproto boards
+- board/sandpoint
+ Files specific to Sandpoint boards
+- board/sbc8260 Files specific to SBC8260 boards
+- board/sacsng Files specific to SACSng boards
+- board/siemens Files specific to boards manufactured by Siemens AG
+- board/siemens/CCM Files specific to CCM boards
+- board/siemens/IAD210 Files specific to IAD210 boards
+- board/siemens/SCM Files specific to SCM boards
+- board/siemens/pcu_e Files specific to PCU_E boards
+- board/sixnet Files specific to SIXNET boards
+- board/spd8xx Files specific to SPD8xxTS boards
+- board/tqm8260 Files specific to TQM8260 boards
+- board/tqm8xx Files specific to TQM8xxL boards
+- board/w7o Files specific to W7O boards
+- board/walnut405
+ Files specific to Walnut405 boards
+- board/westel/ Files specific to boards manufactured by Westel Wireless
+- board/westel/amx860 Files specific to AMX860 boards
+- board/utx8245 Files specific to UTX8245 boards
+
+Software Configuration:
+=======================
+
+Configuration is usually done using C preprocessor defines; the
+rationale behind that is to avoid dead code whenever possible.
+
+There are two classes of configuration variables:
+
+* Configuration _OPTIONS_:
+ These are selectable by the user and have names beginning with
+ "CONFIG_".
+
+* Configuration _SETTINGS_:
+ These depend on the hardware etc. and should not be meddled with if
+ you don't know what you're doing; they have names beginning with
+ "CFG_".
+
+Later we will add a configuration tool - probably similar to or even
+identical to what's used for the Linux kernel. Right now, we have to
+do the configuration by hand, which means creating some symbolic
+links and editing some configuration files. We use the TQM8xxL boards
+as an example here.
+
+
+Selection of Processor Architecture and Board Type:
+---------------------------------------------------
+
+For all supported boards there are ready-to-use default
+configurations available; just type "make <board_name>_config".
+
+Example: For a TQM823L module type:
+
+ cd u-boot
+ make TQM823L_config
+
+For the Cogent platform, you need to specify the cpu type as well;
+e.g. "make cogent_mpc8xx_config". And also configure the cogent
+directory according to the instructions in cogent/README.
+
+
+Configuration Options:
+----------------------
+
+Configuration depends on the combination of board and CPU type; all
+such information is kept in a configuration file
+"include/configs/<board_name>.h".
+
+Example: For a TQM823L module, all configuration settings are in
+"include/configs/TQM823L.h".
+
+
+The following options need to be configured:
+
+- CPU Type: Define exactly one of
+
+ PowerPC based CPUs:
+ -------------------
+ CONFIG_MPC823, CONFIG_MPC850, CONFIG_MPC855, CONFIG_MPC860
+ or CONFIG_MPC824X, CONFIG_MPC8260
+ or CONFIG_IOP480
+ or CONFIG_405GP
+ or CONFIG_440
+ or CONFIG_MPC74xx
+
+ ARM based CPUs:
+ ---------------
+ CONFIG_SA1110
+ CONFIG_ARM7
+ CONFIG_PXA250
+
+
+- Board Type: Define exactly one of
+
+ PowerPC based boards:
+ ---------------------
+
+ CONFIG_ADCIOP, CONFIG_ICU862 CONFIG_RPXsuper,
+ CONFIG_ADS860, CONFIG_IP860, CONFIG_SM850,
+ CONFIG_AMX860, CONFIG_IPHASE4539, CONFIG_SPD823TS,
+ CONFIG_AR405, CONFIG_IVML24, CONFIG_SXNI855T,
+ CONFIG_BAB7xx, CONFIG_IVML24_128, CONFIG_Sandpoint8240,
+ CONFIG_CANBT, CONFIG_IVML24_256, CONFIG_Sandpoint8245,
+ CONFIG_CCM, CONFIG_IVMS8, CONFIG_TQM823L,
+ CONFIG_CPCI405, CONFIG_IVMS8_128, CONFIG_TQM850L,
+ CONFIG_CPCI4052, CONFIG_IVMS8_256, CONFIG_TQM855L,
+ CONFIG_CPCIISER4, CONFIG_LANTEC, CONFIG_TQM860L,
+ CONFIG_CPU86, CONFIG_MBX, CONFIG_TQM8260,
+ CONFIG_CRAYL1, CONFIG_MBX860T, CONFIG_TTTech,
+ CONFIG_CU824, CONFIG_MHPC, CONFIG_UTX8245,
+ CONFIG_DASA_SIM, CONFIG_MIP405, CONFIG_W7OLMC,
+ CONFIG_DU405, CONFIG_MOUSSE, CONFIG_W7OLMG,
+ CONFIG_ELPPC, CONFIG_MPC8260ADS, CONFIG_WALNUT405,
+ CONFIG_ERIC, CONFIG_MUSENKI, CONFIG_ZUMA,
+ CONFIG_ESTEEM192E, CONFIG_MVS1, CONFIG_c2mon,
+ CONFIG_ETX094, CONFIG_NX823, CONFIG_cogent_mpc8260,
+ CONFIG_EVB64260, CONFIG_OCRTC, CONFIG_cogent_mpc8xx,
+ CONFIG_FADS823, CONFIG_ORSG, CONFIG_ep8260,
+ CONFIG_FADS850SAR, CONFIG_OXC, CONFIG_gw8260,
+ CONFIG_FADS860T, CONFIG_PCI405, CONFIG_hermes,
+ CONFIG_FLAGADM, CONFIG_PCIPPC2, CONFIG_hymod,
+ CONFIG_FPS850L, CONFIG_PCIPPC6, CONFIG_lwmon,
+ CONFIG_GEN860T, CONFIG_PIP405, CONFIG_pcu_e,
+ CONFIG_GENIETV, CONFIG_PM826, CONFIG_ppmc8260,
+ CONFIG_GTH, CONFIG_RPXClassic, CONFIG_rsdproto,
+ CONFIG_IAD210, CONFIG_RPXlite, CONFIG_sbc8260,
+ CONFIG_EBONY, CONFIG_sacsng
+
+ ARM based boards:
+ -----------------
+
+ CONFIG_HHP_CRADLE, CONFIG_DNP1110, CONFIG_EP7312,
+ CONFIG_IMPA7, CONFIG_LART, CONFIG_LUBBOCK,
+ CONFIG_SHANNON, CONFIG_SMDK2400, CONFIG_SMDK2410,
+ CONFIG_TRAB
+
+
+- CPU Module Type: (if CONFIG_COGENT is defined)
+ Define exactly one of
+ CONFIG_CMA286_60_OLD
+--- FIXME --- not tested yet:
+ CONFIG_CMA286_60, CONFIG_CMA286_21, CONFIG_CMA286_60P,
+ CONFIG_CMA287_23, CONFIG_CMA287_50
+
+- Motherboard Type: (if CONFIG_COGENT is defined)
+ Define exactly one of
+ CONFIG_CMA101, CONFIG_CMA102
+
+- Motherboard I/O Modules: (if CONFIG_COGENT is defined)
+ Define one or more of
+ CONFIG_CMA302
+
+- Motherboard Options: (if CONFIG_CMA101 or CONFIG_CMA102 are defined)
+ Define one or more of
+ CONFIG_LCD_HEARTBEAT - update a character position on
+ the lcd display every second with
+ a "rotator" |\-/|\-/
+
+- MPC824X Family Member (if CONFIG_MPC824X is defined)
+ Define exactly one of
+ CONFIG_MPC8240, CONFIG_MPC8245
+
+- 8xx CPU Options: (if using an 8xx cpu)
+ Define one or more of
+ CONFIG_8xx_GCLK_FREQ - if get_gclk_freq() can not work e.g.
+ no 32KHz reference PIT/RTC clock
+
+- Clock Interface:
+ CONFIG_CLOCKS_IN_MHZ
+
+ U-Boot stores all clock information in Hz
+ internally. For binary compatibility with older Linux
+ kernels (which expect the clocks passed in the
+ bd_info data to be in MHz) the environment variable
+ "clocks_in_mhz" can be defined so that U-Boot
+ converts clock data to MHZ before passing it to the
+ Linux kernel.
+
+ When CONFIG_CLOCKS_IN_MHZ is defined, a definition of
+ "clocks_in_mhz=1" is automatically included in the
+ default environment.
+
+- Console Interface:
+ Depending on board, define exactly one serial port
+ (like CONFIG_8xx_CONS_SMC1, CONFIG_8xx_CONS_SMC2,
+ CONFIG_8xx_CONS_SCC1, ...), or switch off the serial
+ console by defining CONFIG_8xx_CONS_NONE
+
+ Note: if CONFIG_8xx_CONS_NONE is defined, the serial
+ port routines must be defined elsewhere
+ (i.e. serial_init(), serial_getc(), ...)
+
+ CONFIG_CFB_CONSOLE
+ Enables console device for a color framebuffer. Needs following
+ defines (cf. smiLynxEM, i8042, board/eltec/bab7xx)
+ VIDEO_FB_LITTLE_ENDIAN graphic memory organisation
+ (default big endian)
+ VIDEO_HW_RECTFILL graphic chip supports
+ rectangle fill
+ (cf. smiLynxEM)
+ VIDEO_HW_BITBLT graphic chip supports
+ bit-blit (cf. smiLynxEM)
+ VIDEO_VISIBLE_COLS visible pixel columns
+ (cols=pitch)
+ VIDEO_VISIBLE_ROWS visible pixel rows
+ VIDEO_PIXEL_SIZE bytes per pixel
+ VIDEO_DATA_FORMAT graphic data format
+ (0-5, cf. cfb_console.c)
+ VIDEO_FB_ADRS framebuffer address
+ VIDEO_KBD_INIT_FCT keyboard int fct
+ (i.e. i8042_kbd_init())
+ VIDEO_TSTC_FCT test char fct
+ (i.e. i8042_tstc)
+ VIDEO_GETC_FCT get char fct
+ (i.e. i8042_getc)
+ CONFIG_CONSOLE_CURSOR cursor drawing on/off
+ (requires blink timer
+ cf. i8042.c)
+ CFG_CONSOLE_BLINK_COUNT blink interval (cf. i8042.c)
+ CONFIG_CONSOLE_TIME display time/date info in
+ upper right corner
+ (requires CFG_CMD_DATE)
+ CONFIG_VIDEO_LOGO display Linux logo in
+ upper left corner
+ CONFIG_CONSOLE_EXTRA_INFO
+ addional board info beside
+ the logo
+
+ When CONFIG_CFB_CONSOLE is defined, video console is
+ default i/o. Serial console can be forced with
+ environment 'console=serial'.
+
+- Console Baudrate:
+ CONFIG_BAUDRATE - in bps
+ Select one of the baudrates listed in
+ CFG_BAUDRATE_TABLE, see below.
+
+- Interrupt driven serial port input:
+ CONFIG_SERIAL_SOFTWARE_FIFO
+
+ PPC405GP only.
+ Use an interrupt handler for receiving data on the
+ serial port. It also enables using hardware handshake
+ (RTS/CTS) and UART's built-in FIFO. Set the number of
+ bytes the interrupt driven input buffer should have.
+
+ Set to 0 to disable this feature (this is the default).
+ This will also disable hardware handshake.
+
+- Boot Delay: CONFIG_BOOTDELAY - in seconds
+ Delay before automatically booting the default image;
+ set to -1 to disable autoboot.
+
+ See doc/README.autoboot for these options that
+ work with CONFIG_BOOTDELAY. None are required.
+ CONFIG_BOOT_RETRY_TIME
+ CONFIG_BOOT_RETRY_MIN
+ CONFIG_AUTOBOOT_KEYED
+ CONFIG_AUTOBOOT_PROMPT
+ CONFIG_AUTOBOOT_DELAY_STR
+ CONFIG_AUTOBOOT_STOP_STR
+ CONFIG_AUTOBOOT_DELAY_STR2
+ CONFIG_AUTOBOOT_STOP_STR2
+ CONFIG_ZERO_BOOTDELAY_CHECK
+ CONFIG_RESET_TO_RETRY
+
+- Autoboot Command:
+ CONFIG_BOOTCOMMAND
+ Only needed when CONFIG_BOOTDELAY is enabled;
+ define a command string that is automatically executed
+ when no character is read on the console interface
+ within "Boot Delay" after reset.
+
+ CONFIG_BOOTARGS
+ This can be used to pass arguments to the bootm
+ command. The value of CONFIG_BOOTARGS goes into the
+ environment value "bootargs".
+
+ CONFIG_RAMBOOT and CONFIG_NFSBOOT
+ The value of these goes into the environment as
+ "ramboot" and "nfsboot" respectively, and can be used
+ as a convenience, when switching between booting from
+ ram and nfs.
+
+- Pre-Boot Commands:
+ CONFIG_PREBOOT
+
+ When this option is #defined, the existence of the
+ environment variable "preboot" will be checked
+ immediately before starting the CONFIG_BOOTDELAY
+ countdown and/or running the auto-boot command resp.
+ entering interactive mode.
+
+ This feature is especially useful when "preboot" is
+ automatically generated or modified. For an example
+ see the LWMON board specific code: here "preboot" is
+ modified when the user holds down a certain
+ combination of keys on the (special) keyboard when
+ booting the systems
+
+- Serial Download Echo Mode:
+ CONFIG_LOADS_ECHO
+ If defined to 1, all characters received during a
+ serial download (using the "loads" command) are
+ echoed back. This might be needed by some terminal
+ emulations (like "cu"), but may as well just take
+ time on others. This setting #define's the initial
+ value of the "loads_echo" environment variable.
+
+- Kgdb Serial Baudrate: (if CFG_CMD_KGDB is defined)
+ CONFIG_KGDB_BAUDRATE
+ Select one of the baudrates listed in
+ CFG_BAUDRATE_TABLE, see below.
+
+- Monitor Functions:
+ CONFIG_COMMANDS
+ Most monitor functions can be selected (or
+ de-selected) by adjusting the definition of
+ CONFIG_COMMANDS; to select individual functions,
+ #define CONFIG_COMMANDS by "OR"ing any of the
+ following values:
+
+ #define enables commands:
+ -------------------------
+ CFG_CMD_ASKENV * ask for env variable
+ CFG_CMD_BDI bdinfo
+ CFG_CMD_BEDBUG Include BedBug Debugger
+ CFG_CMD_BOOTD bootd
+ CFG_CMD_CACHE icache, dcache
+ CFG_CMD_CONSOLE coninfo
+ CFG_CMD_DATE * support for RTC, date/time...
+ CFG_CMD_DHCP DHCP support
+ CFG_CMD_ECHO * echo arguments
+ CFG_CMD_EEPROM * EEPROM read/write support
+ CFG_CMD_ELF bootelf, bootvx
+ CFG_CMD_ENV saveenv
+ CFG_CMD_FDC * Floppy Disk Support
+ CFG_CMD_FLASH flinfo, erase, protect
+ CFG_CMD_FPGA FPGA device initialization support
+ CFG_CMD_I2C * I2C serial bus support
+ CFG_CMD_IDE * IDE harddisk support
+ CFG_CMD_IMI iminfo
+ CFG_CMD_IMMAP * IMMR dump support
+ CFG_CMD_IRQ * irqinfo
+ CFG_CMD_KGDB * kgdb
+ CFG_CMD_LOADB loadb
+ CFG_CMD_LOADS loads
+ CFG_CMD_MEMORY md, mm, nm, mw, cp, cmp, crc, base,
+ loop, mtest
+ CFG_CMD_MII MII utility commands
+ CFG_CMD_NET bootp, tftpboot, rarpboot
+ CFG_CMD_PCI * pciinfo
+ CFG_CMD_PCMCIA * PCMCIA support
+ CFG_CMD_REGINFO * Register dump
+ CFG_CMD_RUN run command in env variable
+ CFG_CMD_SCSI * SCSI Support
+ CFG_CMD_SETGETDCR Support for DCR Register access (4xx only)
+ CFG_CMD_SPI * SPI serial bus support
+ CFG_CMD_USB * USB support
+ CFG_CMD_BSP * Board SPecific functions
+ -----------------------------------------------
+ CFG_CMD_ALL all
+
+ CFG_CMD_DFL Default configuration; at the moment
+ this is includes all commands, except
+ the ones marked with "*" in the list
+ above.
+
+ If you don't define CONFIG_COMMANDS it defaults to
+ CFG_CMD_DFL in include/cmd_confdefs.h. A board can
+ override the default settings in the respective
+ include file.
+
+ EXAMPLE: If you want all functions except of network
+ support you can write:
+
+ #define CONFIG_COMMANDS (CFG_CMD_ALL & ~CFG_CMD_NET)
+
+
+ Note: Don't enable the "icache" and "dcache" commands
+ (configuration option CFG_CMD_CACHE) unless you know
+ what you (and your U-Boot users) are doing. Data
+ cache cannot be enabled on systems like the 8xx or
+ 8260 (where accesses to the IMMR region must be
+ uncached), and it cannot be disabled on all other
+ systems where we (mis-) use the data cache to hold an
+ initial stack and some data.
+
+
+ XXX - this list needs to get updated!
+
+- Watchdog:
+ CONFIG_WATCHDOG
+ If this variable is defined, it enables watchdog
+ support. There must support in the platform specific
+ code for a watchdog. For the 8xx and 8260 CPUs, the
+ SIU Watchdog feature is enabled in the SYPCR
+ register.
+
+- Real-Time Clock:
+
+ When CFG_CMD_DATE is selected, the type of the RTC
+ has to be selected, too. Define exactly one of the
+ following options:
+
+ CONFIG_RTC_MPC8xx - use internal RTC of MPC8xx
+ CONFIG_RTC_PCF8563 - use Philips PCF8563 RTC
+ CONFIG_RTC_MC146818 - use MC146818 RTC
+ CONFIG_RTC_DS1337 - use Maxim, Inc. DS1337 RTC
+
+- Timestamp Support:
+
+ When CONFIG_TIMESTAMP is selected, the timestamp
+ (date and time) of an image is printed by image
+ commands like bootm or iminfo. This option is
+ automatically enabled when you select CFG_CMD_DATE .
+
+- Partition Support:
+ CONFIG_MAC_PARTITION and/or CONFIG_DOS_PARTITION
+ and/or CONFIG_ISO_PARTITION
+
+ If IDE or SCSI support is enabled (CFG_CMD_IDE or
+ CFG_CMD_SCSI) you must configure support for at least
+ one partition type as well.
+
+- IDE Reset method:
+ CONFIG_IDE_RESET_ROUTINE
+
+ Set this to define that instead of a reset Pin, the
+ routine ide_set_reset(int idereset) will be used.
+
+- ATAPI Support:
+ CONFIG_ATAPI
+
+ Set this to enable ATAPI support.
+
+- SCSI Support:
+ At the moment only there is only support for the
+ SYM53C8XX SCSI controller; define
+ CONFIG_SCSI_SYM53C8XX to enable it.
+
+ CFG_SCSI_MAX_LUN [8], CFG_SCSI_MAX_SCSI_ID [7] and
+ CFG_SCSI_MAX_DEVICE [CFG_SCSI_MAX_SCSI_ID *
+ CFG_SCSI_MAX_LUN] can be adjusted to define the
+ maximum numbers of LUNs, SCSI ID's and target
+ devices.
+ CFG_SCSI_SYM53C8XX_CCF to fix clock timing (80Mhz)
+
+- NETWORK Support (PCI):
+ CONFIG_EEPRO100
+ Support for Intel 82557/82559/82559ER chips.
+ Optional CONFIG_EEPRO100_SROM_WRITE enables eeprom
+ write routine for first time initialisation.
+
+ CONFIG_TULIP
+ Support for Digital 2114x chips.
+ Optional CONFIG_TULIP_SELECT_MEDIA for board specific
+ modem chip initialisation (KS8761/QS6611).
+
+ CONFIG_NATSEMI
+ Support for National dp83815 chips.
+
+ CONFIG_NS8382X
+ Support for National dp8382[01] gigabit chips.
+
+- USB Support:
+ At the moment only the UHCI host controller is
+ supported (PIP405, MIP405); define
+ CONFIG_USB_UHCI to enable it.
+ define CONFIG_USB_KEYBOARD to enable the USB Keyboard
+ end define CONFIG_USB_STORAGE to enable the USB
+ storage devices.
+ Note:
+ Supported are USB Keyboards and USB Floppy drives
+ (TEAC FD-05PUB).
+
+- Keyboard Support:
+ CONFIG_ISA_KEYBOARD
+
+ Define this to enable standard (PC-Style) keyboard
+ support
+
+ CONFIG_I8042_KBD
+ Standard PC keyboard driver with US (is default) and
+ GERMAN key layout (switch via environment 'keymap=de') support.
+ Export function i8042_kbd_init, i8042_tstc and i8042_getc
+ for cfb_console. Supports cursor blinking.
+
+- Video support:
+ CONFIG_VIDEO
+
+ Define this to enable video support (for output to
+ video).
+
+ CONFIG_VIDEO_CT69000
+
+ Enable Chips & Technologies 69000 Video chip
+
+ CONFIG_VIDEO_SMI_LYNXEM
+ Enable Silicon Motion SMI 712/710/810 Video chip
+ Videomode are selected via environment 'videomode' with
+ standard LiLo mode numbers.
+ Following modes are supported (* is default):
+
+ 800x600 1024x768 1280x1024
+ 256 (8bit) 303* 305 307
+ 65536 (16bit) 314 317 31a
+ 16,7 Mill (24bit) 315 318 31b
+ (i.e. setenv videomode 317; saveenv; reset;)
+
+- LCD Support: CONFIG_LCD
+
+ Define this to enable LCD support (for output to LCD
+ display); also select one of the supported displays
+ by defining one of these:
+
+ CONFIG_NEC_NL6648AC33:
+
+ NEC NL6648AC33-18. Active, color, single scan.
+
+ CONFIG_NEC_NL6648BC20
+
+ NEC NL6648BC20-08. 6.5", 640x480.
+ Active, color, single scan.
+
+ CONFIG_SHARP_16x9
+
+ Sharp 320x240. Active, color, single scan.
+ It isn't 16x9, and I am not sure what it is.
+
+ CONFIG_SHARP_LQ64D341
+
+ Sharp LQ64D341 display, 640x480.
+ Active, color, single scan.
+
+ CONFIG_HLD1045
+
+ HLD1045 display, 640x480.
+ Active, color, single scan.
+
+ CONFIG_OPTREX_BW
+
+ Optrex CBL50840-2 NF-FW 99 22 M5
+ or
+ Hitachi LMG6912RPFC-00T
+ or
+ Hitachi SP14Q002
+
+ 320x240. Black & white.
+
+ Normally display is black on white background; define
+ CFG_WHITE_ON_BLACK to get it inverted.
+
+- Ethernet address:
+ CONFIG_ETHADDR
+ CONFIG_ETH2ADDR
+ CONFIG_ETH3ADDR
+
+ Define a default value for ethernet address to use
+ for the respective ethernet interface, in case this
+ is not determined automatically.
+
+- IP address:
+ CONFIG_IPADDR
+
+ Define a default value for the IP address to use for
+ the default ethernet interface, in case this is not
+ determined through e.g. bootp.
+
+- Server IP address:
+ CONFIG_SERVERIP
+
+ Defines a default value for theIP address of a TFTP
+ server to contact when using the "tftboot" command.
+
+- BOOTP Recovery Mode:
+ CONFIG_BOOTP_RANDOM_DELAY
+
+ If you have many targets in a network that try to
+ boot using BOOTP, you may want to avoid that all
+ systems send out BOOTP requests at precisely the same
+ moment (which would happen for instance at recovery
+ from a power failure, when all systems will try to
+ boot, thus flooding the BOOTP server. Defining
+ CONFIG_BOOTP_RANDOM_DELAY causes a random delay to be
+ inserted before sending out BOOTP requests. The
+ following delays are insterted then:
+
+ 1st BOOTP request: delay 0 ... 1 sec
+ 2nd BOOTP request: delay 0 ... 2 sec
+ 3rd BOOTP request: delay 0 ... 4 sec
+ 4th and following
+ BOOTP requests: delay 0 ... 8 sec
+
+- Status LED: CONFIG_STATUS_LED
+
+ Several configurations allow to display the current
+ status using a LED. For instance, the LED will blink
+ fast while running U-Boot code, stop blinking as
+ soon as a reply to a BOOTP request was received, and
+ start blinking slow once the Linux kernel is running
+ (supported by a status LED driver in the Linux
+ kernel). Defining CONFIG_STATUS_LED enables this
+ feature in U-Boot.
+
+- CAN Support: CONFIG_CAN_DRIVER
+
+ Defining CONFIG_CAN_DRIVER enables CAN driver support
+ on those systems that support this (optional)
+ feature, like the TQM8xxL modules.
+
+- I2C Support: CONFIG_HARD_I2C | CONFIG_SOFT_I2C
+
+ Enables I2C serial bus commands. If this is selected,
+ either CONFIG_HARD_I2C or CONFIG_SOFT_I2C must be defined
+ to include the appropriate I2C driver.
+
+ See also: common/cmd_i2c.c for a description of the
+ command line interface.
+
+
+ CONFIG_HARD_I2C
+
+ Selects the CPM hardware driver for I2C.
+
+ CONFIG_SOFT_I2C
+
+ Use software (aka bit-banging) driver instead of CPM
+ or similar hardware support for I2C. This is configured
+ via the following defines.
+
+ I2C_INIT
+
+ (Optional). Any commands necessary to enable I2C
+ controller or configure ports.
+
+ I2C_PORT
+
+ (Only for MPC8260 CPU). The I/O port to use (the code
+ assumes both bits are on the same port). Valid values
+ are 0..3 for ports A..D.
+
+ I2C_ACTIVE
+
+ The code necessary to make the I2C data line active
+ (driven). If the data line is open collector, this
+ define can be null.
+
+ I2C_TRISTATE
+
+ The code necessary to make the I2C data line tri-stated
+ (inactive). If the data line is open collector, this
+ define can be null.
+
+ I2C_READ
+
+ Code that returns TRUE if the I2C data line is high,
+ FALSE if it is low.
+
+ I2C_SDA(bit)
+
+ If <bit> is TRUE, sets the I2C data line high. If it
+ is FALSE, it clears it (low).
+
+ I2C_SCL(bit)
+
+ If <bit> is TRUE, sets the I2C clock line high. If it
+ is FALSE, it clears it (low).
+
+ I2C_DELAY
+
+ This delay is invoked four times per clock cycle so this
+ controls the rate of data transfer. The data rate thus
+ is 1 / (I2C_DELAY * 4).
+
+- SPI Support: CONFIG_SPI
+
+ Enables SPI driver (so far only tested with
+ SPI EEPROM, also an instance works with Crystal A/D and
+ D/As on the SACSng board)
+
+ CONFIG_SPI_X
+
+ Enables extended (16-bit) SPI EEPROM addressing.
+ (symmetrical to CONFIG_I2C_X)
+
+ CONFIG_SOFT_SPI
+
+ Enables a software (bit-bang) SPI driver rather than
+ using hardware support. This is a general purpose
+ driver that only requires three general I/O port pins
+ (two outputs, one input) to function. If this is
+ defined, the board configuration must define several
+ SPI configuration items (port pins to use, etc). For
+ an example, see include/configs/sacsng.h.
+
+- FPGA Support: CONFIG_FPGA_COUNT
+
+ Specify the number of FPGA devices to support.
+
+ CONFIG_FPGA
+
+ Used to specify the types of FPGA devices. For
+ example,
+ #define CONFIG_FPGA CFG_XILINX_VIRTEX2
+
+ CFG_FPGA_PROG_FEEDBACK
+
+ Enable printing of hash marks during FPGA
+ configuration.
+
+ CFG_FPGA_CHECK_BUSY
+
+ Enable checks on FPGA configuration interface busy
+ status by the configuration function. This option
+ will require a board or device specific function to
+ be written.
+
+ CONFIG_FPGA_DELAY
+
+ If defined, a function that provides delays in the
+ FPGA configuration driver.
+
+ CFG_FPGA_CHECK_CTRLC
+
+ Allow Control-C to interrupt FPGA configuration
+
+ CFG_FPGA_CHECK_ERROR
+
+ Check for configuration errors during FPGA bitfile
+ loading. For example, abort during Virtex II
+ configuration if the INIT_B line goes low (which
+ indicated a CRC error).
+
+ CFG_FPGA_WAIT_INIT
+
+ Maximum time to wait for the INIT_B line to deassert
+ after PROB_B has been deasserted during a Virtex II
+ FPGA configuration sequence. The default time is 500 mS.
+
+ CFG_FPGA_WAIT_BUSY
+
+ Maximum time to wait for BUSY to deassert during
+ Virtex II FPGA configuration. The default is 5 mS.
+
+ CFG_FPGA_WAIT_CONFIG
+
+ Time to wait after FPGA configuration. The default is
+ 200 mS.
+
+- FPGA Support: CONFIG_FPGA_COUNT
+
+ Specify the number of FPGA devices to support.
+
+ CONFIG_FPGA
+
+ Used to specify the types of FPGA devices. For example,
+ #define CONFIG_FPGA CFG_XILINX_VIRTEX2
+
+ CFG_FPGA_PROG_FEEDBACK
+
+ Enable printing of hash marks during FPGA configuration.
+
+ CFG_FPGA_CHECK_BUSY
+
+ Enable checks on FPGA configuration interface busy
+ status by the configuration function. This option
+ will require a board or device specific function to
+ be written.
+
+ CONFIG_FPGA_DELAY
+
+ If defined, a function that provides delays in the FPGA
+ configuration driver.
+
+ CFG_FPGA_CHECK_CTRLC
+ Allow Control-C to interrupt FPGA configuration
+
+ CFG_FPGA_CHECK_ERROR
+
+ Check for configuration errors during FPGA bitfile
+ loading. For example, abort during Virtex II
+ configuration if the INIT_B line goes low (which
+ indicated a CRC error).
+
+ CFG_FPGA_WAIT_INIT
+
+ Maximum time to wait for the INIT_B line to deassert
+ after PROB_B has been deasserted during a Virtex II
+ FPGA configuration sequence. The default time is 500
+ mS.
+
+ CFG_FPGA_WAIT_BUSY
+
+ Maximum time to wait for BUSY to deassert during
+ Virtex II FPGA configuration. The default is 5 mS.
+
+ CFG_FPGA_WAIT_CONFIG
+
+ Time to wait after FPGA configuration. The default is
+ 200 mS.
+
+- Configuration Management:
+ CONFIG_IDENT_STRING
+
+ If defined, this string will be added to the U-Boot
+ version information (U_BOOT_VERSION)
+
+- Vendor Parameter Protection:
+
+ U-Boot considers the values of the environment
+ variables "serial#" (Board Serial Number) and
+ "ethaddr" (Ethernet Address) to bb parameters that
+ are set once by the board vendor / manufacturer, and
+ protects these variables from casual modification by
+ the user. Once set, these variables are read-only,
+ and write or delete attempts are rejected. You can
+ change this behviour:
+
+ If CONFIG_ENV_OVERWRITE is #defined in your config
+ file, the write protection for vendor parameters is
+ completely disabled. Anybody can change or delte
+ these parameters.
+
+ Alternatively, if you #define _both_ CONFIG_ETHADDR
+ _and_ CONFIG_OVERWRITE_ETHADDR_ONCE, a default
+ ethernet address is installed in the environment,
+ which can be changed exactly ONCE by the user. [The
+ serial# is unaffected by this, i. e. it remains
+ read-only.]
+
+- Protected RAM:
+ CONFIG_PRAM
+
+ Define this variable to enable the reservation of
+ "protected RAM", i. e. RAM which is not overwritten
+ by U-Boot. Define CONFIG_PRAM to hold the number of
+ kB you want to reserve for pRAM. You can overwrite
+ this default value by defining an environment
+ variable "pram" to the number of kB you want to
+ reserve. Note that the board info structure will
+ still show the full amount of RAM. If pRAM is
+ reserved, a new environment variable "mem" will
+ automatically be defined to hold the amount of
+ remaining RAM in a form that can be passed as boot
+ argument to Linux, for instance like that:
+
+ setenv bootargs ... mem=\$(mem)
+ saveenv
+
+ This way you can tell Linux not to use this memory,
+ either, which results in a memory region that will
+ not be affected by reboots.
+
+ *WARNING* If your board configuration uses automatic
+ detection of the RAM size, you must make sure that
+ this memory test is non-destructive. So far, the
+ following board configurations are known to be
+ "pRAM-clean":
+
+ ETX094, IVMS8, IVML24, SPD8xx, TQM8xxL,
+ HERMES, IP860, RPXlite, LWMON, LANTEC,
+ PCU_E, FLAGADM, TQM8260
+
+- Error Recovery:
+ CONFIG_PANIC_HANG
+
+ Define this variable to stop the system in case of a
+ fatal error, so that you have to reset it manually.
+ This is probably NOT a good idea for an embedded
+ system where you want to system to reboot
+ automatically as fast as possible, but it may be
+ useful during development since you can try to debug
+ the conditions that lead to the situation.
+
+ CONFIG_NET_RETRY_COUNT
+
+ This variable defines the number of retries for
+ network operations like ARP, RARP, TFTP, or BOOTP
+ before giving up the operation. If not defined, a
+ default value of 5 is used.
+
+- Command Interpreter:
+ CFG_HUSH_PARSER
+
+ Define this variable to enable the "hush" shell (from
+ Busybox) as command line interpreter, thus enabling
+ powerful command line syntax like
+ if...then...else...fi conditionals or `&&' and '||'
+ constructs ("shell scripts").
+
+ If undefined, you get the old, much simpler behaviour
+ with a somewhat smaller memory footprint.
+
+
+ CFG_PROMPT_HUSH_PS2
+
+ This defines the secondary prompt string, which is
+ printed when the command interpreter needs more input
+ to complete a command. Usually "> ".
+
+ Note:
+
+ In the current implementation, the local variables
+ space and global environment variables space are
+ separated. Local variables are those you define by
+ simply typing like `name=value'. To access a local
+ variable later on, you have write `$name' or
+ `${name}'; variable directly by typing say `$name' at
+ the command prompt.
+
+ Global environment variables are those you use
+ setenv/printenv to work with. To run a command stored
+ in such a variable, you need to use the run command,
+ and you must not use the '$' sign to access them.
+
+ To store commands and special characters in a
+ variable, please use double quotation marks
+ surrounding the whole text of the variable, instead
+ of the backslashes before semicolons and special
+ symbols.
+
+- Default Environment
+ CONFIG_EXTRA_ENV_SETTINGS
+
+ Define this to contain any number of null terminated
+ strings (variable = value pairs) that will be part of
+ the default enviroment compiled into the boot image.
+ For example, place something like this in your
+ board's config file:
+
+ #define CONFIG_EXTRA_ENV_SETTINGS \
+ "myvar1=value1\0" \
+ "myvar2=value2\0"
+
+ Warning: This method is based on knowledge about the
+ internal format how the environment is stored by the
+ U-Boot code. This is NOT an official, expoerted
+ interface! Although it is unlikely that this format
+ will change soon, there is no guarantee either.
+ You better know what you are doing here.
+
+ Note: overly (ab)use of the default environment is
+ discouraged. Make sure to check other ways to preset
+ the environment like the autoscript function or the
+ boot command first.
+
+- Show boot progress
+ CONFIG_SHOW_BOOT_PROGRESS
+
+ Defining this option allows to add some board-
+ specific code (calling a user-provided function
+ "show_boot_progress(int)") that enables you to show
+ the system's boot progress on some display (for
+ example, some LED's) on your board. At the moment,
+ the following checkpoints are implemented:
+
+ Arg Where When
+ 1 common/cmd_bootm.c before attempting to boot an image
+ -1 common/cmd_bootm.c Image header has bad magic number
+ 2 common/cmd_bootm.c Image header has correct magic number
+ -2 common/cmd_bootm.c Image header has bad checksum
+ 3 common/cmd_bootm.c Image header has correct checksum
+ -3 common/cmd_bootm.c Image data has bad checksum
+ 4 common/cmd_bootm.c Image data has correct checksum
+ -4 common/cmd_bootm.c Image is for unsupported architecture
+ 5 common/cmd_bootm.c Architecture check OK
+ -5 common/cmd_bootm.c Wrong Image Type (not kernel, multi, standalone)
+ 6 common/cmd_bootm.c Image Type check OK
+ -6 common/cmd_bootm.c gunzip uncompression error
+ -7 common/cmd_bootm.c Unimplemented compression type
+ 7 common/cmd_bootm.c Uncompression OK
+ -8 common/cmd_bootm.c Wrong Image Type (not kernel, multi, standalone)
+ 8 common/cmd_bootm.c Image Type check OK
+ -9 common/cmd_bootm.c Unsupported OS (not Linux, BSD, VxWorks, QNX)
+ 9 common/cmd_bootm.c Start initial ramdisk verification
+ -10 common/cmd_bootm.c Ramdisk header has bad magic number
+ -11 common/cmd_bootm.c Ramdisk header has bad checksum
+ 10 common/cmd_bootm.c Ramdisk header is OK
+ -12 common/cmd_bootm.c Ramdisk data has bad checksum
+ 11 common/cmd_bootm.c Ramdisk data has correct checksum
+ 12 common/cmd_bootm.c Ramdisk verification complete, start loading
+ -13 common/cmd_bootm.c Wrong Image Type (not PPC Linux Ramdisk)
+ 13 common/cmd_bootm.c Start multifile image verification
+ 14 common/cmd_bootm.c No initial ramdisk, no multifile, continue.
+ 15 common/cmd_bootm.c All preparation done, transferring control to OS
+
+ -1 common/cmd_doc.c Bad usage of "doc" command
+ -1 common/cmd_doc.c No boot device
+ -1 common/cmd_doc.c Unknown Chip ID on boot device
+ -1 common/cmd_doc.c Read Error on boot device
+ -1 common/cmd_doc.c Image header has bad magic number
+
+ -1 common/cmd_ide.c Bad usage of "ide" command
+ -1 common/cmd_ide.c No boot device
+ -1 common/cmd_ide.c Unknown boot device
+ -1 common/cmd_ide.c Unknown partition table
+ -1 common/cmd_ide.c Invalid partition type
+ -1 common/cmd_ide.c Read Error on boot device
+ -1 common/cmd_ide.c Image header has bad magic number
+
+ -1 common/cmd_nvedit.c Environment not changable, but has bad CRC
+
+
+Modem Support:
+--------------
+
+[so far only for SMDK2400 board]
+
+- Modem support endable:
+ CONFIG_MODEM_SUPPORT
+
+- RTS/CTS Flow control enable:
+ CONFIG_HWFLOW
+
+- Modem debug support:
+ CONFIG_MODEM_SUPPORT_DEBUG
+
+ Enables debugging stuff (char screen[1024], dbg())
+ for modem support. Useful only with BDI2000.
+
+- General:
+
+ In the target system modem support is enabled when a
+ specific key (key combination) is pressed during
+ power-on. Otherwise U-Boot will boot normally
+ (autoboot). The key_pressed() fuction is called from
+ board_init(). Currently key_pressed() is a dummy
+ function, returning 1 and thus enabling modem
+ initialization.
+
+ If there are no modem init strings in the
+ environment, U-Boot proceed to autoboot; the
+ previous output (banner, info printfs) will be
+ supressed, though.
+
+ See also: doc/README.Modem
+
+
+
+
+Configuration Settings:
+-----------------------
+
+- CFG_LONGHELP: Defined when you want long help messages included;
+ undefine this when you're short of memory.
+
+- CFG_PROMPT: This is what U-Boot prints on the console to
+ prompt for user input.
+
+- CFG_CBSIZE: Buffer size for input from the Console
+
+- CFG_PBSIZE: Buffer size for Console output
+
+- CFG_MAXARGS: max. Number of arguments accepted for monitor commands
+
+- CFG_BARGSIZE: Buffer size for Boot Arguments which are passed to
+ the application (usually a Linux kernel) when it is
+ booted
+
+- CFG_BAUDRATE_TABLE:
+ List of legal baudrate settings for this board.
+
+- CFG_CONSOLE_INFO_QUIET
+ Suppress display of console information at boot.
+
+- CFG_CONSOLE_IS_IN_ENV
+ If the board specific function
+ extern int overwrite_console (void);
+ returns 1, the stdin, stderr and stdout are switched to the
+ serial port, else the settings in the environment are used.
+
+- CFG_CONSOLE_OVERWRITE_ROUTINE
+ Enable the call to overwrite_console().
+
+- CFG_CONSOLE_ENV_OVERWRITE
+ Enable overwrite of previous console environment settings.
+
+- CFG_MEMTEST_START, CFG_MEMTEST_END:
+ Begin and End addresses of the area used by the
+ simple memory test.
+
+- CFG_ALT_MEMTEST:
+ Enable an alternate, more extensive memory test.
+
+- CFG_TFTP_LOADADDR:
+ Default load address for network file downloads
+
+- CFG_LOADS_BAUD_CHANGE:
+ Enable temporary baudrate change while serial download
+
+- CFG_SDRAM_BASE:
+ Physical start address of SDRAM. _Must_ be 0 here.
+
+- CFG_MBIO_BASE:
+ Physical start address of Motherboard I/O (if using a
+ Cogent motherboard)
+
+- CFG_FLASH_BASE:
+ Physical start address of Flash memory.
+
+- CFG_MONITOR_BASE:
+ Physical start address of boot monitor code (set by
+ make config files to be same as the text base address
+ (TEXT_BASE) used when linking) - same as
+ CFG_FLASH_BASE when booting from flash.
+
+- CFG_MONITOR_LEN:
+ Size of memory reserved for monitor code
+
+- CFG_MALLOC_LEN:
+ Size of DRAM reserved for malloc() use.
+
+- CFG_BOOTMAPSZ:
+ Maximum size of memory mapped by the startup code of
+ the Linux kernel; all data that must be processed by
+ the Linux kernel (bd_info, boot arguments, eventually
+ initrd image) must be put below this limit.
+
+- CFG_MAX_FLASH_BANKS:
+ Max number of Flash memory banks
+
+- CFG_MAX_FLASH_SECT:
+ Max number of sectors on a Flash chip
+
+- CFG_FLASH_ERASE_TOUT:
+ Timeout for Flash erase operations (in ms)
+
+- CFG_FLASH_WRITE_TOUT:
+ Timeout for Flash write operations (in ms)
+
+- CFG_DIRECT_FLASH_TFTP:
+
+ Enable TFTP transfers directly to flash memory;
+ without this option such a download has to be
+ performed in two steps: (1) download to RAM, and (2)
+ copy from RAM to flash.
+
+ The two-step approach is usually more reliable, since
+ you can check if the download worked before you erase
+ the flash, but in some situations (when sytem RAM is
+ too limited to allow for a tempory copy of the
+ downloaded image) this option may be very useful.
+
+- CFG_FLASH_CFI:
+ Define if the flash driver uses extra elements in the
+ common flash structure for storing flash geometry
+
+The following definitions that deal with the placement and management
+of environment data (variable area); in general, we support the
+following configurations:
+
+- CFG_ENV_IS_IN_FLASH:
+
+ Define this if the environment is in flash memory.
+
+ a) The environment occupies one whole flash sector, which is
+ "embedded" in the text segment with the U-Boot code. This
+ happens usually with "bottom boot sector" or "top boot
+ sector" type flash chips, which have several smaller
+ sectors at the start or the end. For instance, such a
+ layout can have sector sizes of 8, 2x4, 16, Nx32 kB. In
+ such a case you would place the environment in one of the
+ 4 kB sectors - with U-Boot code before and after it. With
+ "top boot sector" type flash chips, you would put the
+ environment in one of the last sectors, leaving a gap
+ between U-Boot and the environment.
+
+ - CFG_ENV_OFFSET:
+
+ Offset of environment data (variable area) to the
+ beginning of flash memory; for instance, with bottom boot
+ type flash chips the second sector can be used: the offset
+ for this sector is given here.
+
+ CFG_ENV_OFFSET is used relative to CFG_FLASH_BASE.
+
+ - CFG_ENV_ADDR:
+
+ This is just another way to specify the start address of
+ the flash sector containing the environment (instead of
+ CFG_ENV_OFFSET).
+
+ - CFG_ENV_SECT_SIZE:
+
+ Size of the sector containing the environment.
+
+
+ b) Sometimes flash chips have few, equal sized, BIG sectors.
+ In such a case you don't want to spend a whole sector for
+ the environment.
+
+ - CFG_ENV_SIZE:
+
+ If you use this in combination with CFG_ENV_IS_IN_FLASH
+ and CFG_ENV_SECT_SIZE, you can specify to use only a part
+ of this flash sector for the environment. This saves
+ memory for the RAM copy of the environment.
+
+ It may also save flash memory if you decide to use this
+ when your environment is "embedded" within U-Boot code,
+ since then the remainder of the flash sector could be used
+ for U-Boot code. It should be pointed out that this is
+ STRONGLY DISCOURAGED from a robustness point of view:
+ updating the environment in flash makes it always
+ necessary to erase the WHOLE sector. If something goes
+ wrong before the contents has been restored from a copy in
+ RAM, your target system will be dead.
+
+ - CFG_ENV_ADDR_REDUND
+ CFG_ENV_SIZE_REDUND
+
+ These settings describe a second storage area used to hold
+ a redundand copy of the environment data, so that there is
+ a valid backup copy in case there is a power failur during
+ a "saveenv" operation.
+
+BE CAREFUL! Any changes to the flash layout, and some changes to the
+source code will make it necessary to adapt <board>/u-boot.lds*
+accordingly!
+
+
+- CFG_ENV_IS_IN_NVRAM:
+
+ Define this if you have some non-volatile memory device
+ (NVRAM, battery buffered SRAM) which you want to use for the
+ environment.
+
+ - CFG_ENV_ADDR:
+ - CFG_ENV_SIZE:
+
+ These two #defines are used to determin the memory area you
+ want to use for environment. It is assumed that this memory
+ can just be read and written to, without any special
+ provision.
+
+BE CAREFUL! The first access to the environment happens quite early
+in U-Boot initalization (when we try to get the setting of for the
+console baudrate). You *MUST* have mappend your NVRAM area then, or
+U-Boot will hang.
+
+Please note that even with NVRAM we still use a copy of the
+environment in RAM: we could work on NVRAM directly, but we want to
+keep settings there always unmodified except somebody uses "saveenv"
+to save the current settings.
+
+
+- CFG_ENV_IS_IN_EEPROM:
+
+ Use this if you have an EEPROM or similar serial access
+ device and a driver for it.
+
+ - CFG_ENV_OFFSET:
+ - CFG_ENV_SIZE:
+
+ These two #defines specify the offset and size of the
+ environment area within the total memory of your EEPROM.
+
+ - CFG_I2C_EEPROM_ADDR:
+ If defined, specified the chip address of the EEPROM device.
+ The default address is zero.
+
+ - CFG_EEPROM_PAGE_WRITE_BITS:
+ If defined, the number of bits used to address bytes in a
+ single page in the EEPROM device. A 64 byte page, for example
+ would require six bits.
+
+ - CFG_EEPROM_PAGE_WRITE_DELAY_MS:
+ If defined, the number of milliseconds to delay between
+ page writes. The default is zero milliseconds.
+
+ - CFG_I2C_EEPROM_ADDR_LEN:
+ The length in bytes of the EEPROM memory array address. Note
+ that this is NOT the chip address length!
+
+ - CFG_EEPROM_SIZE:
+ The size in bytes of the EEPROM device.
+
+ - CFG_I2C_EEPROM_ADDR:
+ If defined, specified the chip address of the EEPROM device.
+ The default address is zero.
+
+ - CFG_EEPROM_PAGE_WRITE_BITS:
+ If defined, the number of bits used to address bytes in a
+ single page in the EEPROM device. A 64 byte page, for example
+ would require six bits.
+
+ - CFG_EEPROM_PAGE_WRITE_DELAY_MS:
+ If defined, the number of milliseconds to delay between
+ page writes. The default is zero milliseconds.
+
+ - CFG_I2C_EEPROM_ADDR_LEN:
+ The length in bytes of the EEPROM memory array address. Note
+ that this is NOT the chip address length!
+
+ - CFG_EEPROM_SIZE:
+ The size in bytes of the EEPROM device.
+
+- CFG_SPI_INIT_OFFSET
+
+ Defines offset to the initial SPI buffer area in DPRAM. The
+ area is used at an early stage (ROM part) if the environment
+ is configured to reside in the SPI EEPROM: We need a 520 byte
+ scratch DPRAM area. It is used between the two initialization
+ calls (spi_init_f() and spi_init_r()). A value of 0xB00 seems
+ to be a good choice since it makes it far enough from the
+ start of the data area as well as from the stack pointer.
+
+Please note that the environment is read-only as long as the monitor
+has been relocated to RAM and a RAM copy of the environment has been
+created; also, when using EEPROM you will have to use getenv_r()
+until then to read environment variables.
+
+The environment is now protected by a CRC32 checksum. Before the
+monitor is relocated into RAM, as a result of a bad CRC you will be
+working with the compiled-in default environment - *silently*!!!
+[This is necessary, because the first environment variable we need is
+the "baudrate" setting for the console - if we have a bad CRC, we
+don't have any device yet where we could complain.]
+
+Note: once the monitor has been relocated, then it will complain if
+the default environment is used; a new CRC is computed as soon as you
+use the "setenv" command to modify / delete / add any environment
+variable [even when you try to delete a non-existing variable!].
+
+Note2: you must edit your u-boot.lds file to reflect this
+configuration.
+
+
+Many of the options are named exactly as the corresponding Linux
+kernel configuration options. The intention is to make it easier to
+build a config tool - later.
+
+Low Level (hardware related) configuration options:
+
+- CFG_CACHELINE_SIZE:
+ Cache Line Size of the CPU.
+
+- CFG_DEFAULT_IMMR:
+ Default address of the IMMR after system reset.
+ Needed on some 8260 systems (MPC8260ADS and RPXsuper)
+ to be able to adjust the position of the IMMR
+ register after a reset.
+
+- CFG_IMMR: Physical address of the Internal Memory Mapped
+ Register; DO NOT CHANGE! (11-4)
+ [MPC8xx systems only]
+
+- CFG_INIT_RAM_ADDR:
+
+ Start address of memory area tha can be used for
+ initial data and stack; please note that this must be
+ writable memory that is working WITHOUT special
+ initialization, i. e. you CANNOT use normal RAM which
+ will become available only after programming the
+ memory controller and running certain initialization
+ sequences.
+
+ U-Boot uses the following memory types:
+ - MPC8xx and MPC8260: IMMR (internal memory of the CPU)
+ - MPC824X: data cache
+ - PPC4xx: data cache
+
+- CFG_INIT_DATA_OFFSET:
+
+ Offset of the initial data structure in the memory
+ area defined by CFG_INIT_RAM_ADDR. Usually
+ CFG_INIT_DATA_OFFSET is chosen such that the initial
+ data is located at the end of the available space
+ (sometimes written as (CFG_INIT_RAM_END -
+ CFG_INIT_DATA_SIZE), and the initial stack is just
+ below that area (growing from (CFG_INIT_RAM_ADDR +
+ CFG_INIT_DATA_OFFSET) downward.
+
+ Note:
+ On the MPC824X (or other systems that use the data
+ cache for initial memory) the address chosen for
+ CFG_INIT_RAM_ADDR is basically arbitrary - it must
+ point to an otherwise UNUSED address space between
+ the top of RAM and the start of the PCI space.
+
+- CFG_SIUMCR: SIU Module Configuration (11-6)
+
+- CFG_SYPCR: System Protection Control (11-9)
+
+- CFG_TBSCR: Time Base Status and Control (11-26)
+
+- CFG_PISCR: Periodic Interrupt Status and Control (11-31)
+
+- CFG_PLPRCR: PLL, Low-Power, and Reset Control Register (15-30)
+
+- CFG_SCCR: System Clock and reset Control Register (15-27)
+
+- CFG_OR_TIMING_SDRAM:
+ SDRAM timing
+
+- CFG_MAMR_PTA:
+ periodic timer for refresh
+
+- CFG_DER: Debug Event Register (37-47)
+
+- FLASH_BASE0_PRELIM, FLASH_BASE1_PRELIM, CFG_REMAP_OR_AM,
+ CFG_PRELIM_OR_AM, CFG_OR_TIMING_FLASH, CFG_OR0_REMAP,
+ CFG_OR0_PRELIM, CFG_BR0_PRELIM, CFG_OR1_REMAP, CFG_OR1_PRELIM,
+ CFG_BR1_PRELIM:
+ Memory Controller Definitions: BR0/1 and OR0/1 (FLASH)
+
+- SDRAM_BASE2_PRELIM, SDRAM_BASE3_PRELIM, SDRAM_MAX_SIZE,
+ CFG_OR_TIMING_SDRAM, CFG_OR2_PRELIM, CFG_BR2_PRELIM,
+ CFG_OR3_PRELIM, CFG_BR3_PRELIM:
+ Memory Controller Definitions: BR2/3 and OR2/3 (SDRAM)
+
+- CFG_MAMR_PTA, CFG_MPTPR_2BK_4K, CFG_MPTPR_1BK_4K, CFG_MPTPR_2BK_8K,
+ CFG_MPTPR_1BK_8K, CFG_MAMR_8COL, CFG_MAMR_9COL:
+ Machine Mode Register and Memory Periodic Timer
+ Prescaler definitions (SDRAM timing)
+
+- CFG_I2C_UCODE_PATCH, CFG_I2C_DPMEM_OFFSET [0x1FC0]:
+ enable I2C microcode relocation patch (MPC8xx);
+ define relocation offset in DPRAM [DSP2]
+
+- CFG_SPI_UCODE_PATCH, CFG_SPI_DPMEM_OFFSET [0x1FC0]:
+ enable SPI microcode relocation patch (MPC8xx);
+ define relocation offset in DPRAM [SCC4]
+
+- CFG_USE_OSCCLK:
+ Use OSCM clock mode on MBX8xx board. Be careful,
+ wrong setting might damage your board. Read
+ doc/README.MBX before setting this variable!
+
+Building the Software:
+======================
+
+Building U-Boot has been tested in native PPC environments (on a
+PowerBook G3 running LinuxPPC 2000) and in cross environments
+(running RedHat 6.x and 7.x Linux on x86, Solaris 2.6 on a SPARC, and
+NetBSD 1.5 on x86).
+
+If you are not using a native PPC environment, it is assumed that you
+have the GNU cross compiling tools available in your path and named
+with a prefix of "powerpc-linux-". If this is not the case, (e.g. if
+you are using Monta Vista's Hard Hat Linux CDK 1.2) you must change
+the definition of CROSS_COMPILE in Makefile. For HHL on a 4xx CPU,
+change it to:
+
+ CROSS_COMPILE = ppc_4xx-
+
+
+U-Boot is intended to be simple to build. After installing the
+sources you must configure U-Boot for one specific board type. This
+is done by typing:
+
+ make NAME_config
+
+where "NAME_config" is the name of one of the existing
+configurations; the following names are supported:
+
+ ADCIOP_config GTH_config TQM850L_config
+ ADS860_config IP860_config TQM855L_config
+ AR405_config IVML24_config TQM860L_config
+ CANBT_config IVMS8_config WALNUT405_config
+ CPCI405_config LANTEC_config cogent_common_config
+ CPCIISER4_config MBX_config cogent_mpc8260_config
+ CU824_config MBX860T_config cogent_mpc8xx_config
+ ESTEEM192E_config RPXlite_config hermes_config
+ ETX094_config RPXsuper_config hymod_config
+ FADS823_config SM850_config lwmon_config
+ FADS850SAR_config SPD823TS_config pcu_e_config
+ FADS860T_config SXNI855T_config rsdproto_config
+ FPS850L_config Sandpoint8240_config sbc8260_config
+ GENIETV_config TQM823L_config PIP405_config
+ GEN860T_config EBONY_config
+
+Note: for some board special configuration names may exist; check if
+ additional information is available from the board vendor; for
+ instance, the TQM8xxL systems run normally at 50 MHz and use a
+ SCC for 10baseT ethernet; there are also systems with 80 MHz
+ CPU clock, and an optional Fast Ethernet module is available
+ for CPU's with FEC. You can select such additional "features"
+ when chosing the configuration, i. e.
+
+ make TQM860L_config
+ - will configure for a plain TQM860L, i. e. 50MHz, no FEC
+
+ make TQM860L_FEC_config
+ - will configure for a TQM860L at 50MHz with FEC for ethernet
+
+ make TQM860L_80MHz_config
+ - will configure for a TQM860L at 80 MHz, with normal 10baseT
+ interface
+
+ make TQM860L_FEC_80MHz_config
+ - will configure for a TQM860L at 80 MHz with FEC for ethernet
+
+ make TQM823L_LCD_config
+ - will configure for a TQM823L with U-Boot console on LCD
+
+ make TQM823L_LCD_80MHz_config
+ - will configure for a TQM823L at 80 MHz with U-Boot console on LCD
+
+ etc.
+
+
+
+Finally, type "make all", and you should get some working U-Boot
+images ready for downlod to / installation on your system:
+
+- "u-boot.bin" is a raw binary image
+- "u-boot" is an image in ELF binary format
+- "u-boot.srec" is in Motorola S-Record format
+
+
+Please be aware that the Makefiles assume you are using GNU make, so
+for instance on NetBSD you might need to use "gmake" instead of
+native "make".
+
+
+If the system board that you have is not listed, then you will need
+to port U-Boot to your hardware platform. To do this, follow these
+steps:
+
+1. Add a new configuration option for your board to the toplevel
+ "Makefile", using the existing entries as examples.
+2. Create a new directory to hold your board specific code. Add any
+ files you need.
+3. If you're porting U-Boot to a new CPU, then also create a new
+ directory to hold your CPU specific code. Add any files you need.
+4. Run "make config_name" with your new name.
+5. Type "make", and you should get a working "u-boot.srec" file
+ to be installed on your target system.
+ [Of course, this last step is much harder than it sounds.]
+
+
+Testing of U-Boot Modifications, Ports to New Hardware, etc.:
+==============================================================
+
+If you have modified U-Boot sources (for instance added a new board
+or support for new devices, a new CPU, etc.) you are expected to
+provide feedback to the other developers. The feedback normally takes
+the form of a "patch", i. e. a context diff against a certain (latest
+official or latest in CVS) version of U-Boot sources.
+
+But before you submit such a patch, please verify that your modifi-
+cation did not break existing code. At least make sure that *ALL* of
+the supported boards compile WITHOUT ANY compiler warnings. To do so,
+just run the "MAKEALL" script, which will configure and build U-Boot
+for ALL supported system. Be warned, this will take a while. You can
+select which (cross) compiler to use py passing a `CROSS_COMPILE'
+environment variable to the script, i. e. to use the cross tools from
+MontaVista's Hard Hat Linux you can type
+
+ CROSS_COMPILE=ppc_8xx- MAKEALL
+
+or to build on a native PowerPC system you can type
+
+ CROSS_COMPILE=' ' MAKEALL
+
+See also "U-Boot Porting Guide" below.
+
+
+
+Monitor Commands - Overview:
+============================
+
+go - start application at address 'addr'
+run - run commands in an environment variable
+bootm - boot application image from memory
+bootp - boot image via network using BootP/TFTP protocol
+tftpboot- boot image via network using TFTP protocol
+ and env variables "ipaddr" and "serverip"
+ (and eventually "gatewayip")
+rarpboot- boot image via network using RARP/TFTP protocol
+diskboot- boot from IDE devicebootd - boot default, i.e., run 'bootcmd'
+loads - load S-Record file over serial line
+loadb - load binary file over serial line (kermit mode)
+md - memory display
+mm - memory modify (auto-incrementing)
+nm - memory modify (constant address)
+mw - memory write (fill)
+cp - memory copy
+cmp - memory compare
+crc32 - checksum calculation
+imd - i2c memory display
+imm - i2c memory modify (auto-incrementing)
+inm - i2c memory modify (constant address)
+imw - i2c memory write (fill)
+icrc32 - i2c checksum calculation
+iprobe - probe to discover valid I2C chip addresses
+iloop - infinite loop on address range
+isdram - print SDRAM configuration information
+sspi - SPI utility commands
+base - print or set address offset
+printenv- print environment variables
+setenv - set environment variables
+saveenv - save environment variables to persistent storage
+protect - enable or disable FLASH write protection
+erase - erase FLASH memory
+flinfo - print FLASH memory information
+bdinfo - print Board Info structure
+iminfo - print header information for application image
+coninfo - print console devices and informations
+ide - IDE sub-system
+loop - infinite loop on address range
+mtest - simple RAM test
+icache - enable or disable instruction cache
+dcache - enable or disable data cache
+reset - Perform RESET of the CPU
+echo - echo args to console
+version - print monitor version
+help - print online help
+? - alias for 'help'
+
+
+Monitor Commands - Detailed Description:
+========================================
+
+TODO.
+
+For now: just type "help <command>".
+
+
+Environment Variables:
+======================
+
+U-Boot supports user configuration using Environment Variables which
+can be made persistent by saving to Flash memory.
+
+Environment Variables are set using "setenv", printed using
+"printenv", and saved to Flash using "saveenv". Using "setenv"
+without a value can be used to delete a variable from the
+environment. As long as you don't save the environment you are
+working with an in-memory copy. In case the Flash area containing the
+environment is erased by accident, a default environment is provided.
+
+Some configuration options can be set using Environment Variables:
+
+ baudrate - see CONFIG_BAUDRATE
+
+ bootdelay - see CONFIG_BOOTDELAY
+
+ bootcmd - see CONFIG_BOOTCOMMAND
+
+ bootargs - Boot arguments when booting an RTOS image
+
+ bootfile - Name of the image to load with TFTP
+
+ autoload - if set to "no" (any string beginning with 'n'),
+ "bootp" will just load perform a lookup of the
+ configuration from the BOOTP server, but not try to
+ load any image using TFTP
+
+ autostart - if set to "yes", an image loaded using the "bootp",
+ "rarpboot", "tftpboot" or "diskboot" commands will
+ be automatically started (by internally calling
+ "bootm")
+
+ initrd_high - restrict positioning of initrd images:
+ If this variable is not set, initrd images will be
+ copied to the highest possible address in RAM; this
+ is usually what you want since it allows for
+ maximum initrd size. If for some reason you want to
+ make sure that the initrd image is loaded below the
+ CFG_BOOTMAPSZ limit, you can set this environment
+ variable to a value of "no" or "off" or "0".
+ Alternatively, you can set it to a maximum upper
+ address to use (U-Boot will still check that it
+ does not overwrite the U-Boot stack and data).
+
+ For instance, when you have a system with 16 MB
+ RAM, and want to reseve 4 MB from use by Linux,
+ you can do this by adding "mem=12M" to the value of
+ the "bootargs" variable. However, now you must make
+ sure, that the initrd image is placed in the first
+ 12 MB as well - this can be done with
+
+ setenv initrd_high 00c00000
+
+ ipaddr - IP address; needed for tftpboot command
+
+ loadaddr - Default load address for commands like "bootp",
+ "rarpboot", "tftpboot" or "diskboot"
+
+ loads_echo - see CONFIG_LOADS_ECHO
+
+ serverip - TFTP server IP address; needed for tftpboot command
+
+ bootretry - see CONFIG_BOOT_RETRY_TIME
+
+ bootdelaykey - see CONFIG_AUTOBOOT_DELAY_STR
+
+ bootstopkey - see CONFIG_AUTOBOOT_STOP_STR
+
+
+The following environment variables may be used and automatically
+updated by the network boot commands ("bootp" and "rarpboot"),
+depending the information provided by your boot server:
+
+ bootfile - see above
+ dnsip - IP address of your Domain Name Server
+ gatewayip - IP address of the Gateway (Router) to use
+ hostname - Target hostname
+ ipaddr - see above
+ netmask - Subnet Mask
+ rootpath - Pathname of the root filesystem on the NFS server
+ serverip - see above
+
+
+There are two special Environment Variables:
+
+ serial# - contains hardware identification information such
+ as type string and/or serial number
+ ethaddr - Ethernet address
+
+These variables can be set only once (usually during manufacturing of
+the board). U-Boot refuses to delete or overwrite these variables
+once they have been set once.
+
+
+Please note that changes to some configuration parameters may take
+only effect after the next boot (yes, that's just like Windoze :-).
+
+
+Note for Redundant Ethernet Interfaces:
+=======================================
+
+Some boards come with redundand ethernet interfaces; U-Boot supports
+such configurations and is capable of automatic selection of a
+"working" interface when needed. MAC assignemnt works as follows:
+
+Network interfaces are numbered eth0, eth1, eth2, ... Corresponding
+MAC addresses can be stored in the environment as "ethaddr" (=>eth0),
+"eth1addr" (=>eth1), "eth2addr", ...
+
+If the network interface stores some valid MAC address (for instance
+in SROM), this is used as default address if there is NO correspon-
+ding setting in the environment; if the corresponding environment
+variable is set, this overrides the settings in the card; that means:
+
+o If the SROM has a valid MAC address, and there is no address in the
+ environment, the SROM's address is used.
+
+o If there is no valid address in the SROM, and a definition in the
+ environment exists, then the value from the environment variable is
+ used.
+
+o If both the SROM and the environment contain a MAC address, and
+ both addresses are the same, this MAC address is used.
+
+o If both the SROM and the environment contain a MAC address, and the
+ addresses differ, the value from the environment is used and a
+ warning is printed.
+
+o If neither SROM nor the environment contain a MAC address, an error
+ is raised.
+
+
+
+Image Formats:
+==============
+
+The "boot" commands of this monitor operate on "image" files which
+can be basicly anything, preceeded by a special header; see the
+definitions in include/image.h for details; basicly, the header
+defines the following image properties:
+
+* Target Operating System (Provisions for OpenBSD, NetBSD, FreeBSD,
+ 4.4BSD, Linux, SVR4, Esix, Solaris, Irix, SCO, Dell, NCR, VxWorks,
+ LynxOS, pSOS, QNX;
+ Currently supported: Linux, NetBSD, VxWorks, QNX).
+* Target CPU Architecture (Provisions for Alpha, ARM, Intel x86,
+ IA64, MIPS, MIPS, PowerPC, IBM S390, SuperH, Sparc, Sparc 64 Bit;
+ Currently supported: PowerPC).
+* Compression Type (Provisions for uncompressed, gzip, bzip2;
+ Currently supported: uncompressed, gzip).
+* Load Address
+* Entry Point
+* Image Name
+* Image Timestamp
+
+The header is marked by a special Magic Number, and both the header
+and the data portions of the image are secured against corruption by
+CRC32 checksums.
+
+
+Linux Support:
+==============
+
+Although U-Boot should support any OS or standalone application
+easily, Linux has always been in the focus during the design of
+U-Boot.
+
+U-Boot includes many features that so far have been part of some
+special "boot loader" code within the Linux kernel. Also, any
+"initrd" images to be used are no longer part of one big Linux image;
+instead, kernel and "initrd" are separate images. This implementation
+serves serveral purposes:
+
+- the same features can be used for other OS or standalone
+ applications (for instance: using compressed images to reduce the
+ Flash memory footprint)
+
+- it becomes much easier to port new Linux kernel versions because
+ lots of low-level, hardware dependend stuff are done by U-Boot
+
+- the same Linux kernel image can now be used with different "initrd"
+ images; of course this also means that different kernel images can
+ be run with the same "initrd". This makes testing easier (you don't
+ have to build a new "zImage.initrd" Linux image when you just
+ change a file in your "initrd"). Also, a field-upgrade of the
+ software is easier now.
+
+
+Linux HOWTO:
+============
+
+Porting Linux to U-Boot based systems:
+---------------------------------------
+
+U-Boot cannot save you from doing all the necessary modifications to
+configure the Linux device drivers for use with your target hardware
+(no, we don't intend to provide a full virtual machine interface to
+Linux :-).
+
+But now you can ignore ALL boot loader code (in arch/ppc/mbxboot).
+
+Just make sure your machine specific header file (for instance
+include/asm-ppc/tqm8xx.h) includes the same definition of the Board
+Information structure as we define in include/u-boot.h, and make
+sure that your definition of IMAP_ADDR uses the same value as your
+U-Boot configuration in CFG_IMMR.
+
+
+Configuring the Linux kernel:
+-----------------------------
+
+No specific requirements for U-Boot. Make sure you have some root
+device (initial ramdisk, NFS) for your target system.
+
+
+Building a Linux Image:
+-----------------------
+
+No specific requirements for U-Boot. There is no need to add a
+"ramdisk.image.gz" file when building the kernel, even when you
+intend to run it with initial ramdisk.
+
+Example:
+
+ make TQM850L_config
+ make oldconfig
+ make dep
+ make zImage
+
+However, we don't use the 'zImage' (= 'arch/ppc/mbxboot/zvmlinux') we
+build this way. The 'zImage' includes the old boot loader code which
+we don't ned any more. Instead, we use the raw (compressed) Linux
+kernel image in 'arch/ppc/coffboot/vmlinux.gz'.
+
+There is a special tool (in 'tools/mkimage') to encapsulate this
+image with header information, CRC32 checksum etc. for use with
+U-Boot:
+
+In the first form (with "-l" option) mkimage lists the information
+contained in the header of an existing U-Boot image; this includes
+checksum verification:
+
+ tools/mkimage -l image
+ -l ==> list image header information
+
+The second form (with "-d" option) is used to build a U-Boot image
+from a "data file" which is used as image payload:
+
+ tools/mkimage -A arch -O os -T type -C comp -a addr -e ep \
+ -n name -d data_file image
+ -A ==> set architecture to 'arch'
+ -O ==> set operating system to 'os'
+ -T ==> set image type to 'type'
+ -C ==> set compression type 'comp'
+ -a ==> set load address to 'addr' (hex)
+ -e ==> set entry point to 'ep' (hex)
+ -n ==> set image name to 'name'
+ -d ==> use image data from 'datafile'
+
+Right now, all Linux kernels use the same load address (0x00000000),
+but the entry point address depends on the kernel version:
+
+- 2.2.x kernels have the entry point at 0x0000000C,
+- 2.3.x and 2.4.x kernels have the entry point at 0x00000000.
+
+So a typical call to build a U-Boot image would read:
+
+ -> tools/mkimage -n '2.2.13 for initrd on TQM850L' \
+ > -A ppc -O linux -T kernel -C gzip -a 00000000 -e 0000000C \
+ > -d /opt/mpc8xx/src/linux-2.2.13/arch/ppc/coffboot/vmlinux.gz \
+ > examples/image-2.2.13-initrd
+ Image Name: 2.2.13 for initrd on TQM850L
+ Created: Wed Jul 19 02:34:59 2000
+ Image Type: PowerPC Linux Kernel Image (gzip compressed)
+ Data Size: 335725 Bytes = 327.86 kB = 0.32 MB
+ Load Address: 0x00000000
+ Entry Point: 0x0000000c
+
+To verify the contents of the image (or check for corruption):
+
+ -> tools/mkimage -l examples/image-2.2.13-initrd
+ Image Name: 2.2.13 for initrd on TQM850L
+ Created: Wed Jul 19 02:34:59 2000
+ Image Type: PowerPC Linux Kernel Image (gzip compressed)
+ Data Size: 335725 Bytes = 327.86 kB = 0.32 MB
+ Load Address: 0x00000000
+ Entry Point: 0x0000000c
+
+NOTE: for embedded systems where boot time is critical you can trade
+speed for memory and install an UNCOMPRESSED image instead: this
+needs more space in Flash, but boots much faster since it does not
+need to be uncompressed:
+
+ -> gunzip /opt/mpc8xx/src/linux-2.2.13/arch/ppc/coffboot/vmlinux.gz
+ -> tools/mkimage -n '2.2.13 for initrd on TQM850L' \
+ > -A ppc -O linux -T kernel -C none -a 00000000 -e 0000000C \
+ > -d /opt/mpc8xx/src/linux-2.2.13/arch/ppc/coffboot/vmlinux \
+ > examples/image-2.2.13-initrd-uncompressed
+ Image Name: 2.2.13 for initrd on TQM850L
+ Created: Wed Jul 19 02:34:59 2000
+ Image Type: PowerPC Linux Kernel Image (uncompressed)
+ Data Size: 792160 Bytes = 773.59 kB = 0.76 MB
+ Load Address: 0x00000000
+ Entry Point: 0x0000000c
+
+
+Similar you can build U-Boot images from a 'ramdisk.image.gz' file
+when your kernel is intended to use an initial ramdisk:
+
+ -> tools/mkimage -n 'Simple Ramdisk Image' \
+ > -A ppc -O linux -T ramdisk -C gzip \
+ > -d /LinuxPPC/images/SIMPLE-ramdisk.image.gz examples/simple-initrd
+ Image Name: Simple Ramdisk Image
+ Created: Wed Jan 12 14:01:50 2000
+ Image Type: PowerPC Linux RAMDisk Image (gzip compressed)
+ Data Size: 566530 Bytes = 553.25 kB = 0.54 MB
+ Load Address: 0x00000000
+ Entry Point: 0x00000000
+
+
+Installing a Linux Image:
+-------------------------
+
+To downloading a U-Boot image over the serial (console) interface,
+you must convert the image to S-Record format:
+
+ objcopy -I binary -O srec examples/image examples/image.srec
+
+The 'objcopy' does not understand the information in the U-Boot
+image header, so the resulting S-Record file will be relative to
+address 0x00000000. To load it to a given address, you need to
+specify the target address as 'offset' parameter with the 'loads'
+command.
+
+Example: install the image to address 0x40100000 (which on the
+TQM8xxL is in the first Flash bank):
+
+ => erase 40100000 401FFFFF
+
+ .......... done
+ Erased 8 sectors
+
+ => loads 40100000
+ ## Ready for S-Record download ...
+ ~>examples/image.srec
+ 1 2 3 4 5 6 7 8 9 10 11 12 13 ...
+ ...
+ 15989 15990 15991 15992
+ [file transfer complete]
+ [connected]
+ ## Start Addr = 0x00000000
+
+
+You can check the success of the download using the 'iminfo' command;
+this includes a checksum verification so you can be sure no data
+corruption happened:
+
+ => imi 40100000
+
+ ## Checking Image at 40100000 ...
+ Image Name: 2.2.13 for initrd on TQM850L
+ Image Type: PowerPC Linux Kernel Image (gzip compressed)
+ Data Size: 335725 Bytes = 327 kB = 0 MB
+ Load Address: 00000000
+ Entry Point: 0000000c
+ Verifying Checksum ... OK
+
+
+
+Boot Linux:
+-----------
+
+The "bootm" command is used to boot an application that is stored in
+memory (RAM or Flash). In case of a Linux kernel image, the contents
+of the "bootargs" environment variable is passed to the kernel as
+parameters. You can check and modify this variable using the
+"printenv" and "setenv" commands:
+
+
+ => printenv bootargs
+ bootargs=root=/dev/ram
+
+ => setenv bootargs root=/dev/nfs rw nfsroot=10.0.0.2:/LinuxPPC nfsaddrs=10.0.0.99:10.0.0.2
+
+ => printenv bootargs
+ bootargs=root=/dev/nfs rw nfsroot=10.0.0.2:/LinuxPPC nfsaddrs=10.0.0.99:10.0.0.2
+
+ => bootm 40020000
+ ## Booting Linux kernel at 40020000 ...
+ Image Name: 2.2.13 for NFS on TQM850L
+ Image Type: PowerPC Linux Kernel Image (gzip compressed)
+ Data Size: 381681 Bytes = 372 kB = 0 MB
+ Load Address: 00000000
+ Entry Point: 0000000c
+ Verifying Checksum ... OK
+ Uncompressing Kernel Image ... OK
+ Linux version 2.2.13 (wd@denx.local.net) (gcc version 2.95.2 19991024 (release)) #1 Wed Jul 19 02:35:17 MEST 2000
+ Boot arguments: root=/dev/nfs rw nfsroot=10.0.0.2:/LinuxPPC nfsaddrs=10.0.0.99:10.0.0.2
+ time_init: decrementer frequency = 187500000/60
+ Calibrating delay loop... 49.77 BogoMIPS
+ Memory: 15208k available (700k kernel code, 444k data, 32k init) [c0000000,c1000000]
+ ...
+
+If you want to boot a Linux kernel with initial ram disk, you pass
+the memory addreses of both the kernel and the initrd image (PPBCOOT
+format!) to the "bootm" command:
+
+ => imi 40100000 40200000
+
+ ## Checking Image at 40100000 ...
+ Image Name: 2.2.13 for initrd on TQM850L
+ Image Type: PowerPC Linux Kernel Image (gzip compressed)
+ Data Size: 335725 Bytes = 327 kB = 0 MB
+ Load Address: 00000000
+ Entry Point: 0000000c
+ Verifying Checksum ... OK
+
+ ## Checking Image at 40200000 ...
+ Image Name: Simple Ramdisk Image
+ Image Type: PowerPC Linux RAMDisk Image (gzip compressed)
+ Data Size: 566530 Bytes = 553 kB = 0 MB
+ Load Address: 00000000
+ Entry Point: 00000000
+ Verifying Checksum ... OK
+
+ => bootm 40100000 40200000
+ ## Booting Linux kernel at 40100000 ...
+ Image Name: 2.2.13 for initrd on TQM850L
+ Image Type: PowerPC Linux Kernel Image (gzip compressed)
+ Data Size: 335725 Bytes = 327 kB = 0 MB
+ Load Address: 00000000
+ Entry Point: 0000000c
+ Verifying Checksum ... OK
+ Uncompressing Kernel Image ... OK
+ ## Loading RAMDisk Image at 40200000 ...
+ Image Name: Simple Ramdisk Image
+ Image Type: PowerPC Linux RAMDisk Image (gzip compressed)
+ Data Size: 566530 Bytes = 553 kB = 0 MB
+ Load Address: 00000000
+ Entry Point: 00000000
+ Verifying Checksum ... OK
+ Loading Ramdisk ... OK
+ Linux version 2.2.13 (wd@denx.local.net) (gcc version 2.95.2 19991024 (release)) #1 Wed Jul 19 02:32:08 MEST 2000
+ Boot arguments: root=/dev/ram
+ time_init: decrementer frequency = 187500000/60
+ Calibrating delay loop... 49.77 BogoMIPS
+ ...
+ RAMDISK: Compressed image found at block 0
+ VFS: Mounted root (ext2 filesystem).
+
+ bash#
+
+
+Standalone HOWTO:
+=================
+
+One of the features of U-Boot is that you can dynamically load and
+run "standalone" applications, which can use some resources of
+U-Boot like console I/O functions or interrupt services.
+
+Two simple examples are included with the sources:
+
+"Hello World" Demo:
+-------------------
+
+'examples/hello_world.c' contains a small "Hello World" Demo
+application; it is automatically compiled when you build U-Boot.
+It's configured to run at address 0x00040004, so you can play with it
+like that:
+
+ => loads
+ ## Ready for S-Record download ...
+ ~>examples/hello_world.srec
+ 1 2 3 4 5 6 7 8 9 10 11 ...
+ [file transfer complete]
+ [connected]
+ ## Start Addr = 0x00040004
+
+ => go 40004 Hello World! This is a test.
+ ## Starting application at 0x00040004 ...
+ Hello World
+ argc = 7
+ argv[0] = "40004"
+ argv[1] = "Hello"
+ argv[2] = "World!"
+ argv[3] = "This"
+ argv[4] = "is"
+ argv[5] = "a"
+ argv[6] = "test."
+ argv[7] = "<NULL>"
+ Hit any key to exit ...
+
+ ## Application terminated, rc = 0x0
+
+Another example, which demonstrates how to register a CPM interrupt
+handler with the U-Boot code, can be found in 'examples/timer.c'.
+Here, a CPM timer is set up to generate an interrupt every second.
+The interrupt service routine is trivial, just printing a '.'
+character, but this is just a demo program. The application can be
+controlled by the following keys:
+
+ ? - print current values og the CPM Timer registers
+ b - enable interrupts and start timer
+ e - stop timer and disable interrupts
+ q - quit application
+
+ => loads
+ ## Ready for S-Record download ...
+ ~>examples/timer.srec
+ 1 2 3 4 5 6 7 8 9 10 11 ...
+ [file transfer complete]
+ [connected]
+ ## Start Addr = 0x00040004
+
+ => go 40004
+ ## Starting application at 0x00040004 ...
+ TIMERS=0xfff00980
+ Using timer 1
+ tgcr @ 0xfff00980, tmr @ 0xfff00990, trr @ 0xfff00994, tcr @ 0xfff00998, tcn @ 0xfff0099c, ter @ 0xfff009b0
+
+Hit 'b':
+ [q, b, e, ?] Set interval 1000000 us
+ Enabling timer
+Hit '?':
+ [q, b, e, ?] ........
+ tgcr=0x1, tmr=0xff1c, trr=0x3d09, tcr=0x0, tcn=0xef6, ter=0x0
+Hit '?':
+ [q, b, e, ?] .
+ tgcr=0x1, tmr=0xff1c, trr=0x3d09, tcr=0x0, tcn=0x2ad4, ter=0x0
+Hit '?':
+ [q, b, e, ?] .
+ tgcr=0x1, tmr=0xff1c, trr=0x3d09, tcr=0x0, tcn=0x1efc, ter=0x0
+Hit '?':
+ [q, b, e, ?] .
+ tgcr=0x1, tmr=0xff1c, trr=0x3d09, tcr=0x0, tcn=0x169d, ter=0x0
+Hit 'e':
+ [q, b, e, ?] ...Stopping timer
+Hit 'q':
+ [q, b, e, ?] ## Application terminated, rc = 0x0
+
+
+NetBSD Notes:
+=============
+
+Starting at version 0.9.2, U-Boot supports NetBSD both as host
+(build U-Boot) and target system (boots NetBSD/mpc8xx).
+
+Building requires a cross environment; it is known to work on
+NetBSD/i386 with the cross-powerpc-netbsd-1.3 package (you will also
+need gmake since the Makefiles are not compatible with BSD make).
+Note that the cross-powerpc package does not install include files;
+attempting to build U-Boot will fail because <machine/ansi.h> is
+missing. This file has to be installed and patched manually:
+
+ # cd /usr/pkg/cross/powerpc-netbsd/include
+ # mkdir powerpc
+ # ln -s powerpc machine
+ # cp /usr/src/sys/arch/powerpc/include/ansi.h powerpc/ansi.h
+ # ${EDIT} powerpc/ansi.h ## must remove __va_list, _BSD_VA_LIST
+
+Native builds *don't* work due to incompatibilities between native
+and U-Boot include files.
+
+Booting assumes that (the first part of) the image booted is a
+stage-2 loader which in turn loads and then invokes the kernel
+proper. Loader sources will eventually appear in the NetBSD source
+tree (probably in sys/arc/mpc8xx/stand/u-boot_stage2/); in the
+meantime, send mail to bruno@exet-ag.de and/or wd@denx.de for
+details.
+
+
+Implementation Internals:
+=========================
+
+The following is not intended to be a complete description of every
+implementation detail. However, it should help to understand the
+inner workings of U-Boot and make it easier to port it to custom
+hardware.
+
+
+Initial Stack, Global Data:
+---------------------------
+
+The implementation of U-Boot is complicated by the fact that U-Boot
+starts running out of ROM (flash memory), usually without access to
+system RAM (because the memory controller is not initialized yet).
+This means that we don't have writable Data or BSS segments, and BSS
+is not initialized as zero. To be able to get a C environment working
+at all, we have to allocate at least a minimal stack. Implementation
+options for this are defined and restricted by the CPU used: Some CPU
+models provide on-chip memory (like the IMMR area on MPC8xx and
+MPC826x processors), on others (parts of) the data cache can be
+locked as (mis-) used as memory, etc.
+
+It is essential to remember this, since it has some impact on the C
+code for the initialization procedures:
+
+* Initialized global data (data segment) is read-only. Do not attempt
+ to write it.
+
+* Do not use any unitialized global data (or implicitely initialized
+ as zero data - BSS segment) at all - this is undefined, initiali-
+ zation is performed later (when relocationg to RAM).
+
+* Stack space is very limited. Avoid big data buffers or things like
+ that.
+
+Having only the stack as writable memory limits means we cannot use
+normal global data to share information beween the code. But it
+turned out that the implementation of U-Boot can be greatly
+simplified by making a global data structure (gd_t) available to all
+functions. We could pass a pointer to this data as argument to _all_
+functions, but this would bloat the code. Instead we use a feature of
+the GCC compiler (Global Register Variables) to share the data: we
+place a pointer (gd) to the global data into a register which we
+reserve for this purpose.
+
+When chosing a register for such a purpose we are restricted by the
+relevant (E)ABI specifications for the current architecture, and by
+GCC's implementation.
+
+For PowerPC, the following registers have specific use:
+ R1: stack pointer
+ R2: TOC pointer
+ R3-R4: parameter passing and return values
+ R5-R10: parameter passing
+ R13: small data area pointer
+ R30: GOT pointer
+ R31: frame pointer
+
+ (U-Boot also uses R14 as internal GOT pointer.)
+
+ ==> U-Boot will use R29 to hold a pointer to the global data
+
+ Note: on PPC, we could use a static initializer (since the
+ address of the global data structure is known at compile time),
+ but it turned out that reserving a register results in somewhat
+ smaller code - although the code savings are not that big (on
+ average for all boards 752 bytes for the whole U-Boot image,
+ 624 text + 127 data).
+
+On ARM, the following registers are used:
+
+ R0: function argument word/integer result
+ R1-R3: function argument word
+ R9: GOT pointer
+ R10: stack limit (used only if stack checking if enabled)
+ R11: argument (frame) pointer
+ R12: temporary workspace
+ R13: stack pointer
+ R14: link register
+ R15: program counter
+
+ ==> U-Boot will use R8 to hold a pointer to the global data
+
+
+
+Memory Management:
+------------------
+
+U-Boot runs in system state and uses physical addresses, i.e. the
+MMU is not used either for address mapping nor for memory protection.
+
+The available memory is mapped to fixed addresses using the memory
+controller. In this process, a contiguous block is formed for each
+memory type (Flash, SDRAM, SRAM), even when it consists of several
+physical memory banks.
+
+U-Boot is installed in the first 128 kB of the first Flash bank (on
+TQM8xxL modules this is the range 0x40000000 ... 0x4001FFFF). After
+booting and sizing and initializing DRAM, the code relocates itself
+to the upper end of DRAM. Immediately below the U-Boot code some
+memory is reserved for use by malloc() [see CFG_MALLOC_LEN
+configuration setting]. Below that, a structure with global Board
+Info data is placed, followed by the stack (growing downward).
+
+Additionally, some exception handler code is copied to the low 8 kB
+of DRAM (0x00000000 ... 0x00001FFF).
+
+So a typical memory configuration with 16 MB of DRAM could look like
+this:
+
+ 0x0000 0000 Exception Vector code
+ :
+ 0x0000 1FFF
+ 0x0000 2000 Free for Application Use
+ :
+ :
+
+ :
+ :
+ 0x00FB FF20 Monitor Stack (Growing downward)
+ 0x00FB FFAC Board Info Data and permanent copy of global data
+ 0x00FC 0000 Malloc Arena
+ :
+ 0x00FD FFFF
+ 0x00FE 0000 RAM Copy of Monitor Code
+ ... eventually: LCD or video framebuffer
+ ... eventually: pRAM (Protected RAM - unchanged by reset)
+ 0x00FF FFFF [End of RAM]
+
+
+System Initialization:
+----------------------
+
+In the reset configuration, U-Boot starts at the reset entry point
+(on most PowerPC systens at address 0x00000100). Because of the reset
+configuration for CS0# this is a mirror of the onboard Flash memory.
+To be able to re-map memory U-Boot then jumps to it's link address.
+To be able to implement the initialization code in C, a (small!)
+initial stack is set up in the internal Dual Ported RAM (in case CPUs
+which provide such a feature like MPC8xx or MPC8260), or in a locked
+part of the data cache. After that, U-Boot initializes the CPU core,
+the caches and the SIU.
+
+Next, all (potentially) available memory banks are mapped using a
+preliminary mapping. For example, we put them on 512 MB boundaries
+(multiples of 0x20000000: SDRAM on 0x00000000 and 0x20000000, Flash
+on 0x40000000 and 0x60000000, SRAM on 0x80000000). Then UPM A is
+programmed for SDRAM access. Using the temporary configuration, a
+simple memory test is run that determines the size of the SDRAM
+banks.
+
+When there is more than one SDRAM bank, and the banks are of
+different size, the larger is mapped first. For equal size, the first
+bank (CS2#) is mapped first. The first mapping is always for address
+0x00000000, with any additional banks following immediately to create
+contiguous memory starting from 0.
+
+Then, the monitor installs itself at the upper end of the SDRAM area
+and allocates memory for use by malloc() and for the global Board
+Info data; also, the exception vector code is copied to the low RAM
+pages, and the final stack is set up.
+
+Only after this relocation will you have a "normal" C environment;
+until that you are restricted in several ways, mostly because you are
+running from ROM, and because the code will have to be relocated to a
+new address in RAM.
+
+
+U-Boot Porting Guide:
+----------------------
+
+[Based on messages by Jerry Van Baren in the U-Boot-Users mailing
+list, Octover 2002]
+
+
+int main (int argc, char *argv[])
+{
+ sighandler_t no_more_time;
+
+ signal (SIGALRM, no_more_time);
+ alarm (PROJECT_DEADLINE - toSec (3 * WEEK));
+
+ if (available_money > available_manpower) {
+ pay consultant to port U-Boot;
+ return 0;
+ }
+
+ Download latest U-Boot source;
+
+ if (clueless) {
+ email ("Hi, I am new to U-Boot, how do I get started?");
+ }
+
+ while (learning) {
+ Read the README file in the top level directory;
+ Read http://www.denx.de/re/DPLG.html
+ Read the source, Luke;
+ }
+
+ if (available_money > toLocalCurrency ($2500)) {
+ Buy a BDI2000;
+ } else {
+ Add a lot of aggravation and time;
+ }
+
+ Create your own board support subdirectory;
+
+ while (!running) {
+ do {
+ Add / modify source code;
+ } until (compiles);
+ Debug;
+ if (clueless)
+ email ("Hi, I am having problems...");
+ }
+ Send patch file to Wolfgang;
+
+ return 0;
+}
+
+void no_more_time (int sig)
+{
+ hire_a_guru();
+}
+
+
+
+Coding Standards:
+-----------------
+
+All contributions to U-Boot should conform to the Linux kernel
+coding style; see the file "Documentation/CodingStyle" in your Linux
+kernel source directory.
+
+Please note that U-Boot is implemented in C (and to some small parts
+in Assembler); no C++ is used, so please do not use C++ style
+comments (//) in your code.
+
+Submissions which do not conform to the standards may be returned
+with a request to reformat the changes.
+
+
+Submitting Patches:
+-------------------
+
+Since the number of patches for U-Boot is growing, we need to
+establish some rules. Submissions which do not conform to these rules
+may be rejected, even when they contain important and valuable stuff.
+
+
+When you send a patch, please include the following information with
+it:
+
+* For bug fixes: a description of the bug and how your patch fixes
+ this bug. Please try to include a way of demonstrating that the
+ patch actually fixes something.
+
+* For new features: a description of the feature and your
+ implementation.
+
+* A CHANGELOG entry as plaintext (separate from the patch)
+
+* For major contributions, your entry to the CREDITS file
+
+* When you add support for a new board, don't forget to add this
+ board to the MAKEALL script, too.
+
+* If your patch adds new configuration options, don't forget to
+ document these in the README file.
+
+* The patch itself. If you are accessing the CVS repository use "cvs
+ update; cvs diff -puRN"; else, use "diff -purN OLD NEW". If your
+ version of diff does not support these options, then get the latest
+ version of GNU diff.
+
+ We accept patches as plain text, MIME attachments or as uuencoded
+ gzipped text.
+
+Notes:
+
+* Before sending the patch, run the MAKEALL script on your patched
+ source tree and make sure that no errors or warnings are reported
+ for any of the boards.
+
+* Keep your modifications to the necessary minimum: A patch
+ containing several unrelated changes or arbitrary reformats will be
+ returned with a request to re-formatting / split it.
+
+* If you modify existing code, make sure that your new code does not
+ add to the memory footprint of the code ;-) Small is beautiful!
+ When adding new features, these should compile conditionally only
+ (using #ifdef), and the resulting code with the new feature
+ disabled must not need more memory than the old code without your
+ modification.
--- /dev/null
+/*
+ * Simple serial driver for Cogent motherboard serial ports
+ * for use during boot
+ */
+
+#include <common.h>
+#include <board/cogent/serial.h>
+
+#if (CMA_MB_CAPS & CMA_MB_CAP_SERPAR)
+
+#if (defined(CONFIG_8xx) && defined(CONFIG_8xx_CONS_NONE)) || \
+ (defined(CONFIG_8260) && defined(CONFIG_CONS_NONE))
+
+#if CONFIG_CONS_INDEX == 1
+#define CMA_MB_SERIAL_BASE CMA_MB_SERIALA_BASE
+#elif CONFIG_CONS_INDEX == 2
+#define CMA_MB_SERIAL_BASE CMA_MB_SERIALB_BASE
+#elif CONFIG_CONS_INDEX == 3 && (CMA_MB_CAPS & CMA_MB_CAP_SER2)
+#define CMA_MB_SERIAL_BASE CMA_MB_SER2A_BASE
+#elif CONFIG_CONS_INDEX == 4 && (CMA_MB_CAPS & CMA_MB_CAP_SER2)
+#define CMA_MB_SERIAL_BASE CMA_MB_SER2B_BASE
+#else
+#error CONFIG_CONS_INDEX must be configured for Cogent motherboard serial
+#endif
+
+int serial_init (void)
+{
+/* DECLARE_GLOBAL_DATA_PTR; */
+
+ cma_mb_serial *mbsp = (cma_mb_serial *)CMA_MB_SERIAL_BASE;
+
+ cma_mb_reg_write(&mbsp->ser_ier, 0x00); /* turn off interrupts */
+ serial_setbrg ();
+ cma_mb_reg_write(&mbsp->ser_lcr, 0x03); /* 8 data, 1 stop, no parity */
+ cma_mb_reg_write(&mbsp->ser_mcr, 0x03); /* RTS/DTR */
+ cma_mb_reg_write(&mbsp->ser_fcr, 0x07); /* Clear & enable FIFOs */
+
+ return (0);
+}
+
+void
+serial_setbrg (void)
+{
+ DECLARE_GLOBAL_DATA_PTR;
+
+ cma_mb_serial *mbsp = (cma_mb_serial *)CMA_MB_SERIAL_BASE;
+ unsigned int divisor;
+ unsigned char lcr;
+
+ if ((divisor = br_to_div(gd->baudrate)) == 0)
+ divisor = DEFDIV;
+
+ lcr = cma_mb_reg_read(&mbsp->ser_lcr);
+ cma_mb_reg_write(&mbsp->ser_lcr, lcr|0x80);/* Access baud rate(set DLAB)*/
+ cma_mb_reg_write(&mbsp->ser_brl, divisor & 0xff);
+ cma_mb_reg_write(&mbsp->ser_brh, (divisor >> 8) & 0xff);
+ cma_mb_reg_write(&mbsp->ser_lcr, lcr); /* unset DLAB */
+}
+
+void
+serial_putc(const char c)
+{
+ cma_mb_serial *mbsp = (cma_mb_serial *)CMA_MB_SERIAL_BASE;
+
+ if (c == '\n')
+ serial_putc('\r');
+
+ while ((cma_mb_reg_read(&mbsp->ser_lsr) & LSR_THRE) == 0)
+ ;
+
+ cma_mb_reg_write(&mbsp->ser_thr, c);
+}
+
+void
+serial_puts(const char *s)
+{
+ while (*s != '\0')
+ serial_putc(*s++);
+}
+
+int
+serial_getc(void)
+{
+ cma_mb_serial *mbsp = (cma_mb_serial *)CMA_MB_SERIAL_BASE;
+
+ while ((cma_mb_reg_read(&mbsp->ser_lsr) & LSR_DR) == 0)
+ ;
+
+ return ((int)cma_mb_reg_read(&mbsp->ser_rhr) & 0x7f);
+}
+
+int
+serial_tstc(void)
+{
+ cma_mb_serial *mbsp = (cma_mb_serial *)CMA_MB_SERIAL_BASE;
+
+ return ((cma_mb_reg_read(&mbsp->ser_lsr) & LSR_DR) != 0);
+}
+
+#endif /* CONS_NONE */
+
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB) && \
+ defined(CONFIG_KGDB_NONE)
+
+#if CONFIG_KGDB_INDEX == CONFIG_CONS_INDEX
+#error Console and kgdb are on the same serial port - this is not supported
+#endif
+
+#if CONFIG_KGDB_INDEX == 1
+#define CMA_MB_KGDB_SER_BASE CMA_MB_SERIALA_BASE
+#elif CONFIG_KGDB_INDEX == 2
+#define CMA_MB_KGDB_SER_BASE CMA_MB_SERIALB_BASE
+#elif CONFIG_KGDB_INDEX == 3 && (CMA_MB_CAPS & CMA_MB_CAP_SER2)
+#define CMA_MB_KGDB_SER_BASE CMA_MB_SER2A_BASE
+#elif CONFIG_KGDB_INDEX == 4 && (CMA_MB_CAPS & CMA_MB_CAP_SER2)
+#define CMA_MB_KGDB_SER_BASE CMA_MB_SER2B_BASE
+#else
+#error CONFIG_KGDB_INDEX must be configured for Cogent motherboard serial
+#endif
+
+void
+kgdb_serial_init(void)
+{
+ cma_mb_serial *mbsp = (cma_mb_serial *)CMA_MB_KGDB_SER_BASE;
+ unsigned int divisor;
+
+ if ((divisor = br_to_div(CONFIG_KGDB_BAUDRATE)) == 0)
+ divisor = DEFDIV;
+
+ cma_mb_reg_write(&mbsp->ser_ier, 0x00); /* turn off interrupts */
+ cma_mb_reg_write(&mbsp->ser_lcr, 0x80); /* Access baud rate(set DLAB)*/
+ cma_mb_reg_write(&mbsp->ser_brl, divisor & 0xff);
+ cma_mb_reg_write(&mbsp->ser_brh, (divisor >> 8) & 0xff);
+ cma_mb_reg_write(&mbsp->ser_lcr, 0x03); /* 8 data, 1 stop, no parity */
+ cma_mb_reg_write(&mbsp->ser_mcr, 0x03); /* RTS/DTR */
+ cma_mb_reg_write(&mbsp->ser_fcr, 0x07); /* Clear & enable FIFOs */
+
+ printf("[on cma10x serial port B] ");
+}
+
+void
+putDebugChar(int c)
+{
+ cma_mb_serial *mbsp = (cma_mb_serial *)CMA_MB_KGDB_SER_BASE;
+
+ while ((cma_mb_reg_read(&mbsp->ser_lsr) & LSR_THRE) == 0)
+ ;
+
+ cma_mb_reg_write(&mbsp->ser_thr, c & 0xff);
+}
+
+void
+putDebugStr(const char *str)
+{
+ while (*str != '\0') {
+ if (*str == '\n')
+ putDebugChar('\r');
+ putDebugChar(*str++);
+ }
+}
+
+int
+getDebugChar(void)
+{
+ cma_mb_serial *mbsp = (cma_mb_serial *)CMA_MB_KGDB_SER_BASE;
+
+ while ((cma_mb_reg_read(&mbsp->ser_lsr) & LSR_DR) == 0)
+ ;
+
+ return ((int)cma_mb_reg_read(&mbsp->ser_rhr) & 0x7f);
+}
+
+void
+kgdb_interruptible(int yes)
+{
+ cma_mb_serial *mbsp = (cma_mb_serial *)CMA_MB_KGDB_SER_BASE;
+
+ if (yes == 1) {
+ printf("kgdb: turning serial ints on\n");
+ cma_mb_reg_write(&mbsp->ser_ier, 0xf);
+ }
+ else {
+ printf("kgdb: turning serial ints off\n");
+ cma_mb_reg_write(&mbsp->ser_ier, 0x0);
+ }
+}
+
+#endif /* KGDB && KGDB_NONE */
+
+#endif /* CAPS & SERPAR */
--- /dev/null
+/*
+ * (C) Copyright 2001
+ * Rob Taylor, Flying Pig Systems. robt@flyingpig.com.
+ *
+ * (C) Copyright 2001, 2002
+ * Wolfgang Denk, DENX Software Engineering, <wd@denx.de>
+
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <mpc824x.h>
+#include <asm/processor.h>
+#include <pci.h>
+
+#define BOARD_REV_REG 0xFE80002B
+
+int checkboard (void)
+{
+ DECLARE_GLOBAL_DATA_PTR;
+
+ char revision = *(volatile char *)(BOARD_REV_REG);
+ char buf[32];
+
+ puts ("Board: CU824 ");
+ printf("Revision %d ", revision);
+ printf("Local Bus at %s MHz\n", strmhz(buf, gd->bus_clk));
+
+ return 0;
+}
+
+long int initdram(int board_type)
+{
+ int i, cnt;
+ volatile uchar * base = CFG_SDRAM_BASE;
+ volatile ulong * addr;
+ ulong save[32];
+ ulong val, ret = 0;
+
+ for (i=0, cnt=(CFG_MAX_RAM_SIZE / sizeof(long)) >> 1; cnt > 0; cnt >>= 1) {
+ addr = (volatile ulong *)base + cnt;
+ save[i++] = *addr;
+ *addr = ~cnt;
+ }
+
+ addr = (volatile ulong *)base;
+ save[i] = *addr;
+ *addr = 0;
+
+ if (*addr != 0) {
+ *addr = save[i];
+ goto Done;
+ }
+
+ for (cnt = 1; cnt <= CFG_MAX_RAM_SIZE / sizeof(long); cnt <<= 1) {
+ addr = (volatile ulong *)base + cnt;
+ val = *addr;
+ *addr = save[--i];
+ if (val != ~cnt) {
+ ulong new_bank0_end = cnt * sizeof(long) - 1;
+ ulong mear1 = mpc824x_mpc107_getreg(MEAR1);
+ ulong emear1 = mpc824x_mpc107_getreg(EMEAR1);
+ mear1 = (mear1 & 0xFFFFFF00) |
+ ((new_bank0_end & MICR_ADDR_MASK) >> MICR_ADDR_SHIFT);
+ emear1 = (emear1 & 0xFFFFFF00) |
+ ((new_bank0_end & MICR_ADDR_MASK) >> MICR_EADDR_SHIFT);
+ mpc824x_mpc107_setreg(MEAR1, mear1);
+ mpc824x_mpc107_setreg(EMEAR1, emear1);
+
+ ret = cnt * sizeof(long);
+ goto Done;
+ }
+ }
+
+ ret = CFG_MAX_RAM_SIZE;
+Done:
+ return ret;
+}
+
+/*
+ * Initialize PCI Devices, report devices found.
+ */
+#ifndef CONFIG_PCI_PNP
+static struct pci_config_table pci_sandpoint_config_table[] = {
+ { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
+ PCI_BUS(CFG_ETH_DEV_FN), PCI_DEV(CFG_ETH_DEV_FN), PCI_FUNC(CFG_ETH_DEV_FN),
+ pci_cfgfunc_config_device, { CFG_ETH_IOBASE,
+ 0,
+ PCI_COMMAND_IO | PCI_COMMAND_MASTER }},
+ { }
+};
+#endif
+
+struct pci_controller hose = {
+#ifndef CONFIG_PCI_PNP
+ config_table: pci_sandpoint_config_table,
+#endif
+};
+
+void pci_init(void)
+{
+ pci_mpc824x_init(&hose);
+}
--- /dev/null
+/*
+ * (C) Copyright 2000
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
+OUTPUT_ARCH(arm)
+ENTRY(_start)
+SECTIONS
+{
+ . = 0x00000000;
+
+ . = ALIGN(4);
+ .text :
+ {
+ cpu/sa1100/start.o (.text)
+ *(.text)
+ }
+
+ . = ALIGN(4);
+ .rodata : { *(.rodata) }
+
+ . = ALIGN(4);
+ .data : { *(.data) }
+
+ . = ALIGN(4);
+ .got : { *(.got) }
+
+ armboot_end_data = .;
+
+ . = ALIGN(4);
+ .bss : { *(.bss) }
+
+ armboot_end = .;
+}
--- /dev/null
+/*
+ * Copyright (C) 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 "ebony.h"
+#include <asm/processor.h>
+
+#define BOOT_SMALL_FLASH 32 /* 00100000 */
+#define FLASH_ONBD_N 2 /* 00000010 */
+#define FLASH_SRAM_SEL 1 /* 00000001 */
+
+long int fixed_sdram (void);
+
+int board_pre_init (void)
+{
+ uint reg;
+ unsigned char *fpga_base = (unsigned char *) CFG_FPGA_BASE;
+ unsigned char status;
+
+
+ /*--------------------------------------------------------------------
+ * Setup the external bus controller/chip selects
+ *-------------------------------------------------------------------*/
+ mtdcr (ebccfga, xbcfg);
+ reg = mfdcr (ebccfgd);
+ mtdcr (ebccfgd, reg | 0x04000000); /* Set ATC */
+
+ mtebc (pb1ap, 0x02815480); /* NVRAM/RTC */
+ mtebc (pb1cr, 0x48018000); /* BA=0x480 1MB R/W 8-bit */
+ mtebc (pb7ap, 0x01015280); /* FPGA registers */
+ mtebc (pb7cr, 0x48318000); /* BA=0x483 1MB R/W 8-bit */
+
+ /* read FPGA_REG0 and set the bus controller */
+ status = *fpga_base;
+ if ((status & BOOT_SMALL_FLASH) && !(status & FLASH_ONBD_N)) {
+ mtebc (pb0ap, 0x9b015480); /* FLASH/SRAM */
+ mtebc (pb0cr, 0xfff18000); /* BAS=0xfff 1MB R/W 8-bit */
+ mtebc (pb2ap, 0x9b015480); /* 4MB FLASH */
+ mtebc (pb2cr, 0xff858000); /* BAS=0xff8 4MB R/W 8-bit */
+ } else {
+ mtebc (pb0ap, 0x9b015480); /* 4MB FLASH */
+ mtebc (pb0cr, 0xffc58000); /* BAS=0xffc 4MB R/W 8-bit */
+
+ /* set CS2 if FLASH_ONBD_N == 0 */
+ if (!(status & FLASH_ONBD_N)) {
+ mtebc (pb2ap, 0x9b015480); /* FLASH/SRAM */
+ mtebc (pb2cr, 0xff818000); /* BAS=0xff8 4MB R/W 8-bit */
+ }
+ }
+
+ /*--------------------------------------------------------------------
+ * Setup the interrupt controller polarities, triggers, etc.
+ *-------------------------------------------------------------------*/
+ mtdcr (uic0sr, 0xffffffff); /* clear all */
+ mtdcr (uic0er, 0x00000000); /* disable all */
+ mtdcr (uic0cr, 0x00000009); /* SMI & UIC1 crit are critical */
+ mtdcr (uic0pr, 0xfffffe13); /* per ref-board manual */
+ mtdcr (uic0tr, 0x01c00008); /* per ref-board manual */
+ mtdcr (uic0vr, 0x00000001); /* int31 highest, base=0x000 */
+ mtdcr (uic0sr, 0xffffffff); /* clear all */
+
+ mtdcr (uic1sr, 0xffffffff); /* clear all */
+ mtdcr (uic1er, 0x00000000); /* disable all */
+ mtdcr (uic1cr, 0x00000000); /* all non-critical */
+ mtdcr (uic1pr, 0xffffe0ff); /* per ref-board manual */
+ mtdcr (uic1tr, 0x00ffc000); /* per ref-board manual */
+ mtdcr (uic1vr, 0x00000001); /* int31 highest, base=0x000 */
+ mtdcr (uic1sr, 0xffffffff); /* clear all */
+
+ return 0;
+}
+
+
+
+int checkboard (void)
+{
+ sys_info_t sysinfo;
+
+ get_sys_info (&sysinfo);
+
+ printf ("Board: IBM 440GP Evaluation Board (Ebony)\n");
+ printf ("\tVCO: %lu MHz\n", sysinfo.freqVCOMhz / 1000000);
+ printf ("\tCPU: %lu MHz\n", sysinfo.freqProcessor / 1000000);
+ printf ("\tPLB: %lu MHz\n", sysinfo.freqPLB / 1000000);
+ printf ("\tOPB: %lu MHz\n", sysinfo.freqOPB / 1000000);
+ printf ("\tEPB: %lu MHz\n", sysinfo.freqEPB / 1000000);
+ return (0);
+}
+
+
+long int initdram (int board_type)
+{
+ long dram_size = 0;
+ extern long spd_sdram (void);
+
+#if defined(CONFIG_SPD_EEPROM)
+ dram_size = spd_sdram ();
+#else
+ dram_size = fixed_sdram ();
+#endif
+ return dram_size;
+}
+
+
+#if defined(CFG_DRAM_TEST)
+int testdram (void)
+{
+ uint *pstart = (uint *) 0x00000000;
+ uint *pend = (uint *) 0x08000000;
+ uint *p;
+
+ 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;
+ }
+ }
+
+ 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;
+ }
+ }
+ return 0;
+}
+#endif
+
+#if !defined(CONFIG_SPD_EEPROM)
+/*************************************************************************
+ * fixed sdram init -- doesn't use serial presence detect.
+ *
+ * Assumes: 128 MB, non-ECC, non-registered
+ * PLB @ 133 MHz
+ *
+ ************************************************************************/
+long int fixed_sdram (void)
+{
+ uint reg;
+
+ /*--------------------------------------------------------------------
+ * Setup some default
+ *------------------------------------------------------------------*/
+ mtsdram (mem_uabba, 0x00000000); /* ubba=0 (default) */
+ mtsdram (mem_slio, 0x00000000); /* rdre=0 wrre=0 rarw=0 */
+ mtsdram (mem_devopt, 0x00000000); /* dll=0 ds=0 (normal) */
+ mtsdram (mem_wddctr, 0x00000000); /* wrcp=0 dcd=0 */
+ mtsdram (mem_clktr, 0x40000000); /* clkp=1 (90 deg wr) dcdt=0 */
+
+ /*--------------------------------------------------------------------
+ * Setup for board-specific specific mem
+ *------------------------------------------------------------------*/
+ /*
+ * Following for CAS Latency = 2.5 @ 133 MHz PLB
+ */
+ mtsdram (mem_b0cr, 0x000a4001); /* SDBA=0x000 128MB, Mode 3, enabled */
+ mtsdram (mem_tr0, 0x410a4012); /* WR=2 WD=1 CL=2.5 PA=3 CP=4 LD=2 */
+ /* RA=10 RD=3 */
+ mtsdram (mem_tr1, 0x8080082f); /* SS=T2 SL=STAGE 3 CD=1 CT=0x02f */
+ mtsdram (mem_rtr, 0x08200000); /* Rate 15.625 ns @ 133 MHz PLB */
+ mtsdram (mem_cfg1, 0x00000000); /* Self-refresh exit, disable PM */
+ udelay (400); /* Delay 200 usecs (min) */
+
+ /*--------------------------------------------------------------------
+ * Enable the controller, then wait for DCEN to complete
+ *------------------------------------------------------------------*/
+ mtsdram (mem_cfg0, 0x86000000); /* DCEN=1, PMUD=1, 64-bit */
+ for (;;) {
+ mfsdram (mem_mcsts, reg);
+ if (reg & 0x80000000)
+ break;
+ }
+
+ return (128 * 1024 * 1024); /* 128 MB */
+}
+#endif /* !defined(CONFIG_SPD_EEPROM) */
+
+
+/*************************************************************************
+ * pci_pre_init
+ *
+ * This routine is called just prior to registering the hose and gives
+ * the board the opportunity to check things. Returning a value of zero
+ * indicates that things are bad & PCI initialization should be aborted.
+ *
+ * Different boards may wish to customize the pci controller structure
+ * (add regions, override default access routines, etc) or perform
+ * certain pre-initialization actions.
+ *
+ ************************************************************************/
+#if defined(CONFIG_PCI) && defined(CFG_PCI_PRE_INIT)
+int pci_pre_init(struct pci_controller * hose )
+{
+ unsigned long strap;
+
+ /*--------------------------------------------------------------------------+
+ * The ebony board is always configured as the host & requires the
+ * PCI arbiter to be enabled.
+ *--------------------------------------------------------------------------*/
+ strap = mfdcr(cpc0_strp1);
+ if( (strap & 0x00100000) == 0 ){
+ printf("PCI: CPC0_STRP1[PAE] not set.\n");
+ return 0;
+ }
+
+ return 1;
+}
+#endif /* defined(CONFIG_PCI) && defined(CFG_PCI_PRE_INIT) */
+
+/*************************************************************************
+ * pci_target_init
+ *
+ * The bootstrap configuration provides default settings for the pci
+ * inbound map (PIM). But the bootstrap config choices are limited and
+ * may not be sufficient for a given board.
+ *
+ ************************************************************************/
+#if defined(CONFIG_PCI) && defined(CFG_PCI_TARGET_INIT)
+void pci_target_init(struct pci_controller * hose )
+{
+ DECLARE_GLOBAL_DATA_PTR;
+
+ /*--------------------------------------------------------------------------+
+ * Disable everything
+ *--------------------------------------------------------------------------*/
+ out32r( PCIX0_PIM0SA, 0 ); /* disable */
+ out32r( PCIX0_PIM1SA, 0 ); /* disable */
+ out32r( PCIX0_PIM2SA, 0 ); /* disable */
+ out32r( PCIX0_EROMBA, 0 ); /* disable expansion rom */
+
+ /*--------------------------------------------------------------------------+
+ * Map all of SDRAM to PCI address 0x0000_0000. Note that the 440 strapping
+ * options to not support sizes such as 128/256 MB.
+ *--------------------------------------------------------------------------*/
+ out32r( PCIX0_PIM0LAL, CFG_SDRAM_BASE );
+ out32r( PCIX0_PIM0LAH, 0 );
+ out32r( PCIX0_PIM0SA, ~(gd->ram_size - 1) | 1 );
+
+ out32r( PCIX0_BAR0, 0 );
+
+ /*--------------------------------------------------------------------------+
+ * Program the board's subsystem id/vendor id
+ *--------------------------------------------------------------------------*/
+ out16r( PCIX0_SBSYSVID, CFG_PCI_SUBSYS_VENDORID );
+ out16r( PCIX0_SBSYSID, CFG_PCI_SUBSYS_DEVICEID );
+
+ out16r( PCIX0_CMD, in16r(PCIX0_CMD) | PCI_COMMAND_MEMORY );
+}
+#endif /* defined(CONFIG_PCI) && defined(CFG_PCI_TARGET_INIT) */
+
+
+/*************************************************************************
+ * is_pci_host
+ *
+ * This routine is called to determine if a pci scan should be
+ * performed. With various hardware environments (especially cPCI and
+ * PPMC) it's insufficient to depend on the state of the arbiter enable
+ * bit in the strap register, or generic host/adapter assumptions.
+ *
+ * Rather than hard-code a bad assumption in the general 440 code, the
+ * 440 pci code requires the board to decide at runtime.
+ *
+ * Return 0 for adapter mode, non-zero for host (monarch) mode.
+ *
+ *
+ ************************************************************************/
+#if defined(CONFIG_PCI)
+int is_pci_host(struct pci_controller *hose)
+{
+ /* The ebony board is always configured as host. */
+ return(1);
+}
+#endif /* defined(CONFIG_PCI) */
--- /dev/null
+/*
+* Copyright (C) 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
+*/
+
+#include <ppc_asm.tmpl>
+#include <config.h>
+
+/* General */
+#define TLB_VALID 0x00000200
+
+/* Supported page sizes */
+
+#define SZ_1K 0x00000000
+#define SZ_4K 0x00000010
+#define SZ_16K 0x00000020
+#define SZ_64K 0x00000030
+#define SZ_256K 0x00000040
+#define SZ_1M 0x00000050
+#define SZ_16M 0x00000070
+#define SZ_256M 0x00000090
+
+/* Storage attributes */
+#define SA_W 0x00000800 /* Write-through */
+#define SA_I 0x00000400 /* Caching inhibited */
+#define SA_M 0x00000200 /* Memory coherence */
+#define SA_G 0x00000100 /* Guarded */
+#define SA_E 0x00000080 /* Endian */
+
+/* Access control */
+#define AC_X 0x00000024 /* Execute */
+#define AC_W 0x00000012 /* Write */
+#define AC_R 0x00000009 /* Read */
+
+/* Some handy macros */
+
+#define EPN(e) ((e) & 0xfffffc00)
+#define TLB0(epn,sz) ( (EPN((epn)) | (sz) | TLB_VALID ) )
+#define TLB1(rpn,erpn) ( ((rpn)&0xfffffc00) | (erpn) )
+#define TLB2(a) ( (a)&0x00000fbf )
+
+#define tlbtab_start\
+ mflr r1 ;\
+ bl 0f ;
+
+#define tlbtab_end\
+ .long 0, 0, 0 ; \
+0: mflr r0 ; \
+ mtlr r1 ; \
+ blr ;
+
+#define tlbentry(epn,sz,rpn,erpn,attr)\
+ .long TLB0(epn,sz),TLB1(rpn,erpn),TLB2(attr)
+
+
+/**************************************************************************
+ * TLB TABLE
+ *
+ * This table is used by the cpu boot code to setup the initial tlb
+ * entries. Rather than make broad assumptions in the cpu source tree,
+ * this table lets each board set things up however they like.
+ *
+ * Pointer to the table is returned in r1
+ *
+ *************************************************************************/
+
+ .section .bootpg,"ax"
+ .globl tlbtab
+
+tlbtab:
+ tlbtab_start
+ tlbentry( 0xf0000000, SZ_256M, 0xf0000000, 1, AC_R|AC_W|AC_X|SA_G|SA_I)
+ tlbentry( CFG_PERIPHERAL_BASE, SZ_256M, 0x40000000, 1, AC_R|AC_W|SA_G|SA_I)
+ 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_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
+
+
--- /dev/null
+/*
+ * (C) Copyright 2001 ELTEC Elektronik AG
+ * Frank Gottschling <fgottschling@eltec.de>
+ *
+ * ELTEC BAB PPC RAM initialization
+ *
+ * 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 <mpc75x.h>
+#include <mpc106.h>
+#include <version.h>
+
+#include <ppc_asm.tmpl>
+#include <ppc_defs.h>
+
+/*
+ * This following contains the entry code for the initialization code
+ * for the MPC 106, a PCI Bridge/Memory Controller.
+ * Register usage:
+ * r0 = ramtest scratch register, toggleError loop counter
+ * r1 = 0xfec0 0cf8 CONFIG_ADDRESS
+ * r2 = 0xfee0 0cfc CONFIG_DATA
+ * r3 = scratch register, subroutine argument and return value, ramtest size
+ * r4 = scratch register, spdRead clock mask, OutHex loop count
+ * r5 = ramtest scratch register
+ * r6 = toggleError 1st value, spdRead port mask
+ * r7 = toggleError 2nd value, ramtest scratch register,
+ * spdRead scratch register (0x00)
+ * r8 = ramtest scratch register, spdRead scratch register (0x80)
+ * r9 = ramtest scratch register, toggleError loop end, OutHex digit
+ * r10 = ramtest scratch register, spdWriteByte parameter,
+ * spdReadByte return value, printf pointer to COM1
+ * r11 = startType
+ * r12 = ramtest scratch register, spdRead data mask
+ * r13 = pointer to message block
+ * r14 = pointer to GOT
+ * r15 = scratch register, SPD save
+ * r16 = bank0 size, total memory size
+ * r17 = bank1 size
+ * r18 = bank2 size
+ * r19 = bank3 size
+ * r20 = MCCR1, MSAR1
+ * r21 = MCCR3, MEAR1
+ * r22 = MCCR4, MBER
+ * r23 = EMSAR1
+ * r24 = EMEAR1
+ * r25 = save link register 1st level
+ * r26 = save link register 2nd level
+ * r27 = save link register 3rd level
+ * r30 = pointer to GPIO for spdRead
+ */
+
+
+.globl board_asm_init
+board_asm_init:
+/*
+ * setup pointer to message block
+ */
+ mflr r25 /* save away link register */
+ bl get_lnk_reg /* r3=addr of next instruction */
+ subi r4, r3, 8 /* r4=board_asm_init addr */
+ addi r13, r4, (MessageBlock-board_asm_init)
+/*
+ * dcache_disable
+ */
+ mfspr r3, HID0
+ li r4, HID0_DCE
+ andc r3, r3, r4
+ mr r2, r3
+ ori r3, r3, HID0_DCI
+ sync
+ mtspr HID0, r3
+ mtspr HID0, r2
+ isync
+ sync
+/*
+ * icache_disable
+ */
+ mfspr r3, HID0
+ li r4, 0
+ ori r4, r4, HID0_ICE
+ andc r3, r3, r4
+ sync
+ mtspr HID0, r3
+/*
+ * invalidate caches
+ */
+ ori r3, r3, (HID0_ICE | HID0_ICFI | HID0_DCI | HID0_DCE)
+ or r4, r4, r3
+ isync
+ mtspr HID0, r4
+ andc r4, r4, r3
+ isync
+ mtspr HID0, r4
+ isync
+/*
+ * icache_enable
+ */
+ mfspr r3, HID0
+ ori r3, r3, (HID0_ICE | HID0_ICFI)
+ sync
+ mtspr HID0, r3
+
+ lis r1, 0xfec0
+ ori r1, r1, 0x0cf8
+ lis r2, 0xfee0
+ ori r2, r2, 0xcfc
+
+#ifdef CFG_ADDRESS_MAP_A
+/*
+ * Switch to address map A if necessary.
+ */
+ lis r3, MPC106_REG@h
+ ori r3, r3, PCI_PICR1
+ stwbrx r3, 0, r1
+ sync
+ lwbrx r4, 0, r2
+ sync
+ lis r0, PICR1_XIO_MODE@h
+ ori r0, r0, PICR1_XIO_MODE@l
+ andc r4, r4, r0
+ lis r0, PICR1_ADDRESS_MAP@h
+ ori r0, r0, PICR1_ADDRESS_MAP@l
+ or r4, r4, r0
+ stwbrx r4, 0, r2
+ sync
+#endif
+
+/*
+ * Do the init for the SIO.
+ */
+ bl .sioInit
+
+ addi r3, r13, (MinitLogo-MessageBlock)
+ bl Printf
+
+ addi r3, r13, (Mspd01-MessageBlock)
+ bl Printf
+/*
+ * Memory cofiguration using SPD information stored on the SODIMMs
+ */
+ li r17, 0
+ li r18, 0
+ li r19, 0
+
+ li r3, 0x0002 /* get RAM type from spd for bank0/1 */
+ bl spdRead
+
+ cmpi 0, 0, r3, -1 /* error ? */
+ bne noSpdError
+
+ addi r3, r13, (Mfail-MessageBlock)
+ bl Printf
+
+ li r6, 0xe0 /* error codes in r6 and r7 */
+ li r7, 0x00
+ b toggleError /* fail - loop forever */
+
+noSpdError:
+ mr r15, r3 /* save r3 */
+
+ addi r3, r13, (Mok-MessageBlock)
+ bl Printf
+
+ cmpli 0, 0, r15, 0x0001 /* FPM ? */
+ beq configFPM
+ cmpli 0, 0, r15, 0x0002 /* EDO ? */
+ beq configEDO
+ cmpli 0, 0, r15, 0x0004 /* SDRAM ? */
+ beq configSDRAM
+
+ li r6, 0xe0 /* error codes in r6 and r7 */
+ li r7, 0x01
+ b toggleError /* fail - loop forever */
+
+configSDRAM:
+ addi r3, r13, (MsdRam-MessageBlock)
+ bl Printf
+/*
+ * set the Memory Configuration Reg. 1
+ */
+ li r3, 0x001f /* get bank size from spd bank0/1 */
+ bl spdRead
+
+ andi. r3, r3, 0x0038
+ beq SD16MB2B
+
+ li r3, 0x0011 /* get number of internal banks */
+ /* from spd for bank0/1 */
+ bl spdRead
+
+ cmpli 0, 0, r3, 0x02
+ beq SD64MB2B
+
+ cmpli 0, 0, r3, 0x04
+ beq SD64MB4B
+
+ li r6, 0xe0 /* error codes in r6 and r7 */
+ li r7, 0x02
+ b toggleError /* fail - loop forever */
+
+SD64MB2B:
+ li r20, 0x0005 /* 64-Mbit SDRAM 2 banks */
+ b SDRow2nd
+
+SD64MB4B:
+ li r20, 0x0000 /* 64-Mbit SDRAM 4 banks */
+ b SDRow2nd
+
+SD16MB2B:
+ li r20, 0x000f /* 16-Mbit SDRAM 2 banks */
+
+SDRow2nd:
+ li r3, 0x0102 /* get RAM type spd for bank2/3 */
+ bl spdRead
+
+ cmpli 0, 0, r3, 0x0004
+ bne S2D64MB4B /* bank2/3 isn't present or no SDRAM */
+
+ li r3, 0x011f /* get bank size from spd bank2/3 */
+ bl spdRead
+
+ andi. r3, r3, 0x0038
+ beq S2D16MB2B
+/*
+ * set the Memory Configuration Reg. 2
+ */
+ li r3, 0x0111 /* get number of internal banks */
+ /* from spd for bank2/3 */
+ bl spdRead
+
+ cmpli 0, 0, r3, 0x02
+ beq S2D64MB2B
+
+ cmpli 0, 0, r3, 0x04
+ beq S2D64MB4B
+
+ li r6, 0xe0 /* error codes in r6 and r7 */
+ li r7, 0x03
+ b toggleError /* fail - loop forever */
+
+S2D64MB2B:
+ ori r20, r20, 0x0050 /* 64-Mbit SDRAM 2 banks */
+ b S2D64MB4B
+
+S2D16MB2B:
+ ori r20, r20, 0x00f0 /* 16-Mbit SDRAM 2 banks */
+
+/*
+ * set the Memory Configuration Reg. 3
+ */
+S2D64MB4B:
+ lis r21, 0x8630 /* BSTOPRE = 0x80, REFREC = 6, */
+ /* RDLAT = 3 */
+
+/*
+ * set the Memory Configuration Reg. 4
+ */
+ lis r22, 0x2430 /* PRETOACT = 2, ACTOPRE = 4, */
+ /* WCBUF = 1, RCBUF = 1 */
+ ori r22, r22, 0x2220 /* SDMODE = 0x022, ACTORW = 2 */
+
+/*
+ * get the size of bank 0-3
+ */
+ li r3, 0x001f /* get bank size from spd bank0/1 */
+ bl spdRead
+
+ rlwinm r16, r3, 2, 24, 29 /* calculate size in MByte */
+ /* (128 MB max.) */
+
+ li r3, 0x0005 /* get number of banks from spd */
+ /* for bank0/1 */
+ bl spdRead
+
+ cmpi 0, 0, r3, 2 /* 2 banks ? */
+ bne SDRAMnobank1
+
+ mr r17, r16
+
+SDRAMnobank1:
+ addi r3, r13, (Mspd23-MessageBlock)
+ bl Printf
+
+ li r3, 0x0102 /* get RAM type spd for bank2/3 */
+ bl spdRead
+
+ cmpli 0, 0, r3, 0x0001 /* FPM ? */
+ bne noFPM23 /* handle as EDO */
+ addi r3, r13, (Mok-MessageBlock)
+ bl Printf
+ addi r3, r13, (MfpmRam-MessageBlock)
+ bl Printf
+ b configRAMcommon
+noFPM23:
+ cmpli 0, 0, r3, 0x0002 /* EDO ? */
+ bne noEDO23
+ addi r3, r13, (Mok-MessageBlock)
+ bl Printf
+ addi r3, r13, (MedoRam-MessageBlock)
+ bl Printf
+ b configRAMcommon
+noEDO23:
+ cmpli 0, 0, r3, 0x0004 /* SDRAM ? */
+ bne noSDRAM23
+ addi r3, r13, (Mok-MessageBlock)
+ bl Printf
+ addi r3, r13, (MsdRam-MessageBlock)
+ bl Printf
+ b configSDRAM23
+noSDRAM23:
+ addi r3, r13, (Mna-MessageBlock)
+ bl Printf
+ b configRAMcommon /* bank2/3 isn't present or no SDRAM */
+
+configSDRAM23:
+ li r3, 0x011f /* get bank size from spd bank2/3 */
+ bl spdRead
+
+ rlwinm r18, r3, 2, 24, 29 /* calculate size in MByte */
+ /* (128 MB max.) */
+
+ li r3, 0x0105 /* get number of banks from */
+ /* spd bank0/1 */
+ bl spdRead
+
+ cmpi 0, 0, r3, 2 /* 2 banks ? */
+ bne SDRAMnobank3
+
+ mr r19, r18
+
+SDRAMnobank3:
+ b configRAMcommon
+
+configFPM:
+ addi r3, r13, (MfpmRam-MessageBlock)
+ bl Printf
+ b configEDO0
+/*
+ * set the Memory Configuration Reg. 1
+ */
+configEDO:
+ addi r3, r13, (MedoRam-MessageBlock)
+ bl Printf
+configEDO0:
+ lis r20, MCCR1_TYPE_EDO@h
+
+getSpdRowBank01:
+ li r3, 0x0003 /* get number of row bits from */
+ /* spd from bank0/1 */
+ bl spdRead
+ ori r20, r20, (MCCR1_BK0_9BITS | MCCR1_BK1_9BITS)
+ cmpli 0, 0, r3, 0x0009 /* bank0 - 9 row bits */
+ beq getSpdRowBank23
+
+ ori r20, r20, (MCCR1_BK0_10BITS | MCCR1_BK1_10BITS)
+ cmpli 0, 0, r3, 0x000a /* bank0 - 10 row bits */
+ beq getSpdRowBank23
+
+ ori r20, r20, (MCCR1_BK0_11BITS | MCCR1_BK1_11BITS)
+ cmpli 0, 0, r3, 0x000b /* bank0 - 11 row bits */
+ beq getSpdRowBank23
+
+ ori r20, r20, (MCCR1_BK0_12BITS | MCCR1_BK1_12BITS)
+ cmpli 0, 0, r3, 0x000c /* bank0 - 12 row bits */
+ beq getSpdRowBank23
+
+ cmpli 0, 0, r3, 0x000d /* bank0 - 13 row bits */
+ beq getSpdRowBank23
+
+ li r6, 0xe0 /* error codes in r6 and r7 */
+ li r7, 0x10
+ b toggleError /* fail - loop forever */
+
+getSpdRowBank23:
+ li r3, 0x0103 /* get number of row bits from */
+ /* spd for bank2/3 */
+ bl spdRead
+
+ ori r20, r20, (MCCR1_BK2_9BITS | MCCR1_BK3_9BITS)
+ cmpli 0, 0, r3, 0x0009 /* bank0 - 9 row bits */
+ beq writeRowBits
+
+ ori r20, r20, (MCCR1_BK2_10BITS | MCCR1_BK3_10BITS)
+ cmpli 0, 0, r3, 0x000a /* bank0 - 10 row bits */
+ beq writeRowBits
+
+ ori r20, r20, (MCCR1_BK2_11BITS | MCCR1_BK3_11BITS)
+ cmpli 0, 0, r3, 0x000b /* bank0 - 11 row bits */
+ beq writeRowBits
+
+ ori r20, r20, (MCCR1_BK2_12BITS | MCCR1_BK3_12BITS)
+
+/*
+ * set the Memory Configuration Reg. 3
+ */
+writeRowBits:
+ lis r21, 0x000a /* CPX = 1, RAS6P = 4 */
+ ori r21, r21, 0x2293 /* CAS5 = 2, CP4 = 1, */
+ /* CAS3 = 2, RCD2 = 2, RP = 3 */
+/*
+ * set the Memory Configuration Reg. 4
+ */
+ lis r22, 0x0010 /* all SDRAM parameter 0, */
+ /* WCBUF flow through, */
+ /* RCBUF registered */
+/*
+ * get the size of bank 0-3
+ */
+ li r3, 0x0003 /* get row bits from spd bank0/1 */
+ bl spdRead
+
+ li r16, 0 /* bank size is: */
+ /* (8*2^row*2^column)/0x100000 MB */
+ ori r16, r16, 0x8000
+ rlwnm r16, r16, r3, 0, 31
+
+ li r3, 0x0004 /* get column bits from spd bank0/1 */
+ bl spdRead
+
+ rlwnm r16, r16, r3, 0, 31
+
+ li r3, 0x0005 /* get number of banks from */
+ /* spd for bank0/1 */
+ bl spdRead
+
+ cmpi 0, 0, r3, 2 /* 2 banks ? */
+ bne EDOnobank1
+
+ mr r17, r16
+
+EDOnobank1:
+ addi r3, r13, (Mspd23-MessageBlock)
+ bl Printf
+
+ li r3, 0x0102 /* get RAM type spd for bank2/3 */
+ bl spdRead
+
+ cmpli 0, 0, r3, 0x0001 /* FPM ? */
+ bne noFPM231 /* handle as EDO */
+ addi r3, r13, (Mok-MessageBlock)
+ bl Printf
+ addi r3, r13, (MfpmRam-MessageBlock)
+ bl Printf
+ b EDObank2
+noFPM231:
+ cmpli 0, 0, r3, 0x0002 /* EDO ? */
+ bne noEDO231
+ addi r3, r13, (Mok-MessageBlock)
+ bl Printf
+ addi r3, r13, (MedoRam-MessageBlock)
+ bl Printf
+ b EDObank2
+noEDO231:
+ cmpli 0, 0, r3, 0x0004 /* SDRAM ? */
+ bne noSDRAM231
+ addi r3, r13, (Mok-MessageBlock)
+ bl Printf
+ addi r3, r13, (MsdRam-MessageBlock)
+ bl Printf
+ b configRAMcommon
+noSDRAM231:
+ addi r3, r13, (Mfail-MessageBlock)
+ bl Printf
+ b configRAMcommon /* bank2/3 isn't present or no SDRAM */
+
+EDObank2:
+ li r3, 0x0103 /* get row bits from spd for bank2/3 */
+ bl spdRead
+
+ li r18, 0 /* bank size is: */
+ /* (8*2^row*2^column)/0x100000 MB */
+ ori r18, r18, 0x8000
+ rlwnm r18, r18, r3, 0, 31
+
+ li r3, 0x0104 /* get column bits from spd bank2/3 */
+ bl spdRead
+
+ rlwnm r18, r18, r3, 0, 31
+
+ li r3, 0x0105 /* get number of banks from */
+ /* spd for bank2/3 */
+ bl spdRead
+
+ cmpi 0, 0, r3, 2 /* 2 banks ? */
+ bne configRAMcommon
+
+ mr r19, r18
+
+configRAMcommon:
+ lis r1, MPC106_REG_ADDR@h
+ ori r1, r1, MPC106_REG_ADDR@l
+ lis r2, MPC106_REG_DATA@h
+ ori r2, r2, MPC106_REG_DATA@l
+
+ li r0, 0
+
+/*
+ * If we are already running in RAM (debug mode), we should
+ * NOT reset the MEMGO flag. Otherwise we will stop all memory
+ * accesses.
+ */
+#ifdef IN_RAM
+ lis r4, MCCR1_MEMGO@h
+ ori r4, r4, MCCR1_MEMGO@l
+ or r20, r20, r4
+#endif
+
+/*
+ * set the Memory Configuration Reg. 1
+ */
+ lis r3, MPC106_REG@h /* start building new reg number */
+ ori r3, r3, MPC106_MCCR1 /* register number 0xf0 */
+ stwbrx r3, r0, r1 /* write this value to CONFIG_ADDR */
+ eieio /* make sure mem. access is complete */
+ stwbrx r20, r0, r2 /* write data to CONFIG_DATA */
+/*
+ * set the Memory Configuration Reg. 3
+ */
+ lis r3, MPC106_REG@h /* start building new reg number */
+ ori r3, r3, MPC106_MCCR3 /* register number 0xf8 */
+ stwbrx r3, r0, r1 /* write this value to CONFIG_ADDR */
+ eieio /* make sure mem. access is complete */
+ stwbrx r21, r0, r2 /* write data to CONFIG_DATA */
+/*
+ * set the Memory Configuration Reg. 4
+ */
+ lis r3, MPC106_REG@h /* start building new reg number */
+ ori r3, r3, MPC106_MCCR4 /* register number 0xfc */
+ stwbrx r3, r0, r1 /* write this value to CONFIG_ADDR */
+ eieio /* make sure mem. access is complete */
+ stwbrx r22, r0, r2 /* write data to CONFIG_DATA */
+/*
+ * set the memory boundary registers for bank 0-3
+ */
+ li r20, 0
+ li r23, 0
+ li r24, 0
+ subi r21, r16, 1 /* calculate end address bank0 */
+ li r22, (MBER_BANK0)
+
+ cmpi 0, 0, r17, 0 /* bank1 present ? */
+ beq nobank1
+
+ rlwinm r3, r16, 8, 16, 23 /* calculate start address of bank1 */
+ or r20, r20, r3
+ add r16, r16, r17 /* add to total memory size */
+ subi r3, r16, 1 /* calculate end address of bank1 */
+ rlwinm r3, r3, 8, 16, 23
+ or r21, r21, r3
+ ori r22, r22, (MBER_BANK1) /* enable bank1 */
+ b bank2
+
+nobank1:
+ ori r23, r23, 0x0300 /* set bank1 start to unused area */
+ ori r24, r24, 0x0300 /* set bank1 end to unused area */
+
+bank2:
+ cmpi 0, 0, r18, 0 /* bank2 present ? */
+ beq nobank2
+
+ andi. r3, r16, 0x00ff /* calculate start address of bank2 */
+ andi. r4, r16, 0x0300
+ rlwinm r3, r3, 16, 8, 15
+ or r20, r20, r3
+ rlwinm r3, r4, 8, 8, 15
+ or r23, r23, r3
+ add r16, r16, r18 /* add to total memory size */
+ subi r3, r16, 1 /* calculate end address of bank2 */
+ andi. r4, r3, 0x0300
+ andi. r3, r3, 0x00ff
+ rlwinm r3, r3, 16, 8, 15
+ or r21, r21, r3
+ rlwinm r3, r4, 8, 8, 15
+ or r24, r24, r3
+ ori r22, r22, (MBER_BANK2) /* enable bank2 */
+ b bank3
+
+nobank2:
+ lis r3, 0x0003
+ or r23, r23, r3 /* set bank2 start to unused area */
+ or r24, r24, r3 /* set bank2 end to unused area */
+
+bank3:
+ cmpi 0, 0, r19, 0 /* bank3 present ? */
+ beq nobank3
+
+ andi. r3, r16, 0x00ff /* calculate start address of bank3 */
+ andi. r4, r16, 0x0300
+ rlwinm r3, r3, 24, 0, 7
+ or r20, r20, r3
+ rlwinm r3, r4, 16, 0, 7
+ or r23, r23, r3
+ add r16, r16, r19 /* add to total memory size */
+ subi r3, r16, 1 /* calculate end address of bank3 */
+ andi. r4, r3, 0x0300
+ andi. r3, r3, 0x00ff
+ rlwinm r3, r3, 24, 0, 7
+ or r21, r21, r3
+ rlwinm r3, r4, 16, 0, 7
+ or r24, r24, r3
+ ori r22, r22, (MBER_BANK3) /* enable bank3 */
+ b writebound
+
+nobank3:
+ lis r3, 0x0300
+ or r23, r23, r3 /* set bank3 start to unused area */
+ or r24, r24, r3 /* set bank3 end to unused area */
+
+writebound:
+ lis r3, MPC106_REG@h /* start building new reg number */
+ ori r3, r3, MPC106_MSAR1 /* register number 0x80 */
+ stwbrx r3, r0, r1 /* write this value to CONFIG_ADDR */
+ eieio /* make sure mem. access is complete */
+ stwbrx r20, r0, r2 /* write data to CONFIG_DATA */
+
+ lis r3, MPC106_REG@h /* start building new reg number */
+ ori r3, r3, MPC106_MEAR1 /* register number 0x90 */
+ stwbrx r3, r0, r1 /* write this value to CONFIG_ADDR */
+ eieio /* make sure mem. access is complete */
+ stwbrx r21, r0, r2 /* write data to CONFIG_DATA */
+
+ lis r3, MPC106_REG@h /* start building new reg number */
+ ori r3, r3, MPC106_EMSAR1 /* register number 0x88 */
+ stwbrx r3, r0, r1 /* write this value to CONFIG_ADDR */
+ eieio /* make sure mem. access is complete */
+ stwbrx r23, r0, r2 /* write data to CONFIG_DATA */
+
+ lis r3, MPC106_REG@h /* start building new reg number */
+ ori r3, r3, MPC106_EMEAR1 /* register number 0x98 */
+ stwbrx r3, r0, r1 /* write this value to CONFIG_ADDR */
+ eieio /* make sure mem. access is complete */
+ stwbrx r24, r0, r2 /* write data to CONFIG_DATA */
+
+/*
+ * set boundaries of unused banks to unused address space
+ */
+ lis r4, 0x0303
+ ori r4, r4, 0x0303 /* bank 4-7 start and end adresses */
+ lis r3, MPC106_REG@h /* start building new reg number */
+ ori r3, r3, MPC106_EMSAR2 /* register number 0x8C */
+ stwbrx r3, r0, r1 /* write this value to CONFIG_ADDR */
+ eieio /* make sure mem. access is complete */
+ stwbrx r4, r0, r2 /* write data to CONFIG_DATA */
+
+ lis r3, MPC106_REG@h /* start building new reg number */
+ ori r3, r3, MPC106_EMEAR2 /* register number 0x9C */
+ stwbrx r3, r0, r1 /* write this value to CONFIG_ADDR */
+ eieio /* make sure mem. access is complete */
+ stwbrx r4, r0, r2 /* write data to CONFIG_DATA */
+
+/*
+ * set the Memory Configuration Reg. 2
+ */
+ lis r3, MPC106_REG@h /* start building new reg number */
+ ori r3, r3, MPC106_MCCR2 /* register number 0xf4 */
+ stwbrx r3, r0, r1 /* write this value to CONFIG_ADDR */
+ eieio /* make sure mem. access is complete */
+
+ li r3, 0x000c /* get refresh from spd for bank0/1 */
+ bl spdRead
+
+ cmpi 0, 0, r3, -1 /* error ? */
+ bne common1
+
+ li r6, 0xe0 /* error codes in r6 and r7 */
+ li r7, 0x20
+ b toggleError /* fail - loop forever */
+
+common1:
+ andi. r15, r3, 0x007f /* mask selfrefresh bit */
+ li r3, 0x010c /* get refresh from spd for bank2/3 */
+ bl spdRead
+
+ cmpi 0, 0, r3, -1 /* error ? */
+ beq common2
+ andi. r3, r3, 0x007f /* mask selfrefresh bit */
+ cmp 0, 0, r3, r15 /* find the lower */
+ blt common3
+
+common2:
+ mr r3, r15
+
+common3:
+ li r4, 0x1010 /* refesh cycle 1028 clocks */
+ /* left shifted 2 */
+ cmpli 0, 0, r3, 0x0000 /* 15.6 us ? */
+ beq writeRefresh
+
+ li r4, 0x0808 /* refesh cycle 514 clocks */
+ /* left shifted 2 */
+ cmpli 0, 0, r3, 0x0002 /* 7.8 us ? */
+ beq writeRefresh
+
+ li r4, 0x2020 /* refesh cycle 2056 clocks */
+ /* left shifted 2 */
+ cmpli 0, 0, r3, 0x0003 /* 31.3 us ? */
+ beq writeRefresh
+
+ li r4, 0x4040 /* refesh cycle 4112 clocks */
+ /* left shifted 2 */
+ cmpli 0, 0, r3, 0x0004 /* 62.5 us ? */
+ beq writeRefresh
+
+ li r4, 0
+ ori r4, r4, 0x8080 /* refesh cycle 8224 clocks */
+ /* left shifted 2 */
+ cmpli 0, 0, r3, 0x0005 /* 125 us ? */
+ beq writeRefresh
+
+ li r6, 0xe0 /* error codes in r6 and r7 */
+ li r7, 0x21
+ b toggleError /* fail - loop forever */
+
+writeRefresh:
+ stwbrx r4, r0, r2 /* write data to CONFIG_DATA */
+
+/*
+ * DRAM BANKS SHOULD BE ENABLED
+ */
+ addi r3, r13, (Mactivate-MessageBlock)
+ bl Printf
+ mr r3, r16
+ bl OutDec
+ addi r3, r13, (Mmbyte-MessageBlock)
+ bl Printf
+
+ lis r3, MPC106_REG@h /* start building new reg number */
+ ori r3, r3, MPC106_MBER /* register number 0xa0 */
+ stwbrx r3, r0, r1 /* write this value to CONFIG_ADDR */
+ eieio /* make sure mem. access is complete */
+ stb r22, 0(r2) /* write data to CONFIG_DATA */
+ li r8, 0x63 /* PGMAX = 99 */
+ stb r8, 3(r2) /* write data to CONFIG_DATA */
+
+/*
+ * DRAM SHOULD NOW BE CONFIGURED AND ENABLED
+ * MUST WAIT 200us BEFORE ACCESSING
+ */
+ li r0, 0x7800
+ mtctr r0
+
+wait200us:
+ bdnz wait200us
+
+ lis r3, MPC106_REG@h /* start building new reg number */
+ ori r3, r3, MPC106_MCCR1 /* register number 0xf0 */
+ stwbrx r3, r0, r1 /* write this value to CONFIG_ADDR */
+ eieio /* make sure mem. access is complete */
+
+ lwbrx r4, r0, r2 /* load r4 from CONFIG_DATA */
+
+ lis r0, MCCR1_MEMGO@h /* MEMGO=1 */
+ ori r0, r0, MCCR1_MEMGO@l
+ or r4, r4, r0 /* set the MEMGO bit */
+ stwbrx r4, r0, r2 /* write mdfd data to CONFIG_DATA */
+
+ li r0, 0x7000
+ mtctr r0
+
+wait8ref:
+ bdnz wait8ref
+
+ addi r3, r13, (Mok-MessageBlock)
+ bl Printf
+
+ mtlr r25
+ blr
+
+/*
+ * Infinite loop called in case of an error during RAM initialisation.
+ * error codes in r6 and r7.
+ */
+toggleError:
+ li r0, 0
+ lis r9, 127
+ ori r9, r9, 65535
+toggleError1:
+ addic r0, r0, 1
+ cmpw cr1, r0, r9
+ ble cr1, toggleError1
+ li r0, 0
+ lis r9, 127
+ ori r9, r9, 65535
+toggleError2:
+ addic r0, r0, 1
+ cmpw cr1, r0, r9
+ ble cr1, toggleError2
+ b toggleError
+
+
+/******************************************************************************
+ * This function performs a basic initialisation of the superio chip
+ * to enable basic console output and SPD access during RAM initialisation.
+ *
+ * Upon completion, SIO resource registers are mapped as follows:
+ * Resource Enabled Address
+ * UART1 Yes 3F8-3FF COM1
+ * UART2 Yes 2F8-2FF COM2
+ * GPIO Yes 220-227
+ */
+.set SIO_LUNINDEX, 0x07 /* SIO LUN index register */
+.set SIO_CNFG1, 0x21 /* SIO configuration #1 register */
+.set SIO_PCSCI, 0x23 /* SIO PCS configuration index reg */
+.set SIO_PCSCD, 0x24 /* SIO PCS configuration data reg */
+.set SIO_ACTIVATE, 0x30 /* SIO activate register */
+.set SIO_IOBASEHI, 0x60 /* SIO I/O port base address, 15:8 */
+.set SIO_IOBASELO, 0x61 /* SIO I/O port base address, 7:0 */
+.set SIO_LUNENABLE, 0x01 /* SIO LUN enable */
+
+.sioInit:
+ mfspr r7, 8 /* save link register */
+
+.sioInit_87308:
+
+/*
+ * Get base addr of ISA I/O space
+ */
+ lis r6, CFG_ISA_IO@h
+ ori r6, r6, CFG_ISA_IO@l
+
+/*
+ * Set offset to base address for config registers.
+ */
+#if defined(CFG_NS87308_BADDR_0x)
+ addi r4, r0, 0x0279
+#elif defined(CFG_NS87308_BADDR_10)
+ addi r4, r0, 0x015C
+#elif defined(CFG_NS87308_BADDR_11)
+ addi r4, r0, 0x002E
+#endif
+ add r6, r6, r4 /* add offset to base */
+ or r3, r6, r6 /* make a copy */
+
+/*
+ * PMC (LUN 8)
+ */
+ addi r4, r0, SIO_LUNINDEX /* select PMC LUN */
+ addi r5, r0, 0x8
+ bl .sio_bw
+ addi r4, r0, SIO_IOBASEHI /* initialize PMC address to 0x460 */
+ addi r5, r0, 0x04
+ bl .sio_bw
+ addi r4, r0, SIO_IOBASELO
+ addi r5, r0, 0x60
+ bl .sio_bw
+ addi r4, r0, SIO_ACTIVATE /* enable PMC */
+ addi r5, r0, SIO_LUNENABLE
+ bl .sio_bw
+
+ lis r8, CFG_ISA_IO@h
+ ori r8, r8, 0x0460
+ li r9, 0x03
+ stb r9, 0(r8) /* select PMC2 register */
+ eieio
+ li r9, 0x00
+ stb r9, 1(r8) /* SuperI/O clock src: 24MHz via X1 */
+ eieio
+
+/*
+ * map UART1 (LUN 6) or UART2 (LUN 5) to COM1 (0x3F8)
+ */
+ addi r4, r0, SIO_LUNINDEX /* select COM1 LUN */
+ addi r5, r0, 0x6
+ bl .sio_bw
+
+ addi r4, r0, SIO_IOBASEHI /* initialize COM1 address to 0x3F8 */
+ addi r5, r0, 0x03
+ bl .sio_bw
+
+ addi r4, r0, SIO_IOBASELO
+ addi r5, r0, 0xF8
+ bl .sio_bw
+
+ addi r4, r0, SIO_ACTIVATE /* enable COM1 */
+ addi r5, r0, SIO_LUNENABLE
+ bl .sio_bw
+
+/*
+ * Init COM1 for polled output
+ */
+ lis r8, CFG_ISA_IO@h
+ ori r8, r8, 0x03f8
+ li r9, 0x00
+ stb r9, 1(r8) /* int disabled */
+ eieio
+ li r9, 0x00
+ stb r9, 4(r8) /* modem ctrl */
+ eieio
+ li r9, 0x80
+ stb r9, 3(r8) /* link ctrl, bank select */
+ eieio
+ li r9, 115200/CONFIG_BAUDRATE
+ stb r9, 0(r8) /* baud rate (LSB)*/
+ eieio
+ rotrwi r9, r9, 8
+ stb r9, 1(r8) /* baud rate (MSB) */
+ eieio
+ li r9, 0x03
+ stb r9, 3(r8) /* 8 data bits, 1 stop bit, */
+ /* no parity */
+ eieio
+ li r9, 0x0b
+ stb r9, 4(r8) /* enable the receiver and transmitter */
+ eieio
+
+waitEmpty:
+ lbz r9, 5(r8) /* transmit empty */
+ andi. r9, r9, 0x40
+ beq waitEmpty
+ li r9, 0x47
+ stb r9, 3(r8) /* send break, 8 data bits, */
+ /* 2 stop bits, no parity */
+ eieio
+
+ lis r0, 0x0001
+ mtctr r0
+
+waitCOM1:
+ lwz r0, 5(r8) /* load from port for delay */
+ bdnz waitCOM1
+
+waitEmpty1:
+ lbz r9, 5(r8) /* transmit empty */
+ andi. r9, r9, 0x40
+ beq waitEmpty1
+ li r9, 0x07
+ stb r9, 3(r8) /* 8 data bits, 2 stop bits, */
+ /* no parity */
+ eieio
+
+/*
+ * GPIO (LUN 7)
+ */
+ addi r4, r0, SIO_LUNINDEX /* select GPIO LUN */
+ addi r5, r0, 0x7
+ bl .sio_bw
+
+ addi r4, r0, SIO_IOBASEHI /* initialize GPIO address to 0x220 */
+ addi r5, r0, 0x02
+ bl .sio_bw
+
+ addi r4, r0, SIO_IOBASELO
+ addi r5, r0, 0x20
+ bl .sio_bw
+
+ addi r4, r0, SIO_ACTIVATE /* enable GPIO */
+ addi r5, r0, SIO_LUNENABLE
+ bl .sio_bw
+
+.sioInit_done:
+
+/*
+ * Get base addr of ISA I/O space
+ */
+ lis r3, CFG_ISA_IO@h
+ ori r3, r3, CFG_ISA_IO@l
+
+ addi r3, r3, 0x015C /* adjust to superI/O 87308 base */
+ or r6, r3, r3 /* make a copy */
+/*
+ * CS0
+ */
+ addi r4, r0, SIO_PCSCI /* select PCSCIR */
+ addi r5, r0, 0x00
+ bl .sio_bw
+ addi r4, r0, SIO_PCSCD /* select PCSCDR */
+ addi r5, r0, 0x00
+ bl .sio_bw
+ addi r4, r0, SIO_PCSCI /* select PCSCIR */
+ addi r5, r0, 0x01
+ bl .sio_bw
+ addi r4, r0, SIO_PCSCD /* select PCSCDR */
+ addi r5, r0, 0x76
+ bl .sio_bw
+ addi r4, r0, SIO_PCSCI /* select PCSCIR */
+ addi r5, r0, 0x02
+ bl .sio_bw
+ addi r4, r0, SIO_PCSCD /* select PCSCDR */
+ addi r5, r0, 0x40
+ bl .sio_bw
+/*
+ * CS1
+ */
+ addi r4, r0, SIO_PCSCI /* select PCSCIR */
+ addi r5, r0, 0x05
+ bl .sio_bw
+ addi r4, r0, SIO_PCSCD /* select PCSCDR */
+ addi r5, r0, 0x00
+ bl .sio_bw
+ addi r4, r0, SIO_PCSCI /* select PCSCIR */
+ addi r5, r0, 0x05
+ bl .sio_bw
+ addi r4, r0, SIO_PCSCD /* select PCSCDR */
+ addi r5, r0, 0x70
+ bl .sio_bw
+ addi r4, r0, SIO_PCSCI /* select PCSCIR */
+ addi r5, r0, 0x06
+ bl .sio_bw
+ addi r4, r0, SIO_PCSCD /* select PCSCDR */
+ addi r5, r0, 0x1C
+ bl .sio_bw
+/*
+ * CS2
+ */
+ addi r4, r0, SIO_PCSCI /* select PCSCIR */
+ addi r5, r0, 0x08
+ bl .sio_bw
+ addi r4, r0, SIO_PCSCD /* select PCSCDR */
+ addi r5, r0, 0x00
+ bl .sio_bw
+ addi r4, r0, SIO_PCSCI /* select PCSCIR */
+ addi r5, r0, 0x09
+ bl .sio_bw
+ addi r4, r0, SIO_PCSCD /* select PCSCDR */
+ addi r5, r0, 0x71
+ bl .sio_bw
+ addi r4, r0, SIO_PCSCI /* select PCSCIR */
+ addi r5, r0, 0x0A
+ bl .sio_bw
+ addi r4, r0, SIO_PCSCD /* select PCSCDR */
+ addi r5, r0, 0x1C
+ bl .sio_bw
+
+ mtspr 8, r7 /* restore link register */
+ bclr 20, 0 /* return to caller */
+
+/*
+ * this function writes a register to the SIO chip
+ */
+.sio_bw:
+ stb r4, 0(r3) /* write index register with register offset */
+ eieio
+ sync
+ stb r5, 1(r3) /* 1st write */
+ eieio
+ sync
+ stb r5, 1(r3) /* 2nd write */
+ eieio
+ sync
+ bclr 20, 0 /* return to caller */
+/*
+ * this function reads a register from the SIO chip
+ */
+.sio_br:
+ stb r4, 0(r3) /* write index register with register offset */
+ eieio
+ sync
+ lbz r3, 1(r3) /* retrieve specified reg offset contents */
+ eieio
+ sync
+ bclr 20, 0 /* return to caller */
+
+/*
+ * Print a message to COM1 in polling mode
+ * r10=COM1 port, r3=(char*)string
+ */
+.globl Printf
+Printf:
+ lis r10, CFG_ISA_IO@h /* COM1 port */
+ ori r10, r10, 0x03f8
+
+WaitChr:
+ lbz r0, 5(r10) /* read link status */
+ eieio
+ andi. r0, r0, 0x40 /* mask transmitter empty bit */
+ beq cr0, WaitChr /* wait till empty */
+ lbzx r0, r0, r3 /* get char */
+ stb r0, 0(r10) /* write to transmit reg */
+ eieio
+ addi r3, r3, 1 /* next char */
+ lbzx r0, r0, r3 /* get char */
+ cmpwi cr1, r0, 0 /* end of string ? */
+ bne cr1, WaitChr
+ blr
+
+/*
+ * Print 8/4/2 digits hex value to COM1 in polling mode
+ * r10=COM1 port, r3=val
+ */
+OutHex2:
+ li r9, 4 /* shift reg for 2 digits */
+ b OHstart
+OutHex4:
+ li r9, 12 /* shift reg for 4 digits */
+ b OHstart
+ .globl OutHex
+OutHex:
+ li r9, 28 /* shift reg for 8 digits */
+OHstart:
+ lis r10, CFG_ISA_IO@h /* COM1 port */
+ ori r10, r10, 0x03f8
+OutDig:
+ lbz r0, 5(r10) /* read link status */
+ eieio
+ andi. r0, r0, 0x40 /* mask transmitter empty bit */
+ beq cr0, OutDig
+ sraw r0, r3, r9
+ clrlwi r0, r0, 28
+ cmpwi cr1, r0, 9
+ ble cr1, digIsNum
+ addic r0, r0, 55
+ b nextDig
+digIsNum:
+ addic r0, r0, 48
+nextDig:
+ stb r0, 0(r10) /* write to transmit reg */
+ eieio
+ addic. r9, r9, -4
+ bge OutDig
+ blr
+/*
+ * Print 3 digits hdec value to COM1 in polling mode
+ * r10=COM1 port, r3=val, r7=x00, r8=x0, r9=x, r0, r6=scratch
+ */
+.globl OutDec
+OutDec:
+ li r6, 10
+ divwu r0, r3, r6 /* r0 = r3 / 10, r9 = r3 mod 10 */
+ mullw r10, r0, r6
+ subf r9, r10, r3
+
+ mr r3, r0
+ divwu r0, r3, r6 /* r0 = r3 / 10, r8 = r3 mod 10 */
+ mullw r10, r0, r6
+ subf r8, r10, r3
+
+ mr r3, r0
+ divwu r0, r3, r6 /* r0 = r3 / 10, r7 = r3 mod 10 */
+ mullw r10, r0, r6
+ subf r7, r10, r3
+
+ lis r10, CFG_ISA_IO@h /* COM1 port */
+ ori r10, r10, 0x03f8
+
+ or. r7, r7, r7
+ bne noblank1
+ li r3, 0x20
+ b OutDec4
+
+noblank1:
+ addi r3, r7, 48 /* convert to ASCII */
+
+OutDec4:
+ lbz r0, 0(r13) /* slow down dummy read */
+ lbz r0, 5(r10) /* read link status */
+ eieio
+ andi. r0, r0, 0x40 /* mask transmitter empty bit */
+ beq cr0, OutDec4
+ stb r3, 0(r10) /* x00 to transmit */
+ eieio
+
+ or. r7, r7, r8
+ beq OutDec5
+
+ addi r3, r8, 48 /* convert to ASCII */
+OutDec5:
+ lbz r0, 0(r13) /* slow down dummy read */
+ lbz r0, 5(r10) /* read link status */
+ eieio
+ andi. r0, r0, 0x40 /* mask transmitter empty bit */
+ beq cr0, OutDec5
+ stb r3, 0(r10) /* x0 to transmit */
+ eieio
+
+ addi r3, r9, 48 /* convert to ASCII */
+OutDec6:
+ lbz r0, 0(r13) /* slow down dummy read */
+ lbz r0, 5(r10) /* read link status */
+ eieio
+ andi. r0, r0, 0x40 /* mask transmitter empty bit */
+ beq cr0, OutDec6
+ stb r3, 0(r10) /* x to transmit */
+ eieio
+ blr
+/*
+ * Print a char to COM1 in polling mode
+ * r10=COM1 port, r3=char
+ */
+.globl OutChr
+OutChr:
+ lis r10, CFG_ISA_IO@h /* COM1 port */
+ ori r10, r10, 0x03f8
+
+OutChr1:
+ lbz r0, 5(r10) /* read link status */
+ eieio
+ andi. r0, r0, 0x40 /* mask transmitter empty bit */
+ beq cr0, OutChr1 /* wait till empty */
+ stb r3, 0(r10) /* write to transmit reg */
+ eieio
+ blr
+/*
+ * Input: r3 adr to read
+ * Output: r3 val or -1 for error
+ */
+spdRead:
+ mfspr r26, 8 /* save link register */
+
+ lis r30, CFG_ISA_IO@h
+ ori r30, r30, 0x220 /* GPIO Port 1 */
+ li r7, 0x00
+ li r8, 0x100
+ and. r5, r3, r8
+ beq spdbank0
+ li r12, 0x08
+ li r4, 0x10
+ li r6, 0x18
+ b spdRead1
+
+spdbank0:
+ li r12, 0x20 /* set I2C data */
+ li r4, 0x40 /* set I2C clock */
+ li r6, 0x60 /* set I2C clock and data */
+
+spdRead1:
+ li r8, 0x80
+
+ bl spdStart /* access I2C bus as master */
+ li r10, 0xa0 /* write to SPD */
+ bl spdWriteByte
+ bl spdReadAck /* ACK returns in r10 */
+ cmpw cr0, r10, r7
+ bne AckErr /* r10 must be 0, if ACK received */
+ mr r10, r3 /* adr to read */
+ bl spdWriteByte
+ bl spdReadAck
+ cmpw cr0, r10, r7
+ bne AckErr
+ bl spdStart
+ li r10, 0xa1 /* read from SPD */
+ bl spdWriteByte
+ bl spdReadAck
+ cmpw cr0, r10, r7
+ bne AckErr
+ bl spdReadByte /* return val in r10 */
+ bl spdWriteAck
+ bl spdStop /* release I2C bus */
+ mr r3, r10
+ mtspr 8, r26 /* restore link register */
+ blr
+/*
+ * ACK error occurred
+ */
+AckErr:
+ bl spdStop
+ orc r3, r0, r0 /* return -1 */
+ mtspr 8, r26 /* restore link register */
+ blr
+
+/*
+ * Routines to read from RAM spd.
+ * r30 - GPIO Port1 address in all cases.
+ * r4 - clock mask for SPD
+ * r6 - port mask for SPD
+ * r12 - data mask for SPD
+ */
+waitSpd:
+ li r0, 0x1000
+ mtctr r0
+wSpd:
+ bdnz wSpd
+ bclr 20, 0 /* return to caller */
+
+/*
+ * establish START condition on I2C bus
+ */
+spdStart:
+ mfspr r27, 8 /* save link register */
+ stb r6, 0(r30) /* set SDA and SCL */
+ eieio
+ stb r6, 1(r30) /* switch GPIO to output */
+ eieio
+ bl waitSpd
+ stb r4, 0(r30) /* reset SDA */
+ eieio
+ bl waitSpd
+ stb r7, 0(r30) /* reset SCL */
+ eieio
+ bl waitSpd
+ mtspr 8, r27
+ bclr 20, 0 /* return to caller */
+
+/*
+ * establish STOP condition on I2C bus
+ */
+spdStop:
+ mfspr r27, 8 /* save link register */
+ stb r7, 0(r30) /* reset SCL and SDA */
+ eieio
+ stb r6, 1(r30) /* switch GPIO to output */
+ eieio
+ bl waitSpd
+ stb r4, 0(r30) /* set SCL */
+ eieio
+ bl waitSpd
+ stb r6, 0(r30) /* set SDA and SCL */
+ eieio
+ bl waitSpd
+ stb r7, 1(r30) /* switch GPIO to input */
+ eieio
+ mtspr 8, r27
+ bclr 20, 0 /* return to caller */
+
+spdReadByte:
+ mfspr r27, 8
+ stb r4, 1(r30) /* set GPIO for SCL output */
+ eieio
+ li r9, 0x08
+ li r10, 0x00
+loopRB:
+ stb r7, 0(r30) /* reset SDA and SCL */
+ eieio
+ bl waitSpd
+ stb r4, 0(r30) /* set SCL */
+ eieio
+ bl waitSpd
+ lbz r5, 0(r30) /* read from GPIO Port1 */
+ rlwinm r10, r10, 1, 0, 31
+ and. r5, r5, r12
+ beq clearBit
+ ori r10, r10, 0x01 /* append _1_ */
+clearBit:
+ stb r7, 0(r30) /* reset SCL */
+ eieio
+ bl waitSpd
+ addic. r9, r9, -1
+ bne loopRB
+ mtspr 8, r27
+ bclr 20, 0 /* return (r10) to caller */
+
+/*
+ * spdWriteByte writes bits 24 - 31 of r10 to I2C.
+ * r8 contains bit mask 0x80
+ */
+spdWriteByte:
+ mfspr r27, 8 /* save link register */
+ li r9, 0x08 /* write octet */
+ and. r5, r10, r8
+ bne sWB1
+ stb r7, 0(r30) /* set SDA to _0_ */
+ eieio
+ b sWB2
+sWB1:
+ stb r12, 0(r30) /* set SDA to _1_ */
+ eieio
+sWB2:
+ stb r6, 1(r30) /* set GPIO to output */
+ eieio
+loopWB:
+ and. r5, r10, r8
+ bne sWB3
+ stb r7, 0(r30) /* set SDA to _0_ */
+ eieio
+ b sWB4
+sWB3:
+ stb r12, 0(r30) /* set SDA to _1_ */
+ eieio
+sWB4:
+ bl waitSpd
+ and. r5, r10, r8
+ bne sWB5
+ stb r4, 0(r30) /* set SDA to _0_ and SCL */
+ eieio
+ b sWB6
+sWB5:
+ stb r6, 0(r30) /* set SDA to _1_ and SCL */
+ eieio
+sWB6:
+ bl waitSpd
+ and. r5, r10, r8
+ bne sWB7
+ stb r7, 0(r30) /* set SDA to _0_ and reset SCL */
+ eieio
+ b sWB8
+sWB7:
+ stb r12, 0(r30) /* set SDA to _1_ and reset SCL */
+ eieio
+sWB8:
+ bl waitSpd
+ rlwinm r10, r10, 1, 0, 31 /* next bit */
+ addic. r9, r9, -1
+ bne loopWB
+ mtspr 8, r27
+ bclr 20, 0 /* return to caller */
+
+/*
+ * Read ACK from SPD, return value in r10
+ */
+spdReadAck:
+ mfspr r27, 8 /* save link register */
+ stb r4, 1(r30) /* set GPIO to output */
+ eieio
+ stb r7, 0(r30) /* reset SDA and SCL */
+ eieio
+ bl waitSpd
+ stb r4, 0(r30) /* set SCL */
+ eieio
+ bl waitSpd
+ lbz r10, 0(r30) /* read GPIO Port 1 and mask SDA */
+ and r10, r10, r12
+ bl waitSpd
+ stb r7, 0(r30) /* reset SDA and SCL */
+ eieio
+ bl waitSpd
+ mtspr 8, r27
+ bclr 20, 0 /* return (r10) to caller */
+
+spdWriteAck:
+ mfspr r27, 8
+ stb r12, 0(r30) /* set SCL */
+ eieio
+ stb r6, 1(r30) /* set GPIO to output */
+ eieio
+ bl waitSpd
+ stb r6, 0(r30) /* SDA and SCL */
+ eieio
+ bl waitSpd
+ stb r12, 0(r30) /* reset SCL */
+ eieio
+ bl waitSpd
+ mtspr 8, r27
+ bclr 20, 0 /* return to caller */
+
+get_lnk_reg:
+ mflr r3 /* return link reg */
+ blr
+
+/*
+ * Messages for console output
+ */
+.globl MessageBlock
+MessageBlock:
+Mok:
+ .ascii "OK\015\012\000"
+Mfail:
+ .ascii "FAILED\015\012\000"
+Mna:
+ .ascii "NA\015\012\000"
+MinitLogo:
+ .ascii "\015\012*** ELTEC Elektronik, Mainz ***\015\012"
+ .ascii "\015\012Initialising RAM\015\012\000"
+Mspd01:
+ .ascii " Reading SPD of bank0/1 ..... \000"
+Mspd23:
+ .ascii " Reading SPD of bank2/3 ..... \000"
+MfpmRam:
+ .ascii " RAM-Type: FPM \015\012\000"
+MedoRam:
+ .ascii " RAM-Type: EDO \015\012\000"
+MsdRam:
+ .ascii " RAM-Type: SDRAM \015\012\000"
+Mactivate:
+ .ascii " Activating \000"
+Mmbyte:
+ .ascii " MB .......... \000"
+ .align 4
+
+
+
+
+
+
+
+
+
+
+
+
--- /dev/null
+/*
+ * (C) Copyright 2002 ELTEC Elektronik AG
+ * Frank Gottschling <fgottschling@eltec.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 "srom.h"
+
+/*----------------------------------------------------------------------------*/
+/*
+ * START sequence
+ * _ _________
+ * SCLK _> \____
+ * _ ____
+ * SDIO _> \_________
+ * : : :
+ */
+static void eepStart (void)
+{
+ out8(I2C_BUS_DAT, 0x60); /* SCLK = high SDIO = high */
+ out8(I2C_BUS_DIR, 0x60); /* set output direction for SCLK/SDIO */
+ udelay(10);
+ out8(I2C_BUS_DAT, 0x40); /* SCLK = high SDIO = low */
+ udelay(10);
+ out8(I2C_BUS_DAT, 0x00); /* SCLK = low SDIO = low */
+ udelay(10);
+}
+
+/*----------------------------------------------------------------------------*/
+/*
+ * STOP sequence
+ * _______
+ * SCLK _____/
+ * _ ___
+ * SDIO _>_______/
+ * : : :
+ */
+static void eepStop (void)
+{
+ out8(I2C_BUS_DAT, 0x00); /* SCLK = low SDIO = low */
+ out8(I2C_BUS_DIR, 0x60); /* set output direction for SCLK/SDIO */
+ udelay(10);
+ out8(I2C_BUS_DAT, 0x40); /* SCLK = high SDIO = low */
+ udelay(10);
+ out8(I2C_BUS_DAT, 0x60); /* SCLK = high SDIO = high */
+ udelay(10);
+ out8(I2C_BUS_DIR, 0x00); /* reset to input direction */
+}
+
+/*----------------------------------------------------------------------------*/
+/*
+ * Read one byte from EEPROM
+ * ___ ___ ___ ___ ___ ___ ___ ___
+ * SCLK ___/ \___/ \___/ \___/ \___/ \___/ \___/ \___/ \
+ * _________________________________________________________________
+ * SDIO > ^ ^ ^ ^ ^ ^ ^ ^
+ * : : : : : : : : : : : : : : : : :
+ */
+static unsigned char eepReadByte (void)
+{
+ register unsigned char buf = 0x00;
+ register int i;
+
+ out8(I2C_BUS_DIR, 0x40);
+
+ for (i = 0; i < 8; i++)
+ {
+ out8(I2C_BUS_DAT, 0x00); /* SCLK = low SDIO = high */
+ udelay(10);
+ out8(I2C_BUS_DAT, 0x40); /* SCLK = high SDIO = high */
+ udelay(15);
+ buf <<= 1;
+ buf = (in8(I2C_BUS_DAT) & 0x20) ? (buf | 0x01) : (buf & 0xFE);
+ out8(I2C_BUS_DAT, 0x00); /* SCLK = low SDIO = high */
+ udelay(10);
+ }
+ return(buf);
+}
+
+/*----------------------------------------------------------------------------*/
+/*
+ * Write one byte to EEPROM
+ * ___ ___ ___ ___ ___ ___ ___ ___
+ * SCLK __/ \___/ \___/ \___/ \___/ \___/ \___/ \___/ \__
+ * _______ _______ _______ _______ _______ _______ _______ ________
+ * SDIO X_______X_______X_______X_______X_______X_______X_______X________
+ * : 7 : 6 : 5 : 4 : 3 : 2 : 1 : 0
+ */
+static void eepWriteByte (register unsigned char buf)
+{
+ register int i;
+
+ (buf & 0x80) ? out8(I2C_BUS_DAT, 0x20) : out8(I2C_BUS_DAT, 0x00); /* SCLK = low SDIO = data */
+ out8(I2C_BUS_DIR, 0x60);
+
+ for (i = 7; i >= 0; i--)
+ {
+ (buf & 0x80) ? out8(I2C_BUS_DAT, 0x20) : out8(I2C_BUS_DAT, 0x00); /* SCLK=low SDIO=data */
+ udelay(10);
+ (buf & 0x80) ? out8(I2C_BUS_DAT, 0x60) : out8(I2C_BUS_DAT, 0x40); /* SCLK=high SDIO=data */
+ udelay(15);
+ (buf & 0x80) ? out8(I2C_BUS_DAT, 0x20) : out8(I2C_BUS_DAT, 0x00); /* SCLK=low SDIO=data */
+ udelay(10);
+ buf <<= 1;
+ }
+}
+
+/*----------------------------------------------------------------------------*/
+/*
+ * Read data acknowledge of EEPROM
+ * _______
+ * SCLK ____/ \___
+ * _______________
+ * SDIO >
+ * : : ^ :
+ */
+static int eepReadAck (void)
+{
+ int retval;
+
+ out8(I2C_BUS_DIR, 0x40);
+ out8(I2C_BUS_DAT, 0x00); /* SCLK = low SDIO = high */
+ udelay(10);
+ out8(I2C_BUS_DAT, 0x40); /* SCLK = high SDIO = high */
+ udelay(10);
+ retval = (in8(I2C_BUS_DAT) & 0x20) ? ERROR : 0;
+ udelay(10);
+ out8(I2C_BUS_DAT, 0x00); /* SCLK = low SDIO = high */
+ udelay(10);
+
+ return(retval);
+}
+
+/*----------------------------------------------------------------------------*/
+/*
+ * Write data acknowledge to EEPROM
+ * _______
+ * SCLK ____/ \___
+ *
+ * SDIO >_______________
+ * : : :
+ */
+static void eepWriteAck (unsigned char ack)
+{
+ ack ? out8(I2C_BUS_DAT, 0x20) : out8(I2C_BUS_DAT, 0x00); /* SCLK = low SDIO = ack */
+ out8(I2C_BUS_DIR, 0x60);
+ udelay(10);
+ ack ? out8(I2C_BUS_DAT, 0x60) : out8(I2C_BUS_DAT, 0x40); /* SCLK = high SDIO = ack */
+ udelay(15);
+ ack ? out8(I2C_BUS_DAT, 0x20) : out8(I2C_BUS_DAT, 0x00); /* SCLK = low SDIO = ack */
+ udelay(10);
+}
+
+/*----------------------------------------------------------------------------*/
+/*
+ * Read bytes from EEPROM
+ */
+int el_srom_load (addr, buf, cnt, device, block)
+unsigned char addr;
+unsigned char *buf;
+int cnt;
+unsigned char device;
+unsigned char block;
+{
+ register int i;
+
+ for (i=0;i<cnt;i++)
+ {
+ eepStart();
+ eepWriteByte(0xA0 | device | block);
+ if (eepReadAck() == ERROR)
+ {
+ eepStop();
+ return(ERROR);
+ }
+ eepWriteByte(addr++);
+ if (eepReadAck() == ERROR)
+ {
+ eepStop();
+ return(ERROR);
+ }
+ eepStart();
+
+ eepWriteByte(0xA1 | device | block);
+ if (eepReadAck() == ERROR)
+ {
+ eepStop();
+ return(ERROR);
+ }
+
+ *buf++ = eepReadByte();
+ eepWriteAck(1);
+ eepStop();
+
+ if ((addr == 0) && (i != (cnt-1))) /* is it the same block ? */
+ {
+ if (block == FIRST_BLOCK)
+ block = SECOND_BLOCK;
+ else
+ return(ERROR);
+ }
+ }
+ return(cnt);
+}
+
+/*----------------------------------------------------------------------------*/
+/*
+ *
+ * Write bytes to EEPROM
+ *
+ */
+int el_srom_store (addr, buf, cnt, device, block)
+unsigned char addr, *buf, device, block;
+int cnt;
+{
+ register int i, retVal;
+
+ for (i=0;i<cnt;i++)
+ {
+ retVal = ERROR;
+ do
+ {
+ eepStart();
+ eepWriteByte(0xA0 | device | block);
+ if ((retVal = eepReadAck()) == ERROR)
+ eepStop();
+ } while (retVal == ERROR);
+
+ eepWriteByte(addr++);
+ if (eepReadAck() == ERROR) return(ERROR);
+
+ if ((addr == 0) && (i != (cnt-1))) /* is it the same block ? */
+ {
+ if (block == FIRST_BLOCK)
+ block = SECOND_BLOCK;
+ else
+ return(ERROR);
+ }
+
+ eepWriteByte(*buf++);
+ if (eepReadAck() == ERROR)
+ return(ERROR);
+
+ eepStop();
+ }
+ return(cnt);
+}
+
+/*----------------------------------------------------------------------------*/
+/*
+ * calculate checksum for ELTEC revision srom
+ */
+unsigned long el_srom_checksum (ptr, size)
+register unsigned char *ptr;
+unsigned long size;
+{
+ u_long f, accu = 0;
+ u_int i;
+ u_char byte;
+
+ for (; size; size--)
+ {
+ byte = *ptr++;
+ for (i = 8; i; i--)
+ {
+ f = ((byte & 1) ^ (accu & 1)) ? 0x84083001 : 0;
+ accu >>= 1; accu ^= f;
+ byte >>= 1;
+ }
+ }
+ return(accu);
+}
+
+/*----------------------------------------------------------------------------*/
--- /dev/null
+/*
+ * (C) Copyright 2001
+ * Josh Huber <huber@mclx.com>, Mission Critical Linux, 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
+ */
+
+/*
+ * u-boot.lds - linker script for U-Boot on the Galileo Eval Board.
+ */
+
+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/74xx_7xx/start.o (.text)
+
+/* store the environment in a seperate sector in the boot flash */
+/* . = env_offset; */
+/* common/environment.o(.text) */
+
+ *(.text)
+ *(.fixup)
+ *(.got1)
+ }
+ _etext = .;
+ PROVIDE (etext = .);
+ .rodata :
+ {
+ *(.rodata)
+ *(.rodata1)
+ }
+ .fini : { *(.fini) } =0
+ .ctors : { *(.ctors) }
+ .dtors : { *(.dtors) }
+
+ /* Read-write section, merged into data segment: */
+ . = (. + 0x00FF) & 0xFFFFFF00;
+ _erotext = .;
+ PROVIDE (erotext = .);
+ .reloc :
+ {
+ *(.got)
+ _GOT2_TABLE_ = .;
+ *(.got2)
+ _FIXUP_TABLE_ = .;
+ *(.fixup)
+ }
+ __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2;
+ __fixup_entries = (. - _FIXUP_TABLE_)>>2;
+
+ .data :
+ {
+ *(.data)
+ *(.data1)
+ *(.sdata)
+ *(.sdata2)
+ *(.dynamic)
+ CONSTRUCTORS
+ }
+ _edata = .;
+ PROVIDE (edata = .);
+
+ __start___ex_table = .;
+ __ex_table : { *(__ex_table) }
+ __stop___ex_table = .;
+
+ . = ALIGN(256);
+ __init_begin = .;
+ .text.init : { *(.text.init) }
+ .data.init : { *(.data.init) }
+ . = ALIGN(256);
+ __init_end = .;
+
+ __bss_start = .;
+ .bss :
+ {
+ *(.sbss) *(.scommon)
+ *(.dynbss)
+ *(.bss)
+ *(COMMON)
+ }
+ _end = . ;
+ PROVIDE (end = .);
+}
--- /dev/null
+/*
+ * (C) Copyright 2001 ELTEC Elektronik AG
+ * Frank Gottschling <fgottschling@eltec.de>
+ *
+ * ELTEC ELPPC RAM initialization
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <config.h>
+#include <version.h>
+#include <mpc106.h>
+
+#include <ppc_asm.tmpl>
+#include <ppc_defs.h>
+
+.globl board_asm_init
+board_asm_init:
+
+/*
+ * setup pointer to message block
+ */
+ mflr r13 /* save away link register */
+ bl get_lnk_reg /* r3=addr of next instruction */
+ subi r4, r3, 8 /* r4=board_asm_init addr */
+ addi r29, r4, (MessageBlock-board_asm_init)
+
+/*
+ * dcache_disable
+ */
+ mfspr r3, HID0
+ li r4, HID0_DCE
+ andc r3, r3, r4
+ mr r2, r3
+ ori r3, r3, HID0_DCI
+ sync
+ mtspr HID0, r3
+ mtspr HID0, r2
+ isync
+ sync
+/*
+ * icache_disable
+ */
+ mfspr r3, HID0
+ li r4, 0
+ ori r4, r4, HID0_ICE
+ andc r3, r3, r4
+ sync
+ mtspr HID0, r3
+/*
+ * invalidate caches
+ */
+ ori r3, r3, (HID0_ICE | HID0_ICFI | HID0_DCI | HID0_DCE)
+ or r4, r4, r3
+ isync
+ mtspr HID0, r4
+ andc r4, r4, r3
+ isync
+ mtspr HID0, r4
+ isync
+/*
+ * icache_enable
+ */
+ mfspr r3, HID0
+ ori r3, r3, (HID0_ICE | HID0_ICFI)
+ sync
+ mtspr HID0, r3
+
+
+/*
+ * setup memory controller
+ */
+ lis r1, MPC106_REG_ADDR@h
+ ori r1, r1, MPC106_REG_ADDR@l
+ lis r2, MPC106_REG_DATA@h
+ ori r2, r2, MPC106_REG_DATA@l
+
+ /* Configure PICR1 */
+ lis r3, MPC106_REG@h
+ ori r3, r3, PCI_PICR1
+ stwbrx r3, 0, r1
+ addis r3, r0, 0xFF14
+ ori r3, r3, 0x1CC8
+ eieio
+ stwbrx r3, 0, r2
+
+ /* Configure PICR2 */
+ lis r3, MPC106_REG@h
+ ori r3, r3, PCI_PICR2
+ stwbrx r3, 0, r1
+ addis r3, r0, 0x0000
+ ori r3, r3, 0x0000
+ eieio
+ stwbrx r3, 0, r2
+
+ /* Configure EUMBAR */
+ lis r3, MPC106_REG@h
+ ori r3, r3, 0x0078 /* offest of EUMBAR in PCI config space */
+ stwbrx r3, 0, r1
+ lis r3, MPC107_EUMB_ADDR@h
+ eieio
+ stwbrx r3, 0, r2
+
+ /* Configure Address Map B Option Reg */
+ lis r3, MPC106_REG@h
+ ori r3, r3, 0x00e0 /* offest of AMBOR in PCI config space */
+ stwbrx r3, 0, r1
+ lis r3, 0
+ eieio
+ stwbrx r3, 0, r2
+
+ /* Configure I2C Controller */
+ lis r14, MPC107_I2C_ADDR@h /* base of I2C controller */
+ ori r14, r14, MPC107_I2C_ADDR@l
+ lis r3, 0x2b10 /* I2C clock = 100MHz/1024 */
+ stw r3, 4(r14)
+ li r3, 0 /* clear arbitration */
+ eieio
+ stw r3, 12(r14)
+
+ /* Configure MCCR1 */
+ lis r3, MPC106_REG@h
+ ori r3, r3, MPC106_MCCR1
+ stwbrx r3, 0, r1
+ addis r3, r0, 0x0660 /* don't set MEMGO now ! */
+ ori r3, r3, 0x0000
+ eieio
+ stwbrx r3, 0, r2
+
+ /* Configure MCCR2 */
+ lis r3, MPC106_REG@h
+ ori r3, r3, MPC106_MCCR2
+ stwbrx r3, 0, r1
+ addis r3, r0, 0x0400
+ ori r3, r3, 0x1800
+ eieio
+ stwbrx r3, 0, r2
+
+
+ /* Configure MCCR3 */
+ lis r3, MPC106_REG@h
+ ori r3, r3, MPC106_MCCR3
+ stwbrx r3, 0, r1
+ addis r3, r0, 0x0230
+ ori r3, r3, 0x0000
+ eieio
+ stwbrx r3, 0, r2
+
+ /* Configure MCCR4 */
+ lis r3, MPC106_REG@h
+ ori r3, r3, MPC106_MCCR4
+ stwbrx r3, 0, r1
+ addis r3, r0, 0x2532
+ ori r3, r3, 0x2220
+ eieio
+ stwbrx r3, 0, r2
+
+/*
+ * configure memory interface (MICRs)
+ */
+ addis r3, r0, 0x8000 /* ADDR_80 */
+ ori r3, r3, 0x0080 /* SMEMADD1 */
+ stwbrx r3, 0, r1
+ addis r3, r0, 0xFFFF
+ ori r3, r3, 0x4000
+ eieio
+ stwbrx r3, 0, r2
+
+ addis r3, r0, 0x8000 /* ADDR_84 */
+ ori r3, r3, 0x0084 /* SMEMADD2 */
+ stwbrx r3, 0, r1
+ addis r3, r0, 0xFFFF
+ ori r3, r3, 0xFFFF
+ eieio
+ stwbrx r3, 0, r2
+
+ addis r3, r0, 0x8000 /* ADDR_88 */
+ ori r3, r3, 0x0088 /* EXTSMEM1 */
+ stwbrx r3, 0, r1
+ addis r3, r0, 0x0303
+ ori r3, r3, 0x0000
+ eieio
+ stwbrx r3, 0, r2
+
+ addis r3, r0, 0x8000 /* ADDR_8C */
+ ori r3, r3, 0x008c /* EXTSMEM2 */
+ stwbrx r3, 0, r1
+ addis r3, r0, 0x0303
+ ori r3, r3, 0x0303
+ eieio
+ stwbrx r3, 0, r2
+
+ addis r3, r0, 0x8000 /* ADDR_90 */
+ ori r3, r3, 0x0090 /* EMEMADD1 */
+ stwbrx r3, 0, r1
+ addis r3, r0, 0xFFFF
+ ori r3, r3, 0x7F3F
+ eieio
+ stwbrx r3, 0, r2
+
+ addis r3, r0, 0x8000 /* ADDR_94 */
+ ori r3, r3, 0x0094 /* EMEMADD2 */
+ stwbrx r3, 0, r1
+ addis r3, r0, 0xFFFF
+ ori r3, r3, 0xFFFF
+ eieio
+ stwbrx r3, 0, r2
+
+ addis r3, r0, 0x8000 /* ADDR_98 */
+ ori r3, r3, 0x0098 /* EXTEMEM1 */
+ stwbrx r3, 0, r1
+ addis r3, r0, 0x0303
+ ori r3, r3, 0x0000
+ eieio
+ stwbrx r3, 0, r2
+
+ addis r3, r0, 0x8000 /* ADDR_9C */
+ ori r3, r3, 0x009c /* EXTEMEM2 */
+ stwbrx r3, 0, r1
+ addis r3, r0, 0x0303
+ ori r3, r3, 0x0303
+ eieio
+ stwbrx r3, 0, r2
+
+ addis r3, r0, 0x8000 /* ADDR_A0 */
+ ori r3, r3, 0x00a0 /* MEMBNKEN */
+ stwbrx r3, 0, r1
+ addis r3, r0, 0x0000
+ ori r3, r3, 0x0003
+ eieio
+ stwbrx r3, 0, r2
+
+/*
+ * must wait at least 100us after HRESET to issue a MEMGO
+ */
+ lis r0, 1
+ mtctr r0
+memStartWait:
+ bdnz memStartWait
+
+/*
+ * enable RAM Operations through MCCR1 (MEMGO)
+ */
+ lis r3, 0x8000
+ ori r3, r3, 0x00f0
+ stwbrx r3, r0, r1
+ sync
+ lwbrx r3, 0, r2
+ lis r0, 0x0008
+ or r3, r0, r3
+ stwbrx r3, 0, r2
+ sync
+
+/*
+ * set LEDs first time
+ */
+ li r3, 0x1
+ lis r30, CFG_USR_LED_BASE@h
+ stb r3, 2(r30)
+ sync
+
+/*
+ * init COM1 for polled output
+ */
+ lis r8, CFG_NS16550_COM1@h /* COM1 base address*/
+ ori r8, r8, CFG_NS16550_COM1@l
+ li r9, 0x00
+ stb r9, 1(r8) /* int disabled */
+ eieio
+ li r9, 0x00
+ stb r9, 4(r8) /* modem ctrl */
+ eieio
+ li r9, 0x80
+ stb r9, 3(r8) /* link ctrl */
+ eieio
+ li r9, (CFG_NS16550_CLK / 16 / CONFIG_BAUDRATE)
+ stb r9, 0(r8) /* baud rate (LSB)*/
+ eieio
+ li r9, ((CFG_NS16550_CLK / 16 / CONFIG_BAUDRATE) >> 8)
+ stb r9, 1(r8) /* baud rate (MSB) */
+ eieio
+ li r9, 0x07
+ stb r9, 3(r8) /* 8 data bits, 2 stop bit, no parity */
+ eieio
+ li r9, 0x0b
+ stb r9, 4(r8) /* enable the receiver and transmitter (modem ctrl) */
+ eieio
+waitEmpty:
+ lbz r9, 5(r8) /* transmit empty */
+ andi. r9, r9, 0x40
+ beq waitEmpty
+ li r9, 0x47
+ stb r9, 3(r8) /* send break, 8 data bits, 2 stop bit, no parity */
+ eieio
+
+ lis r0, 0x0001
+ mtctr r0
+waitCOM1:
+ lwz r0, 5(r8) /* load from port for delay */
+ bdnz waitCOM1
+
+waitEmpty1:
+ lbz r9, 5(r8) /* transmit empty */
+ andi. r9, r9, 0x40
+ beq waitEmpty1
+ li r9, 0x07
+ stb r9, 3(r8) /* 8 data bits, 2 stop bit, no parity */
+ eieio
+
+/*
+ * intro message from message block
+ */
+ addi r3, r29, (MnewLine-MessageBlock)
+ bl Printf
+ addi r3, r29, (MinitLogo-MessageBlock)
+ bl Printf
+
+/*
+ * memory cofiguration using SPD information stored on the SODIMMs
+ */
+ addi r3, r29, (Mspd01-MessageBlock)
+ bl Printf
+
+ li r17, 0
+
+ li r3, 0x0002 /* get RAM type from spd for bank0/1 */
+ bl spdRead
+
+ cmpi 0, 0, r3, -1 /* error ? */
+ bne noSpdError
+
+ addi r3, r29, (Mfail-MessageBlock)
+ bl Printf
+
+ li r6, 0xe /* error codes in r6 and r7 */
+ li r7, 0x0
+ b toggleError /* fail - loop forever */
+
+noSpdError:
+ mr r15, r3 /* save r3 */
+
+ addi r3, r29, (Mok-MessageBlock)
+ bl Printf
+
+ cmpli 0, 0, r15, 0x0004 /* SDRAM ? */
+ beq isSDRAM
+
+ addi r3, r29, (MramTyp-MessageBlock)
+ bl Printf
+
+ li r6, 0xd /* error codes in r6 and r7 */
+ li r7, 0x0
+ b toggleError /* fail - loop forever */
+
+isSDRAM:
+ li r3, 0x0012 /* get supported CAS latencies from byte 18 */
+ bl spdRead
+ mr r15, r3
+ li r3, 0x09
+ andi. r0, r15, 0x04
+ bne maxCLis3
+ li r3, 0x17
+maxCLis3:
+ andi. r0, r15, 0x02
+ bne CL2
+
+ addi r3, r29, (MramTyp-MessageBlock)
+ bl Printf
+
+ li r6, 0xc /* error codes in r6 and r7 */
+ li r7, 0x0
+ b toggleError /* fail - loop forever */
+CL2:
+ bl spdRead
+ cmpli 0, 0, r3, 0xa1 /* cycle time must be 10ns max. */
+ blt speedOk
+
+ addi r3, r29, (MramTyp-MessageBlock)
+ bl Printf
+
+ li r6, 0xb /* error codes in r6 and r7 */
+ li r7, 0x0
+ b toggleError /* fail - loop forever */
+speedOk:
+ lis r20, 0x06e8 /* preset MCR1 value */
+
+ li r3, 0x0011 /* get number of internal banks from spd for bank0/1 */
+ bl spdRead
+
+ cmpli 0, 0, r3, 0x02
+ beq SD_2B
+ cmpli 0, 0, r3, 0x04
+ beq SD_4B
+memConfErr:
+ addi r3, r29, (MramConfErr-MessageBlock)
+ bl Printf
+
+ li r6, 0xa /* error codes in r6 and r7 */
+ li r7, 0x0
+ b toggleError /* fail - loop forever */
+
+SD_2B:
+ li r3, 0x0003 /* get number of row bits from spd for bank0/1 */
+ bl spdRead
+ cmpli 0, 0, r3, 0x0b
+ beq row11x2
+ cmpli 0, 0, r3, 0x0c
+ beq row12x2or13x2
+ cmpli 0, 0, r3, 0x0d
+ beq row12x2or13x2
+ b memConfErr
+SD_4B:
+ li r3, 0x0003 /* get number of row bits from spd for bank0/1 */
+ bl spdRead
+ cmpli 0, 0, r3, 0x0b
+ beq row11x4or12x4
+ cmpli 0, 0, r3, 0x0c
+ beq row11x4or12x4
+ cmpli 0, 0, r3, 0x0d
+ beq row13x4
+ b memConfErr
+row12x2or13x2:
+ ori r20, r20, 0x05
+ b row11x4or12x4
+row13x4:
+ ori r20, r20, 0x0a
+ b row11x4or12x4
+row11x2:
+ ori r20, r20, 0x0f
+row11x4or12x4:
+ /* get the size of bank 0-1 */
+
+ li r3, 0x001f /* get bank size from spd for bank0/1 */
+ bl spdRead
+
+ rlwinm r16, r3, 2, 24, 29 /* calculate size in MByte (128 MB max.) */
+
+ li r3, 0x0005 /* get number of banks from spd for bank0/1 */
+ bl spdRead
+
+ cmpi 0, 0, r3, 2 /* 2 banks ? */
+ bne SDRAMnobank1
+
+ mr r17, r16
+
+SDRAMnobank1:
+ li r3, 0x000c /* get refresh from spd for bank0/1 */
+ bl spdRead
+ andi. r3, r3, 0x007f /* mask selfrefresh bit */
+ li r4, 0x1800 /* refesh cycle 1536 clocks left shifted 2 */
+ cmpli 0, 0, r3, 0x0000 /* 15.6 us ? */
+ beq writeRefresh
+
+ li r4, 0x0c00 /* refesh cycle 768 clocks left shifted 2 */
+ cmpli 0, 0, r3, 0x0002 /* 7.8 us ? */
+ beq writeRefresh
+
+ li r4, 0x3000 /* refesh cycle 3072 clocks left shifted 2 */
+ cmpli 0, 0, r3, 0x0003 /* 31.3 us ? */
+ beq writeRefresh
+
+ li r4, 0x6000 /* refesh cycle 6144 clocks left shifted 2 */
+ cmpli 0, 0, r3, 0x0004 /* 62.5 us ? */
+ beq writeRefresh
+
+ li r4, 0
+ ori r4, r4, 0xc000 /* refesh cycle 8224 clocks left shifted 2 */
+ cmpli 0, 0, r3, 0x0005 /* 125 us ? */
+ beq writeRefresh
+
+ b memConfErr
+
+writeRefresh:
+ lis r21, 0x0400 /* preset MCCR2 value */
+ or r21, r21, r4
+
+ /* Overwrite MCCR1 */
+ lis r3, MPC106_REG@h
+ ori r3, r3, MPC106_MCCR1
+ stwbrx r3, 0, r1
+ eieio
+ stwbrx r20, 0, r2
+
+ /* Overwrite MCCR2 */
+ lis r3, MPC106_REG@h
+ ori r3, r3, MPC106_MCCR2
+ stwbrx r3, 0, r1
+ eieio
+ stwbrx r21, 0, r2
+
+ /* set the memory boundary registers for bank 0-3 */
+ li r20, 0
+ lis r23, 0x0303
+ lis r24, 0x0303
+ subi r21, r16, 1 /* calculate end address bank0 */
+ li r22, 1
+
+ cmpi 0, 0, r17, 0 /* bank1 present ? */
+ beq nobank1
+
+ andi. r3, r16, 0x00ff /* calculate start address of bank1 */
+ andi. r4, r16, 0x0300
+ rlwinm r3, r3, 8, 16, 23
+ or r20, r20, r3
+ or r23, r23, r4
+
+ add r16, r16, r17 /* add to total memory size */
+
+ subi r3, r16, 1 /* calculate end address of bank1 */
+ andi. r4, r3, 0x0300
+ andi. r3, r3, 0x00ff
+ rlwinm r3, r3, 8, 16, 23
+ or r21, r21, r3
+ or r24, r24, r4
+
+ ori r22, r22, 2 /* enable bank1 */
+ b bankOk
+nobank1:
+ ori r23, r23, 0x0300 /* set bank1 start to unused area */
+ ori r24, r24, 0x0300 /* set bank1 end to unused area */
+bankOk:
+ addi r3, r29, (Mactivate-MessageBlock)
+ bl Printf
+ mr r3, r16
+ bl OutDec
+ addi r3, r29, (Mact0123e-MessageBlock)
+ bl Printf
+
+/*
+ * overwrite MSAR1, MEAR1, EMSAR1, and EMEAR1
+ */
+ addis r3, r0, 0x8000 /* ADDR_80 */
+ ori r3, r3, 0x0080 /* MSAR1 */
+ stwbrx r3, 0, r1
+ eieio
+ stwbrx r20, 0, r2
+
+ addis r3, r0, 0x8000 /* ADDR_88 */
+ ori r3, r3, 0x0088 /* EMSAR1 */
+ stwbrx r3, 0, r1
+ eieio
+ stwbrx r23, 0, r2
+
+ addis r3, r0, 0x8000 /* ADDR_90 */
+ ori r3, r3, 0x0090 /* MEAR1 */
+ stwbrx r3, 0, r1
+ eieio
+ stwbrx r21, 0, r2
+
+ addis r3, r0, 0x8000 /* ADDR_98 */
+ ori r3, r3, 0x0098 /* EMEAR1 */
+ stwbrx r3, 0, r1
+ eieio
+ stwbrx r24, 0, r2
+
+ addis r3, r0, 0x8000 /* ADDR_A0 */
+ ori r3, r3, 0x00a0 /* MBER */
+ stwbrx r3, 0, r1
+ eieio
+ stwbrx r22, 0, r2
+
+/*
+ * delay to let SDRAM go through several initialization/refresh cycles
+ */
+ lis r3, 3
+ mtctr r3
+memStartWait_1:
+ bdnz memStartWait_1
+ eieio
+
+/*
+ * set LEDs end
+ */
+ li r3, 0xf
+ lis r30, CFG_USR_LED_BASE@h
+ stb r3, 2(r30)
+ sync
+
+ mtlr r13
+ blr /* EXIT board_asm_init ... */
+
+/*----------------------------------------------------------------------------*/
+/*
+ * print a message to COM1 in polling mode (r10=COM1 port, r3=(char*)string)
+ */
+
+Printf:
+ lis r10, CFG_NS16550_COM1@h /* COM1 base address*/
+ ori r10, r10, CFG_NS16550_COM1@l
+WaitChr:
+ lbz r0, 5(r10) /* read link status */
+ eieio
+ andi. r0, r0, 0x40 /* mask transmitter empty bit */
+ beq cr0, WaitChr /* wait till empty */
+ lbzx r0, r0, r3 /* get char */
+ stb r0, 0(r10) /* write to transmit reg */
+ eieio
+ addi r3, r3, 1 /* next char */
+ lbzx r0, r0, r3 /* get char */
+ cmpwi cr1, r0, 0 /* end of string ? */
+ bne cr1, WaitChr
+ blr
+
+/*
+ * print a char to COM1 in polling mode (r10=COM1 port, r3=char)
+ */
+OutChr:
+ lis r10, CFG_NS16550_COM1@h /* COM1 base address*/
+ ori r10, r10, CFG_NS16550_COM1@l
+OutChr1:
+ lbz r0, 5(r10) /* read link status */
+ eieio
+ andi. r0, r0, 0x40 /* mask transmitter empty bit */
+ beq cr0, OutChr1 /* wait till empty */
+ stb r3, 0(r10) /* write to transmit reg */
+ eieio
+ blr
+
+/*
+ * print 8/4/2 digits hex value to COM1 in polling mode (r10=COM1 port, r3=val)
+ */
+OutHex2:
+ li r9, 4 /* shift reg for 2 digits */
+ b OHstart
+OutHex4:
+ li r9, 12 /* shift reg for 4 digits */
+ b OHstart
+OutHex:
+ li r9, 28 /* shift reg for 8 digits */
+OHstart:
+ lis r10, CFG_NS16550_COM1@h /* COM1 base address*/
+ ori r10, r10, CFG_NS16550_COM1@l
+OutDig:
+ lbz r0, 0(r29) /* slow down dummy read */
+ lbz r0, 5(r10) /* read link status */
+ eieio
+ andi. r0, r0, 0x40 /* mask transmitter empty bit */
+ beq cr0, OutDig
+ sraw r0, r3, r9
+ clrlwi r0, r0, 28
+ cmpwi cr1, r0, 9
+ ble cr1, digIsNum
+ addic r0, r0, 55
+ b nextDig
+digIsNum:
+ addic r0, r0, 48
+nextDig:
+ stb r0, 0(r10) /* write to transmit reg */
+ eieio
+ addic. r9, r9, -4
+ bge OutDig
+ blr
+
+/*
+ * print 3 digits hdec value to COM1 in polling mode
+ * (r10=COM1 port, r3=val, r7=x00, r8=x0, r9=x, r0, r6=scratch)
+ */
+OutDec:
+ li r6, 10
+ divwu r0, r3, r6 /* r0 = r3 / 10, r9 = r3 mod 10 */
+ mullw r10, r0, r6
+ subf r9, r10, r3
+ mr r3, r0
+ divwu r0, r3, r6 /* r0 = r3 / 10, r8 = r3 mod 10 */
+ mullw r10, r0, r6
+ subf r8, r10, r3
+ mr r3, r0
+ divwu r0, r3, r6 /* r0 = r3 / 10, r7 = r3 mod 10 */
+ mullw r10, r0, r6
+ subf r7, r10, r3
+ lis r10, CFG_NS16550_COM1@h /* COM1 base address*/
+ ori r10, r10, CFG_NS16550_COM1@l
+ or. r7, r7, r7
+ bne noblank1
+ li r3, 0x20
+ b OutDec4
+noblank1:
+ addi r3, r7, 48 /* convert to ASCII */
+OutDec4:
+ lbz r0, 0(r29) /* slow down dummy read */
+ lbz r0, 5(r10) /* read link status */
+ eieio
+ andi. r0, r0, 0x40 /* mask transmitter empty bit */
+ beq cr0, OutDec4
+ stb r3, 0(r10) /* x00 to transmit */
+ eieio
+ or. r7, r7, r8
+ beq OutDec5
+ addi r3, r8, 48 /* convert to ASCII */
+OutDec5:
+ lbz r0, 0(r29) /* slow down dummy read */
+ lbz r0, 5(r10) /* read link status */
+ eieio
+ andi. r0, r0, 0x40 /* mask transmitter empty bit */
+ beq cr0, OutDec5
+ stb r3, 0(r10) /* x0 to transmit */
+ eieio
+ addi r3, r9, 48 /* convert to ASCII */
+OutDec6:
+ lbz r0, 0(r29) /* slow down dummy read */
+ lbz r0, 5(r10) /* read link status */
+ eieio
+ andi. r0, r0, 0x40 /* mask transmitter empty bit */
+ beq cr0, OutDec6
+ stb r3, 0(r10) /* x to transmit */
+ eieio
+ blr
+
+/*
+ * hang endless loop
+ */
+toggleError: /* fail type in r6, r7=0xff, toggle LEDs */
+ stb r7, 2(r30) /* r7 to LED */
+ li r0, 0
+ lis r9, 127
+ ori r9, r9, 65535
+toggleError1:
+ addic r0, r0, 1
+ cmpw cr1, r0, r9
+ ble cr1, toggleError1
+ stb r6, 2(r30) /* r6 to LED */
+ li r0, 0
+ lis r9, 127
+ ori r9, r9, 65535
+toggleError2:
+ addic r0, r0, 1
+ cmpw cr1, r0, r9
+ ble cr1, toggleError2
+ b toggleError
+
+/*
+ * routines to read from ram spd
+ */
+spdWaitIdle:
+ lis r0, 0x1 /* timeout for about 100us */
+ mtctr r0
+iSpd:
+ lbz r10, 12(r14)
+ andi. r10, r10, 0x20 /* mask and test MBB */
+ beq idle
+ bdnz iSpd
+ orc. r10, r0, r0 /* return -1 to caller */
+idle:
+ bclr 20, 0 /* return to caller */
+
+waitSpd:
+ lis r0, 0x10 /* timeout for about 1.5ms */
+ mtctr r0
+wSpd:
+ lbz r10, 12(r14)
+ andi. r10, r10, 0x82
+ cmpli 0, 0, r10, 0x82 /* test MCF and MIF set */
+ beq wend
+ bdnz wSpd
+ orc. r10, r0, r0 /* return -1 to caller */
+ bclr 20, 0 /* return to caller */
+
+wend:
+ li r10, 0
+ stb r10, 12(r14) /* clear status */
+ bclr 20, 0 /* return to caller */
+
+/*
+ * spdread
+ * in: r3 adr to read
+ * out: r3 val or -1 for error
+ * uses r10, assumes that r14 points to I2C controller
+ */
+spdRead:
+ mfspr r25, 8 /* save link register */
+
+ bl spdWaitIdle
+ bne spdErr
+
+ li r10, 0x80 /* start with MEN */
+ stb r10, 8(r14)
+ eieio
+
+ li r10, 0xb0 /* start as master */
+ stb r10, 8(r14)
+ eieio
+
+ li r10, 0xa0 /* write device 0xA0 */
+ stb r10, 16(r14)
+ eieio
+ bl waitSpd
+ bne spdErr
+
+ lbz r10, 12(r14) /* test ACK */
+ andi. r10, r10, 0x01
+ bne gotNoAck
+
+ stb r3, 16(r14) /* data address */
+ eieio
+ bl waitSpd
+ bne spdErr
+
+
+ li r10, 0xb4 /* switch to read - restart */
+ stb r10, 8(r14)
+ eieio
+
+ li r10, 0xa1 /* read device 0xA0 */
+ stb r10, 16(r14)
+ eieio
+ bl waitSpd
+ bne spdErr
+
+ li r10, 0xa8 /* no ACK */
+ stb r10, 8(r14)
+ eieio
+
+ lbz r10, 16(r14) /* trigger read next byte */
+ eieio
+ bl waitSpd
+ bne spdErr
+
+ li r10, 0x88 /* generate STOP condition */
+ stb r10, 8(r14)
+ eieio
+
+ lbz r3, 16(r14) /* return read byte */
+
+ mtspr 8, r25 /* restore link register */
+ blr
+
+gotNoAck:
+ li r10, 0x80 /* generate STOP condition */
+ stb r10, 8(r14)
+ eieio
+spdErr:
+ orc r3, r0, r0 /* return -1 */
+ mtspr 8, r25 /* restore link register */
+ blr
+
+get_lnk_reg:
+ mflr r3 /* return link reg */
+ blr
+
+MessageBlock:
+
+MinitLogo:
+ .ascii "\015\012*** ELTEC Elektronik, Mainz ***\015\012"
+ .ascii "\015\012Initialising RAM\015\012\000"
+Mspd01:
+ .ascii " Reading SPD of SODIMM ...... \000"
+MramTyp:
+ .ascii "\015\012\SDRAM with CL=2 at 100 MHz required!\015\012\000"
+MramConfErr:
+ .ascii "\015\012\Unsupported SODIMM Configuration!\015\012\000"
+Mactivate:
+ .ascii " Activating \000"
+Mact0123e:
+ .ascii " MByte.\015\012\000"
+Mok:
+ .ascii "OK \015\012\000"
+Mfail:
+ .ascii "FAILED \015\012\000"
+MnewLine:
+ .ascii "\015\012\000"
+ .align 4
--- /dev/null
+/*
+ * (C) Copyright 2001
+ * Josh Huber <huber@mclx.com>, Mission Critical Linux, 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
+ */
+
+/*
+ * u-boot.lds - linker script for U-Boot on the Galileo Eval Board.
+ */
+
+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/74xx_7xx/start.o (.text)
+
+/* store the environment in a seperate sector in the boot flash */
+/* . = env_offset; */
+/* common/environment.o(.text) */
+
+ *(.text)
+ *(.fixup)
+ *(.got1)
+ }
+ _etext = .;
+ PROVIDE (etext = .);
+ .rodata :
+ {
+ *(.rodata)
+ *(.rodata1)
+ }
+ .fini : { *(.fini) } =0
+ .ctors : { *(.ctors) }
+ .dtors : { *(.dtors) }
+
+ /* Read-write section, merged into data segment: */
+ . = (. + 0x00FF) & 0xFFFFFF00;
+ _erotext = .;
+ PROVIDE (erotext = .);
+ .reloc :
+ {
+ *(.got)
+ _GOT2_TABLE_ = .;
+ *(.got2)
+ _FIXUP_TABLE_ = .;
+ *(.fixup)
+ }
+ __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2;
+ __fixup_entries = (. - _FIXUP_TABLE_)>>2;
+
+ .data :
+ {
+ *(.data)
+ *(.data1)
+ *(.sdata)
+ *(.sdata2)
+ *(.dynamic)
+ CONSTRUCTORS
+ }
+ _edata = .;
+ PROVIDE (edata = .);
+
+ __start___ex_table = .;
+ __ex_table : { *(__ex_table) }
+ __stop___ex_table = .;
+
+ . = ALIGN(256);
+ __init_begin = .;
+ .text.init : { *(.text.init) }
+ .data.init : { *(.data.init) }
+ . = ALIGN(256);
+ __init_end = .;
+
+ __bss_start = .;
+ .bss :
+ {
+ *(.sbss) *(.scommon)
+ *(.dynbss)
+ *(.bss)
+ *(COMMON)
+ }
+ _end = . ;
+ PROVIDE (end = .);
+}
--- /dev/null
+/*
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Marius Groeger <mgroeger@sysgo.de>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+
+#define FLASH_BANK_SIZE 0x1000000
+#define MAIN_SECT_SIZE 0x20000
+
+flash_info_t flash_info[CFG_MAX_FLASH_BANKS];
+
+
+/*-----------------------------------------------------------------------
+ */
+
+ulong flash_init (void)
+{
+ int i, j;
+ ulong size = 0;
+
+ for (i = 0; i < CFG_MAX_FLASH_BANKS; i++) {
+ ulong flashbase = 0;
+
+ flash_info[i].flash_id =
+ (INTEL_MANUFACT & FLASH_VENDMASK) |
+ (INTEL_ID_28F128J3 & FLASH_TYPEMASK);
+ flash_info[i].size = FLASH_BANK_SIZE;
+ flash_info[i].sector_count = CFG_MAX_FLASH_SECT;
+ memset (flash_info[i].protect, 0, CFG_MAX_FLASH_SECT);
+ if (i == 0)
+ flashbase = PHYS_FLASH_1;
+ else
+ panic ("configured to many flash banks!\n");
+ for (j = 0; j < flash_info[i].sector_count; j++) {
+ flash_info[i].start[j] = flashbase + j * MAIN_SECT_SIZE;
+ }
+ size += flash_info[i].size;
+ }
+
+ /* Protect monitor and environment sectors
+ */
+ flash_protect ( FLAG_PROTECT_SET,
+ CFG_FLASH_BASE,
+ CFG_FLASH_BASE + _armboot_end_data - _armboot_start,
+ &flash_info[0]);
+
+ flash_protect ( FLAG_PROTECT_SET,
+ CFG_ENV_ADDR,
+ CFG_ENV_ADDR + CFG_ENV_SIZE - 1, &flash_info[0]);
+
+ return size;
+}
+
+/*-----------------------------------------------------------------------
+ */
+void flash_print_info (flash_info_t * info)
+{
+ int i;
+
+ switch (info->flash_id & FLASH_VENDMASK) {
+ case (INTEL_MANUFACT & FLASH_VENDMASK):
+ printf ("Intel: ");
+ break;
+ default:
+ printf ("Unknown Vendor ");
+ break;
+ }
+
+ switch (info->flash_id & FLASH_TYPEMASK) {
+ case (INTEL_ID_28F128J3 & FLASH_TYPEMASK):
+ printf ("28F128J3 (128Mbit)\n");
+ break;
+ default:
+ printf ("Unknown Chip Type\n");
+ goto Done;
+ break;
+ }
+
+ printf (" Size: %ld MB in %d Sectors\n",
+ info->size >> 20, info->sector_count);
+
+ printf (" Sector Start Addresses:");
+ for (i = 0; i < info->sector_count; i++) {
+ if ((i % 5) == 0) {
+ printf ("\n ");
+ }
+ printf (" %08lX%s", info->start[i],
+ info->protect[i] ? " (RO)" : " ");
+ }
+ printf ("\n");
+
+ Done:
+}
+
+/*-----------------------------------------------------------------------
+ */
+
+int flash_erase (flash_info_t * info, int s_first, int s_last)
+{
+ int flag, prot, sect;
+ int rc = ERR_OK;
+
+ if (info->flash_id == FLASH_UNKNOWN)
+ return ERR_UNKNOWN_FLASH_TYPE;
+
+ if ((s_first < 0) || (s_first > s_last)) {
+ return ERR_INVAL;
+ }
+
+ if ((info->flash_id & FLASH_VENDMASK) !=
+ (INTEL_MANUFACT & FLASH_VENDMASK)) {
+ return ERR_UNKNOWN_FLASH_VENDOR;
+ }
+
+ prot = 0;
+ for (sect = s_first; sect <= s_last; ++sect) {
+ if (info->protect[sect]) {
+ prot++;
+ }
+ }
+ if (prot)
+ return ERR_PROTECTED;
+
+ /*
+ * Disable interrupts which might cause a timeout
+ * here. Remember that our exception vectors are
+ * at address 0 in the flash, and we don't want a
+ * (ticker) exception to happen while the flash
+ * chip is in programming mode.
+ */
+ flag = disable_interrupts ();
+
+ /* Start erase on unprotected sectors */
+ for (sect = s_first; sect <= s_last && !ctrlc (); sect++) {
+
+ printf ("Erasing sector %2d ... ", sect);
+
+ /* arm simple, non interrupt dependent timer */
+ reset_timer_masked ();
+
+ if (info->protect[sect] == 0) { /* not protected */
+ vu_short *addr = (vu_short *) (info->start[sect]);
+
+ *addr = 0x20; /* erase setup */
+ *addr = 0xD0; /* erase confirm */
+
+ while ((*addr & 0x80) != 0x80) {
+ if (get_timer_masked () > CFG_FLASH_ERASE_TOUT) {
+ *addr = 0xB0; /* suspend erase */
+ *addr = 0xFF; /* reset to read mode */
+ rc = ERR_TIMOUT;
+ goto outahere;
+ }
+ }
+
+ /* clear status register command */
+ *addr = 0x50;
+ /* reset to read mode */
+ *addr = 0xFF;
+ }
+ printf ("ok.\n");
+ }
+ if (ctrlc ())
+ printf ("User Interrupt!\n");
+
+ outahere:
+
+ /* allow flash to settle - wait 10 ms */
+ udelay_masked (10000);
+
+ if (flag)
+ enable_interrupts ();
+
+ return rc;
+}
+
+/*-----------------------------------------------------------------------
+ * Copy memory to flash
+ */
+
+static int write_word (flash_info_t * info, ulong dest, ushort data)
+{
+ vu_short *addr = (vu_short *) dest, val;
+ int rc = ERR_OK;
+ int flag;
+
+ /* Check if Flash is (sufficiently) erased
+ */
+ if ((*addr & data) != data)
+ return ERR_NOT_ERASED;
+
+ /*
+ * Disable interrupts which might cause a timeout
+ * here. Remember that our exception vectors are
+ * at address 0 in the flash, and we don't want a
+ * (ticker) exception to happen while the flash
+ * chip is in programming mode.
+ */
+ flag = disable_interrupts ();
+
+ /* clear status register command */
+ *addr = 0x50;
+
+ /* program set-up command */
+ *addr = 0x40;
+
+ /* latch address/data */
+ *addr = data;
+
+ /* arm simple, non interrupt dependent timer */
+ reset_timer_masked ();
+
+ /* wait while polling the status register */
+ while (((val = *addr) & 0x80) != 0x80) {
+ if (get_timer_masked () > CFG_FLASH_WRITE_TOUT) {
+ rc = ERR_TIMOUT;
+ /* suspend program command */
+ *addr = 0xB0;
+ goto outahere;
+ }
+ }
+
+ if (val & 0x1A) { /* check for error */
+ printf ("\nFlash write error %02x at address %08lx\n",
+ (int) val, (unsigned long) dest);
+ if (val & (1 << 3)) {
+ printf ("Voltage range error.\n");
+ rc = ERR_PROG_ERROR;
+ goto outahere;
+ }
+ if (val & (1 << 1)) {
+ printf ("Device protect error.\n");
+ rc = ERR_PROTECTED;
+ goto outahere;
+ }
+ if (val & (1 << 4)) {
+ printf ("Programming error.\n");
+ rc = ERR_PROG_ERROR;
+ goto outahere;
+ }
+ rc = ERR_PROG_ERROR;
+ goto outahere;
+ }
+
+ outahere:
+ /* read array command */
+ *addr = 0xFF;
+
+ if (flag)
+ enable_interrupts ();
+
+ return rc;
+}
+
+/*-----------------------------------------------------------------------
+ * Copy memory to flash.
+ */
+
+int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt)
+{
+ ulong cp, wp;
+ ushort data;
+ int l;
+ int i, rc;
+
+ wp = (addr & ~1); /* get lower word aligned address */
+
+ /*
+ * handle unaligned start bytes
+ */
+ if ((l = addr - wp) != 0) {
+ data = 0;
+ for (i = 0, cp = wp; i < l; ++i, ++cp) {
+ data = (data >> 8) | (*(uchar *) cp << 8);
+ }
+ for (; i < 2 && cnt > 0; ++i) {
+ data = (data >> 8) | (*src++ << 8);
+ --cnt;
+ ++cp;
+ }
+ for (; cnt == 0 && i < 2; ++i, ++cp) {
+ data = (data >> 8) | (*(uchar *) cp << 8);
+ }
+
+ if ((rc = write_word (info, wp, data)) != 0) {
+ return (rc);
+ }
+ wp += 2;
+ }
+
+ /*
+ * handle word aligned part
+ */
+ while (cnt >= 2) {
+ data = *((vu_short *) src);
+ if ((rc = write_word (info, wp, data)) != 0) {
+ return (rc);
+ }
+ src += 2;
+ wp += 2;
+ cnt -= 2;
+ }
+
+ if (cnt == 0) {
+ return ERR_OK;
+ }
+
+ /*
+ * handle unaligned tail bytes
+ */
+ data = 0;
+ for (i = 0, cp = wp; i < 2 && cnt > 0; ++i, ++cp) {
+ data = (data >> 8) | (*src++ << 8);
+ --cnt;
+ }
+ for (; i < 2; ++i, ++cp) {
+ data = (data >> 8) | (*(uchar *) cp << 8);
+ }
+
+ return write_word (info, wp, data);
+}
--- /dev/null
+/*
+ * (C) Copyright 2000
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
+OUTPUT_ARCH(arm)
+ENTRY(_start)
+SECTIONS
+{
+ . = 0x00000000;
+
+ . = ALIGN(4);
+ .text :
+ {
+ cpu/arm720t/start.o (.text)
+ *(.text)
+ }
+
+ . = ALIGN(4);
+ .rodata : { *(.rodata) }
+
+ . = ALIGN(4);
+ .data : { *(.data) }
+
+ . = ALIGN(4);
+ .got : { *(.got) }
+
+ armboot_end_data = .;
+
+ . = ALIGN(4);
+ .bss : { *(.bss) }
+
+ armboot_end = .;
+}
--- /dev/null
+/*
+ * (C) Copyright 2001
+ * Matthias Fuchs, esd gmbh germany, matthias.fuchs@esd-electronics.com
+ * Stefan Roese, esd gmbh germany, stefan.roese@esd-electronics.com
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <asm/processor.h>
+#include <command.h>
+
+/* ------------------------------------------------------------------------- */
+
+#ifdef FPGA_DEBUG
+#define DBG(x...) printf(x)
+#else
+#define DBG(x...)
+#endif /* DEBUG */
+
+#define MAX_ONES 226
+
+#define IBM405GP_GPIO0_OR 0xef600700 /* GPIO Output */
+#define IBM405GP_GPIO0_TCR 0xef600704 /* GPIO Three-State Control */
+#define IBM405GP_GPIO0_ODR 0xef600718 /* GPIO Open Drain */
+#define IBM405GP_GPIO0_IR 0xef60071c /* GPIO Input */
+
+#ifdef CFG_FPGA_PRG
+# define FPGA_PRG CFG_FPGA_PRG /* FPGA program pin (ppc output)*/
+# define FPGA_CLK CFG_FPGA_CLK /* FPGA clk pin (ppc output) */
+# define FPGA_DATA CFG_FPGA_DATA /* FPGA data pin (ppc output) */
+# define FPGA_DONE CFG_FPGA_DONE /* FPGA done pin (ppc input) */
+# define FPGA_INIT CFG_FPGA_INIT /* FPGA init pin (ppc input) */
+#else
+# define FPGA_PRG 0x04000000 /* FPGA program pin (ppc output) */
+# define FPGA_CLK 0x02000000 /* FPGA clk pin (ppc output) */
+# define FPGA_DATA 0x01000000 /* FPGA data pin (ppc output) */
+# define FPGA_DONE 0x00800000 /* FPGA done pin (ppc input) */
+# define FPGA_INIT 0x00400000 /* FPGA init pin (ppc input) */
+#endif
+
+#define ERROR_FPGA_PRG_INIT_LOW -1 /* Timeout after PRG* asserted */
+#define ERROR_FPGA_PRG_INIT_HIGH -2 /* Timeout after PRG* deasserted */
+#define ERROR_FPGA_PRG_DONE -3 /* Timeout after programming */
+
+#define SET_FPGA(data) out32(IBM405GP_GPIO0_OR, data)
+
+#define FPGA_WRITE_1 { \
+ SET_FPGA(FPGA_PRG | FPGA_DATA); /* set clock to 0 */ \
+ SET_FPGA(FPGA_PRG | FPGA_DATA); /* set data to 1 */ \
+ SET_FPGA(FPGA_PRG | FPGA_CLK | FPGA_DATA); /* set clock to 1 */ \
+ SET_FPGA(FPGA_PRG | FPGA_CLK | FPGA_DATA);} /* set data to 1 */
+
+#define FPGA_WRITE_0 { \
+ SET_FPGA(FPGA_PRG | FPGA_DATA); /* set clock to 0 */ \
+ SET_FPGA(FPGA_PRG); /* set data to 0 */ \
+ SET_FPGA(FPGA_PRG | FPGA_CLK); /* set clock to 1 */ \
+ SET_FPGA(FPGA_PRG | FPGA_CLK | FPGA_DATA);} /* set data to 1 */
+
+
+static int fpga_boot(unsigned char *fpgadata, int size)
+{
+ int i,index,len;
+ int count;
+#ifdef CFG_FPGA_SPARTAN2
+ int j;
+#else
+ unsigned char b;
+ int bit;
+#endif
+
+ /* display infos on fpgaimage */
+ index = 15;
+ for (i=0; i<4; i++)
+ {
+ len = fpgadata[index];
+ DBG("FPGA: %s\n", &(fpgadata[index+1]));
+ index += len+3;
+ }
+
+#ifdef CFG_FPGA_SPARTAN2
+ /* search for preamble 0xFFFFFFFF */
+ while (1)
+ {
+ if ((fpgadata[index] == 0xff) && (fpgadata[index+1] == 0xff) &&
+ (fpgadata[index+2] == 0xff) && (fpgadata[index+3] == 0xff))
+ break; /* preamble found */
+ else
+ index++;
+ }
+#else
+ /* search for preamble 0xFF2X */
+ for (index = 0; index < size-1 ; index++)
+ {
+ if ((fpgadata[index] == 0xff) && ((fpgadata[index+1] & 0xf0) == 0x30))
+ break;
+ }
+ index += 2;
+#endif
+
+ DBG("FPGA: configdata starts at position 0x%x\n",index);
+ DBG("FPGA: length of fpga-data %d\n", size-index);
+
+ /*
+ * Setup port pins for fpga programming
+ */
+ out32(IBM405GP_GPIO0_ODR, 0x00000000); /* no open drain pins */
+ out32(IBM405GP_GPIO0_TCR, FPGA_PRG | FPGA_CLK | FPGA_DATA); /* setup for output */
+ out32(IBM405GP_GPIO0_OR, FPGA_PRG | FPGA_CLK | FPGA_DATA); /* set output pins to high */
+
+ DBG("%s, ",((in32(IBM405GP_GPIO0_IR) & FPGA_DONE) == 0) ? "NOT DONE" : "DONE" );
+ DBG("%s\n",((in32(IBM405GP_GPIO0_IR) & FPGA_INIT) == 0) ? "NOT INIT" : "INIT" );
+
+ /*
+ * Init fpga by asserting and deasserting PROGRAM*
+ */
+ SET_FPGA(FPGA_CLK | FPGA_DATA);
+
+ /* Wait for FPGA init line low */
+ count = 0;
+ while (in32(IBM405GP_GPIO0_IR) & FPGA_INIT)
+ {
+ udelay(1000); /* wait 1ms */
+ /* Check for timeout - 100us max, so use 3ms */
+ if (count++ > 3)
+ {
+ DBG("FPGA: Booting failed!\n");
+ return ERROR_FPGA_PRG_INIT_LOW;
+ }
+ }
+
+ DBG("%s, ",((in32(IBM405GP_GPIO0_IR) & FPGA_DONE) == 0) ? "NOT DONE" : "DONE" );
+ DBG("%s\n",((in32(IBM405GP_GPIO0_IR) & FPGA_INIT) == 0) ? "NOT INIT" : "INIT" );
+
+ /* deassert PROGRAM* */
+ SET_FPGA(FPGA_PRG | FPGA_CLK | FPGA_DATA);
+
+ /* Wait for FPGA end of init period . */
+ count = 0;
+ while (!(in32(IBM405GP_GPIO0_IR) & FPGA_INIT))
+ {
+ udelay(1000); /* wait 1ms */
+ /* Check for timeout */
+ if (count++ > 3)
+ {
+ DBG("FPGA: Booting failed!\n");
+ return ERROR_FPGA_PRG_INIT_HIGH;
+ }
+ }
+
+ DBG("%s, ",((in32(IBM405GP_GPIO0_IR) & FPGA_DONE) == 0) ? "NOT DONE" : "DONE" );
+ DBG("%s\n",((in32(IBM405GP_GPIO0_IR) & FPGA_INIT) == 0) ? "NOT INIT" : "INIT" );
+
+ DBG("write configuration data into fpga\n");
+ /* write configuration-data into fpga... */
+
+#ifdef CFG_FPGA_SPARTAN2
+ /*
+ * Load uncompressed image into fpga
+ */
+ for (i=index; i<size; i++)
+ {
+ for (j=0; j<8; j++)
+ {
+ if ((fpgadata[i] & 0x80) == 0x80)
+ {
+ FPGA_WRITE_1;
+ }
+ else
+ {
+ FPGA_WRITE_0;
+ }
+ fpgadata[i] <<= 1;
+ }
+ }
+#else
+ /* send 0xff 0x20 */
+ FPGA_WRITE_1; FPGA_WRITE_1; FPGA_WRITE_1; FPGA_WRITE_1;
+ FPGA_WRITE_1; FPGA_WRITE_1; FPGA_WRITE_1; FPGA_WRITE_1;
+ FPGA_WRITE_0; FPGA_WRITE_0; FPGA_WRITE_1; FPGA_WRITE_0;
+ FPGA_WRITE_0; FPGA_WRITE_0; FPGA_WRITE_0; FPGA_WRITE_0;
+
+ /*
+ ** Bit_DeCompression
+ ** Code 1 .. maxOnes : n '1's followed by '0'
+ ** maxOnes + 1 .. maxOnes + 1 : n - 1 '1's no '0'
+ ** maxOnes + 2 .. 254 : n - (maxOnes + 2) '0's followed by '1'
+ ** 255 : '1'
+ */
+
+ for (i=index; i<size; i++)
+ {
+ b = fpgadata[i];
+ if ((b >= 1) && (b <= MAX_ONES))
+ {
+ for(bit=0; bit<b; bit++)
+ {
+ FPGA_WRITE_1;
+ }
+ FPGA_WRITE_0;
+ }
+ else if (b == (MAX_ONES+1))
+ {
+ for(bit=1; bit<b; bit++)
+ {
+ FPGA_WRITE_1;
+ }
+ }
+ else if ((b >= (MAX_ONES+2)) && (b <= 254))
+ {
+ for(bit=0; bit<(b-(MAX_ONES+2)); bit++)
+ {
+ FPGA_WRITE_0;
+ }
+ FPGA_WRITE_1;
+ }
+ else if (b == 255)
+ {
+ FPGA_WRITE_1;
+ }
+ }
+#endif
+
+ DBG("%s, ",((in32(IBM405GP_GPIO0_IR) & FPGA_DONE) == 0) ? "NOT DONE" : "DONE" );
+ DBG("%s\n",((in32(IBM405GP_GPIO0_IR) & FPGA_INIT) == 0) ? "NOT INIT" : "INIT" );
+
+ /*
+ * Check if fpga's DONE signal - correctly booted ?
+ */
+
+ /* Wait for FPGA end of programming period . */
+ count = 0;
+ while (!(in32(IBM405GP_GPIO0_IR) & FPGA_DONE))
+ {
+ udelay(1000); /* wait 1ms */
+ /* Check for timeout */
+ if (count++ > 3)
+ {
+ DBG("FPGA: Booting failed!\n");
+ return ERROR_FPGA_PRG_DONE;
+ }
+ }
+
+ DBG("FPGA: Booting successful!\n");
+ return 0;
+}
--- /dev/null
+/*
+ * (C) Copyright 2001
+ * Stefan Roese, esd gmbh germany, stefan.roese@esd-electronics.com
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <ppc4xx.h>
+#include <asm/processor.h>
+#include <pci.h>
+
+
+u_long pci9054_iobase;
+
+
+#define PCI_PRIMARY_CAR (0x500000dc) /* PCI config address reg */
+#define PCI_PRIMARY_CDR (0x80000000) /* PCI config data reg */
+
+
+/*-----------------------------------------------------------------------------+
+| Subroutine: pci9054_read_config_dword
+| Description: Read a PCI configuration register
+| Inputs:
+| hose PCI Controller
+| dev PCI Bus+Device+Function number
+| offset Configuration register number
+| value Address of the configuration register value
+| Return value:
+| 0 Successful
++-----------------------------------------------------------------------------*/
+int pci9054_read_config_dword(struct pci_controller *hose,
+ pci_dev_t dev, int offset, u32* value)
+{
+ unsigned long conAdrVal;
+ unsigned long val;
+
+ /* generate coded value for CON_ADR register */
+ conAdrVal = dev | (offset & 0xfc) | 0x80000000;
+
+ /* Load the CON_ADR (CAR) value first, then read from CON_DATA (CDR) */
+ *(unsigned long *)PCI_PRIMARY_CAR = conAdrVal;
+
+ /* Note: *pResult comes back as -1 if machine check happened */
+ val = in32r(PCI_PRIMARY_CDR);
+
+ *value = (unsigned long) val;
+
+ out32r(PCI_PRIMARY_CAR, 0);
+
+ if ((*(unsigned long *)0x50000304) & 0x60000000)
+ {
+ /* clear pci master/target abort bits */
+ *(unsigned long *)0x50000304 = *(unsigned long *)0x50000304;
+ }
+
+ return 0;
+}
+
+/*-----------------------------------------------------------------------------+
+| Subroutine: pci9054_write_config_dword
+| Description: Write a PCI configuration register.
+| Inputs:
+| hose PCI Controller
+| dev PCI Bus+Device+Function number
+| offset Configuration register number
+| Value Configuration register value
+| Return value:
+| 0 Successful
+| Updated for pass2 errata #6. Need to disable interrupts and clear the
+| PCICFGADR reg after writing the PCICFGDATA reg.
++-----------------------------------------------------------------------------*/
+int pci9054_write_config_dword(struct pci_controller *hose,
+ pci_dev_t dev, int offset, u32 value)
+{
+ unsigned long conAdrVal;
+
+ conAdrVal = dev | (offset & 0xfc) | 0x80000000;
+
+ *(unsigned long *)PCI_PRIMARY_CAR = conAdrVal;
+
+ out32r(PCI_PRIMARY_CDR, value);
+
+ out32r(PCI_PRIMARY_CAR, 0);
+
+ /* clear pci master/target abort bits */
+ *(unsigned long *)0x50000304 = *(unsigned long *)0x50000304;
+
+ return (0);
+}
+
+/*-----------------------------------------------------------------------
+ */
+
+#ifdef CONFIG_DASA_SIM
+static void pci_dasa_sim_config_pci9054(struct pci_controller *hose, pci_dev_t dev,
+ struct pci_config_table *_)
+{
+ unsigned int iobase;
+ unsigned short status = 0;
+ unsigned char timer;
+
+ /*
+ * Configure PLX PCI9054
+ */
+ pci_read_config_word(CFG_PCI9054_DEV_FN, PCI_COMMAND, &status);
+ status |= PCI_COMMAND_MASTER | PCI_COMMAND_IO | PCI_COMMAND_MEMORY;
+ pci_write_config_word(CFG_PCI9054_DEV_FN, PCI_COMMAND, status);
+
+ /* Check the latency timer for values >= 0x60.
+ */
+ pci_read_config_byte(CFG_PCI9054_DEV_FN, PCI_LATENCY_TIMER, &timer);
+ if (timer < 0x60)
+ {
+ pci_write_config_byte(CFG_PCI9054_DEV_FN, PCI_LATENCY_TIMER, 0x60);
+ }
+
+ /* Set I/O base register.
+ */
+ pci_write_config_dword(CFG_PCI9054_DEV_FN, PCI_BASE_ADDRESS_0, CFG_PCI9054_IOBASE);
+ pci_read_config_dword(CFG_PCI9054_DEV_FN, PCI_BASE_ADDRESS_0, &iobase);
+
+ pci9054_iobase = pci_mem_to_phys(CFG_PCI9054_DEV_FN, iobase & PCI_BASE_ADDRESS_MEM_MASK);
+
+ if (pci9054_iobase == 0xffffffff)
+ {
+ printf("Error: Can not set I/O base register.\n");
+ return;
+ }
+}
+#endif
+
+static struct pci_config_table pci9054_config_table[] = {
+#ifndef CONFIG_PCI_PNP
+ { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
+ PCI_BUS(CFG_ETH_DEV_FN), PCI_DEV(CFG_ETH_DEV_FN), PCI_FUNC(CFG_ETH_DEV_FN),
+ pci_cfgfunc_config_device, { CFG_ETH_IOBASE,
+ CFG_ETH_IOBASE,
+ PCI_COMMAND_IO | PCI_COMMAND_MASTER }},
+#ifdef CONFIG_DASA_SIM
+ { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
+ PCI_BUS(CFG_PCI9054_DEV_FN), PCI_DEV(CFG_PCI9054_DEV_FN), PCI_FUNC(CFG_PCI9054_DEV_FN),
+ pci_dasa_sim_config_pci9054 },
+#endif
+#endif
+ { }
+};
+
+static struct pci_controller pci9054_hose = {
+ config_table: pci9054_config_table,
+};
+
+void pci_init(void)
+{
+ struct pci_controller *hose = &pci9054_hose;
+
+ /*
+ * Register the hose
+ */
+ hose->first_busno = 0;
+ hose->last_busno = 0xff;
+
+ /* System memory space */
+ pci_set_region(hose->regions + 0,
+ 0x00000000, 0x00000000, 0x01000000,
+ PCI_REGION_MEM | PCI_REGION_MEMORY);
+
+ /* PCI Memory space */
+ pci_set_region(hose->regions + 1,
+ 0x00000000, 0xc0000000, 0x10000000,
+ PCI_REGION_MEM);
+
+ pci_set_ops(hose,
+ pci_hose_read_config_byte_via_dword,
+ pci_hose_read_config_word_via_dword,
+ pci9054_read_config_dword,
+ pci_hose_write_config_byte_via_dword,
+ pci_hose_write_config_word_via_dword,
+ pci9054_write_config_dword);
+
+ hose->region_count = 2;
+
+ pci_register_hose(hose);
+
+ hose->last_busno = pci_hose_scan(hose);
+}
--- /dev/null
+/*
+ * (C) Copyright 2001
+ * Stefan Roese, esd gmbh germany, stefan.roese@esd-electronics.com
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <asm/processor.h>
+#include <command.h>
+#include <cmd_boot.h>
+#include <malloc.h>
+
+/* ------------------------------------------------------------------------- */
+
+#if 0
+#define FPGA_DEBUG
+#endif
+
+/* fpga configuration data - generated by bin2cc */
+const unsigned char fpgadata[] =
+{
+#ifdef CONFIG_CPCI405_VER2
+# include "fpgadata_cpci4052.c"
+#else
+# include "fpgadata_cpci405.c"
+#endif
+};
+
+/*
+ * include common fpga code (for esd boards)
+ */
+#include "../common/fpga.c"
+
+
+/* Prototypes */
+int version2(void);
+int gunzip(void *, int, unsigned char *, int *);
+
+
+int board_pre_init (void)
+{
+#ifndef CONFIG_CPCI405_VER2
+ int index, len, i;
+ int status;
+#endif
+
+#ifdef FPGA_DEBUG
+ DECLARE_GLOBAL_DATA_PTR;
+
+ /* set up serial port with default baudrate */
+ (void) get_clocks ();
+ gd->baudrate = CONFIG_BAUDRATE;
+ serial_init ();
+ console_init_f();
+#endif
+
+ /*
+ * First pull fpga-prg pin low, to disable fpga logic (on version 2 board)
+ */
+ out32(IBM405GP_GPIO0_ODR, 0x00000000); /* no open drain pins */
+ out32(IBM405GP_GPIO0_TCR, CFG_FPGA_PRG); /* setup for output */
+ out32(IBM405GP_GPIO0_OR, CFG_FPGA_PRG); /* set output pins to high */
+ out32(IBM405GP_GPIO0_OR, 0); /* pull prg low */
+
+ /*
+ * Boot onboard FPGA
+ */
+#ifndef CONFIG_CPCI405_VER2
+ if (!version2()) {
+ status = fpga_boot((unsigned char *)fpgadata, sizeof(fpgadata));
+ if (status != 0) {
+ /* booting FPGA failed */
+#ifndef FPGA_DEBUG
+ DECLARE_GLOBAL_DATA_PTR;
+
+ /* set up serial port with default baudrate */
+ (void) get_clocks ();
+ gd->baudrate = CONFIG_BAUDRATE;
+ serial_init ();
+ console_init_f();
+#endif
+ printf("\nFPGA: Booting failed ");
+ switch (status) {
+ case ERROR_FPGA_PRG_INIT_LOW:
+ printf("(Timeout: INIT not low after asserting PROGRAM*)\n ");
+ break;
+ case ERROR_FPGA_PRG_INIT_HIGH:
+ printf("(Timeout: INIT not high after deasserting PROGRAM*)\n ");
+ break;
+ case ERROR_FPGA_PRG_DONE:
+ printf("(Timeout: DONE not high after programming FPGA)\n ");
+ break;
+ }
+
+ /* display infos on fpgaimage */
+ index = 15;
+ for (i=0; i<4; i++) {
+ len = fpgadata[index];
+ printf("FPGA: %s\n", &(fpgadata[index+1]));
+ index += len+3;
+ }
+ putc ('\n');
+ /* delayed reboot */
+ for (i=20; i>0; i--) {
+ printf("Rebooting in %2d seconds \r",i);
+ for (index=0;index<1000;index++)
+ udelay(1000);
+ }
+ putc ('\n');
+ do_reset(NULL, 0, 0, NULL);
+ }
+ }
+#endif /* !CONFIG_CPCI405_VER2 */
+
+ /*
+ * IRQ 0-15 405GP internally generated; active high; level sensitive
+ * IRQ 16 405GP internally generated; active low; level sensitive
+ * IRQ 17-24 RESERVED
+ * IRQ 25 (EXT IRQ 0) CAN0; active low; level sensitive
+ * IRQ 26 (EXT IRQ 1) CAN1 (+FPGA on CPCI4052) ; active low; level sensitive
+ * IRQ 27 (EXT IRQ 2) PCI SLOT 0; active low; level sensitive
+ * IRQ 28 (EXT IRQ 3) PCI SLOT 1; active low; level sensitive
+ * IRQ 29 (EXT IRQ 4) PCI SLOT 2; active low; level sensitive
+ * IRQ 30 (EXT IRQ 5) PCI SLOT 3; active low; level sensitive
+ * IRQ 31 (EXT IRQ 6) COMPACT FLASH; active high; level sensitive
+ */
+ mtdcr(uicsr, 0xFFFFFFFF); /* clear all ints */
+ mtdcr(uicer, 0x00000000); /* disable all ints */
+ mtdcr(uiccr, 0x00000000); /* set all to be non-critical*/
+ mtdcr(uicpr, 0xFFFFFF81); /* set int polarities */
+ mtdcr(uictr, 0x10000000); /* set int trigger levels */
+ mtdcr(uicvcr, 0x00000001); /* set vect base=0,INT0 highest priority*/
+ mtdcr(uicsr, 0xFFFFFFFF); /* clear all ints */
+
+ return 0;
+}
+
+
+/* ------------------------------------------------------------------------- */
+
+int ctermm2(void)
+{
+#ifdef CONFIG_CPCI405_VER2
+ return 0; /* no, board is cpci405 */
+#else
+ if ((*(unsigned char *)0xf0000400 == 0x00) &&
+ (*(unsigned char *)0xf0000401 == 0x01))
+ return 0; /* no, board is cpci405 */
+ else
+ return -1; /* yes, board is cterm-m2 */
+#endif
+}
+
+
+int cpci405_host(void)
+{
+ if (mfdcr(strap) & PSR_PCI_ARBIT_EN)
+ return -1; /* yes, board is cpci405 host */
+ else
+ return 0; /* no, board is cpci405 adapter */
+}
+
+
+int version2(void)
+{
+ unsigned long cntrl0Reg;
+ unsigned long value;
+
+ /*
+ * Setup GPIO pins (CS2/GPIO11 as GPIO)
+ */
+ cntrl0Reg = mfdcr(cntrl0);
+ mtdcr(cntrl0, cntrl0Reg | 0x02000000);
+
+ udelay(1000); /* wait some time before reading input */
+ value = in32(IBM405GP_GPIO0_IR) & 0x00100000; /* test GPIO11 */
+
+ /*
+ * Setup GPIO pins (CS2/GPIO11 as CS again)
+ */
+ mtdcr(cntrl0, cntrl0Reg);
+
+ if (value)
+ return 0; /* no, board is version 1.x */
+ else
+ return -1; /* yes, board is version 2.x */
+}
+
+
+int misc_init_f (void)
+{
+ return 0; /* dummy implementation */
+}
+
+
+int misc_init_r (void)
+{
+ DECLARE_GLOBAL_DATA_PTR;
+
+ bd_t *bd = gd->bd;
+ char * tmp; /* Temporary char pointer */
+
+#ifdef CONFIG_CPCI405_VER2
+ unsigned char *dst;
+ ulong len = sizeof(fpgadata);
+ int status;
+ int index;
+ int i;
+ unsigned long cntrl0Reg;
+
+ /*
+ * On CPCI-405 version 2 the environment is saved in eeprom!
+ * FPGA can be gzip compressed (malloc) and booted this late.
+ */
+
+ if (version2()) {
+ /*
+ * Setup GPIO pins (CS6+CS7 as GPIO)
+ */
+ cntrl0Reg = mfdcr(cntrl0);
+ mtdcr(cntrl0, cntrl0Reg | 0x00300000);
+
+ dst = malloc(CFG_FPGA_MAX_SIZE);
+ if (gunzip (dst, CFG_FPGA_MAX_SIZE, (uchar *)fpgadata, (int *)&len) != 0) {
+ printf ("GUNZIP ERROR - must RESET board to recover\n");
+ do_reset (NULL, 0, 0, NULL);
+ }
+
+ status = fpga_boot(dst, len);
+ if (status != 0) {
+ printf("\nFPGA: Booting failed ");
+ switch (status) {
+ case ERROR_FPGA_PRG_INIT_LOW:
+ printf("(Timeout: INIT not low after asserting PROGRAM*)\n ");
+ break;
+ case ERROR_FPGA_PRG_INIT_HIGH:
+ printf("(Timeout: INIT not high after deasserting PROGRAM*)\n ");
+ break;
+ case ERROR_FPGA_PRG_DONE:
+ printf("(Timeout: DONE not high after programming FPGA)\n ");
+ break;
+ }
+
+ /* display infos on fpgaimage */
+ index = 15;
+ for (i=0; i<4; i++) {
+ len = dst[index];
+ printf("FPGA: %s\n", &(dst[index+1]));
+ index += len+3;
+ }
+ putc ('\n');
+ /* delayed reboot */
+ for (i=20; i>0; i--) {
+ printf("Rebooting in %2d seconds \r",i);
+ for (index=0;index<1000;index++)
+ udelay(1000);
+ }
+ putc ('\n');
+ do_reset(NULL, 0, 0, NULL);
+ }
+
+ /* restore gpio/cs settings */
+ mtdcr(cntrl0, cntrl0Reg);
+
+ puts("FPGA: ");
+
+ /* display infos on fpgaimage */
+ index = 15;
+ for (i=0; i<4; i++) {
+ len = dst[index];
+ printf("%s ", &(dst[index+1]));
+ index += len+3;
+ }
+ putc ('\n');
+
+ free(dst);
+ }
+ else {
+ printf("\n*** U-Boot Version does not match Board Version!\n");
+ printf("*** CPCI-405 Version 2.x detected!\n");
+ printf("*** Please use correct U-Boot version (CPCI4052)!\n\n");
+ }
+
+#else /* CONFIG_CPCI405_VER2 */
+
+ /*
+ * Generate last byte of ip-addr from code-plug @ 0xf0000400
+ */
+ if (ctermm2()) {
+ char str[32];
+ unsigned char ipbyte = *(unsigned char *)0xf0000400;
+
+ /*
+ * Only overwrite ip-addr with allowed values
+ */
+ if ((ipbyte != 0x00) && (ipbyte != 0xff)) {
+ bd->bi_ip_addr = (bd->bi_ip_addr & 0xffffff00) | ipbyte;
+ sprintf(str, "%ld.%ld.%ld.%ld",
+ (bd->bi_ip_addr & 0xff000000) >> 24,
+ (bd->bi_ip_addr & 0x00ff0000) >> 16,
+ (bd->bi_ip_addr & 0x0000ff00) >> 8,
+ (bd->bi_ip_addr & 0x000000ff));
+ setenv("ipaddr", str);
+ }
+ }
+
+ if (version2()) {
+ printf("\n*** U-Boot Version does not match Board Version!\n");
+ printf("*** CPCI-405 Board Version 1.x detected!\n");
+ printf("*** Please use correct U-Boot version (CPCI405)!\n\n");
+ }
+
+#endif /* CONFIG_CPCI405_VER2 */
+
+ /*
+ * Write ethernet addr in NVRAM for VxWorks
+ */
+ tmp = (char *)CFG_NVRAM_BASE_ADDR + CFG_NVRAM_VXWORKS_OFFS;
+ memcpy( (char *)tmp, (char *)&bd->bi_enetaddr[0], 6 );
+ return (0);
+}
+
+
+/*
+ * Check Board Identity:
+ */
+
+int checkboard (void)
+{
+#ifndef CONFIG_CPCI405_VER2
+ int index;
+ int len;
+#endif
+ unsigned char str[64];
+ int i = getenv_r ("serial#", str, sizeof(str));
+
+ puts ("Board: ");
+
+ if (i == -1) {
+ puts ("### No HW ID - assuming CPCI405");
+ } else {
+ puts(str);
+ }
+
+ if (version2())
+ puts (" (Ver 2.x, ");
+ else
+ puts (" (Ver 1.x, ");
+
+#if 0
+ if ((*(unsigned short *)((unsigned long)CFG_FPGA_BASE_ADDR) + CFG_FPGA_STATUS)
+ & CFG_FPGA_STATUS_FLASH)
+ puts ("FLASH Bank A, ");
+ else
+ puts ("FLASH Bank B, ");
+#endif
+
+ if (ctermm2()) {
+ printf("CTERM-M2 - Id=0x%02x)", *(unsigned char *)0xf0000400);
+ } else {
+ if (cpci405_host()) {
+ puts ("PCI Host Version)");
+ } else {
+ puts ("PCI Adapter Version)");
+ }
+ }
+
+#ifndef CONFIG_CPCI405_VER2
+ puts ("\nFPGA: ");
+
+ /* display infos on fpgaimage */
+ index = 15;
+ for (i=0; i<4; i++) {
+ len = fpgadata[index];
+ printf("%s ", &(fpgadata[index+1]));
+ index += len+3;
+ }
+#endif
+
+ putc ('\n');
+
+ return 0;
+}
+
+/* ------------------------------------------------------------------------- */
+
+long int initdram (int board_type)
+{
+ unsigned long val;
+
+ mtdcr(memcfga, mem_mb0cf);
+ val = mfdcr(memcfgd);
+
+#if 0
+ printf("\nmb0cf=%x\n", val); /* test-only */
+ printf("strap=%x\n", mfdcr(strap)); /* test-only */
+#endif
+
+ return (4*1024*1024 << ((val & 0x000e0000) >> 17));
+}
+
+/* ------------------------------------------------------------------------- */
+
+int testdram (void)
+{
+ /* TODO: XXX XXX XXX */
+ printf ("test: 16 MB - ok\n");
+
+ return (0);
+}
+
+/* ------------------------------------------------------------------------- */
+
+#ifdef CONFIG_CPCI405_VER2
+#ifdef CONFIG_IDE_RESET
+
+void ide_set_reset(int on)
+{
+ volatile unsigned short *fpga_mode = (unsigned short *)CFG_FPGA_BASE_ADDR;
+
+ /*
+ * Assert or deassert CompactFlash Reset Pin
+ */
+ if (on) { /* assert RESET */
+ *fpga_mode &= ~(CFG_FPGA_MODE_CF_RESET);
+ } else { /* release RESET */
+ *fpga_mode |= CFG_FPGA_MODE_CF_RESET;
+ }
+}
+
+#endif /* CONFIG_IDE_RESET */
+#endif /* CONFIG_CPCI405_VER2 */
+
+/* ------------------------------------------------------------------------- */
--- /dev/null
+/*
+ * (C) Copyright 2002
+ * Stefan Roese, esd gmbh germany, stefan.roese@esd-electronics.com
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+
+#include <common.h>
+#include <asm/processor.h>
+
+
+long int fixed_sdram( void );
+
+int board_pre_init (void)
+{
+ uint reg;
+
+ /*--------------------------------------------------------------------
+ * Setup the external bus controller/chip selects
+ *-------------------------------------------------------------------*/
+ mtdcr( ebccfga, xbcfg );
+ reg = mfdcr( ebccfgd );
+ mtdcr( ebccfgd, reg | 0x04000000 ); /* Set ATC */
+
+ mtebc( pb0ap, 0x92015480 ); /* FLASH/SRAM */
+ mtebc( pb0cr, 0xFF87A000 ); /* BAS=0xff8 8MB R/W 16-bit */
+ /* test-only: other regs still missing... */
+
+ /*--------------------------------------------------------------------
+ * Setup the interrupt controller polarities, triggers, etc.
+ *-------------------------------------------------------------------*/
+ mtdcr( uic0sr, 0xffffffff ); /* clear all */
+ mtdcr( uic0er, 0x00000000 ); /* disable all */
+ mtdcr( uic0cr, 0x00000009 ); /* SMI & UIC1 crit are critical */
+ mtdcr( uic0pr, 0xfffffe13 ); /* per ref-board manual */
+ mtdcr( uic0tr, 0x01c00008 ); /* per ref-board manual */
+ mtdcr( uic0vr, 0x00000001 ); /* int31 highest, base=0x000 */
+ mtdcr( uic0sr, 0xffffffff ); /* clear all */
+
+ mtdcr( uic1sr, 0xffffffff ); /* clear all */
+ mtdcr( uic1er, 0x00000000 ); /* disable all */
+ mtdcr( uic1cr, 0x00000000 ); /* all non-critical */
+ mtdcr( uic1pr, 0xffffe0ff ); /* per ref-board manual */
+ mtdcr( uic1tr, 0x00ffc000 ); /* per ref-board manual */
+ mtdcr( uic1vr, 0x00000001 ); /* int31 highest, base=0x000 */
+ mtdcr( uic1sr, 0xffffffff ); /* clear all */
+
+ return 0;
+}
+
+
+
+int checkboard (void)
+{
+ sys_info_t sysinfo;
+ get_sys_info(&sysinfo);
+
+ printf("Board: esd CPCI-440\n");
+ printf("\tVCO: %lu MHz\n", sysinfo.freqVCOMhz/1000000);
+ printf("\tCPU: %lu MHz\n", sysinfo.freqProcessor/1000000);
+ printf("\tPLB: %lu MHz\n", sysinfo.freqPLB/1000000);
+ printf("\tOPB: %lu MHz\n", sysinfo.freqOPB/1000000);
+ printf("\tEPB: %lu MHz\n", sysinfo.freqEPB/1000000);
+ return (0);
+}
+
+
+long int initdram (int board_type)
+{
+ long dram_size = 0;
+
+ dram_size = fixed_sdram();
+ return dram_size;
+}
+
+
+/*************************************************************************
+ * fixed sdram init -- doesn't use serial presence detect.
+ *
+ * Assumes: 64 MB, non-ECC, non-registered
+ * PLB @ 133 MHz
+ *
+ ************************************************************************/
+long int fixed_sdram( void )
+{
+ uint reg;
+
+ /*--------------------------------------------------------------------
+ * Setup some default
+ *------------------------------------------------------------------*/
+ mtsdram( mem_uabba, 0x00000000 ); /* ubba=0 (default) */
+ mtsdram( mem_slio, 0x00000000 ); /* rdre=0 wrre=0 rarw=0 */
+ mtsdram( mem_devopt,0x00000000 ); /* dll=0 ds=0 (normal) */
+ mtsdram( mem_wddctr,0x40000000 ); /* wrcp=0 dcd=0 */
+ mtsdram( mem_clktr, 0x40000000 ); /* clkp=1 (90 deg wr) dcdt=0 */
+
+ /*--------------------------------------------------------------------
+ * Setup for board-specific specific mem
+ *------------------------------------------------------------------*/
+ /*
+ * Following for CAS Latency = 2.5 @ 133 MHz PLB
+ */
+ mtsdram( mem_b0cr, 0x00082001 );/* SDBA=0x000, 64MB, Mode 2, enabled*/
+ mtsdram( mem_tr0, 0x410a4012 );/* WR=2 WD=1 CL=2.5 PA=3 CP=4 LD=2 */
+ /* RA=10 RD=3 */
+ mtsdram( mem_tr1, 0x8080082f );/* SS=T2 SL=STAGE 3 CD=1 CT=0x02f */
+ mtsdram( mem_rtr, 0x08200000 );/* Rate 15.625 ns @ 133 MHz PLB */
+ mtsdram( mem_cfg1, 0x00000000 );/* Self-refresh exit, disable PM */
+ udelay( 400 ); /* Delay 200 usecs (min) */
+
+ /*--------------------------------------------------------------------
+ * Enable the controller, then wait for DCEN to complete
+ *------------------------------------------------------------------*/
+ mtsdram( mem_cfg0, 0x86000000 );/* DCEN=1, PMUD=1, 64-bit */
+ for(;;)
+ {
+ mfsdram( mem_mcsts, reg );
+ if( reg & 0x80000000 )
+ break;
+ }
+
+ return( 64 * 1024 * 1024 ); /* 64 MB */
+}
--- /dev/null
+/*
+* Copyright (C) 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
+*/
+
+#include <ppc_asm.tmpl>
+#include <config.h>
+
+/* General */
+#define TLB_VALID 0x00000200
+
+/* Supported page sizes */
+
+#define SZ_1K 0x00000000
+#define SZ_4K 0x00000010
+#define SZ_16K 0x00000020
+#define SZ_64K 0x00000030
+#define SZ_256K 0x00000040
+#define SZ_1M 0x00000050
+#define SZ_16M 0x00000070
+#define SZ_256M 0x00000090
+
+/* Storage attributes */
+#define SA_W 0x00000800 /* Write-through */
+#define SA_I 0x00000400 /* Caching inhibited */
+#define SA_M 0x00000200 /* Memory coherence */
+#define SA_G 0x00000100 /* Guarded */
+#define SA_E 0x00000080 /* Endian */
+
+/* Access control */
+#define AC_X 0x00000024 /* Execute */
+#define AC_W 0x00000012 /* Write */
+#define AC_R 0x00000009 /* Read */
+
+/* Some handy macros */
+
+#define EPN(e) ((e) & 0xfffffc00)
+#define TLB0(epn,sz) ( (EPN((epn)) | (sz) | TLB_VALID ) )
+#define TLB1(rpn,erpn) ( ((rpn)&0xfffffc00) | (erpn) )
+#define TLB2(a) ( (a)&0x00000fbf )
+
+#define tlbtab_start\
+ mflr r1 ;\
+ bl 0f ;
+
+#define tlbtab_end\
+ .long 0, 0, 0 ; \
+0: mflr r0 ; \
+ mtlr r1 ; \
+ blr ;
+
+#define tlbentry(epn,sz,rpn,erpn,attr)\
+ .long TLB0(epn,sz),TLB1(rpn,erpn),TLB2(attr)
+
+
+/**************************************************************************
+ * TLB TABLE
+ *
+ * This table is used by the cpu boot code to setup the initial tlb
+ * entries. Rather than make broad assumptions in the cpu source tree,
+ * this table lets each board set things up however they like.
+ *
+ * Pointer to the table is returned in r1
+ *
+ *************************************************************************/
+
+ .section .bootpg,"ax"
+ .globl tlbtab
+
+tlbtab:
+ tlbtab_start
+ tlbentry( 0xf0000000, SZ_256M, 0xf0000000, 1, AC_R|AC_W|AC_X|SA_G|SA_I)
+ tlbentry( CFG_PERIPHERAL_BASE, SZ_256M, 0x40000000, 1, AC_R|AC_W|SA_G|SA_I)
+ 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 )
+ tlbtab_end
+
+
--- /dev/null
+/*
+ * (C) Copyright 2001
+ * Stefan Roese, esd gmbh germany, stefan.roese@esd-electronics.com
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <asm/processor.h>
+#include <command.h>
+#include <cmd_boot.h>
+#include <malloc.h>
+#include <pci.h>
+#include <405gp_pci.h>
+
+/* ------------------------------------------------------------------------- */
+
+#if 0
+#define FPGA_DEBUG
+#endif
+
+#define PCI_RECONFIG_MAGIC 0x07081967
+
+
+struct pci_config_regs {
+ unsigned short command;
+ unsigned char latency_timer;
+ unsigned char int_line;
+ unsigned long bar1;
+ unsigned long bar2;
+ unsigned long magic;
+};
+
+
+/* fpga configuration data - generated by bin2cc */
+const unsigned char fpgadata[] =
+{
+#include "fpgadata.c"
+};
+
+/*
+ * include common fpga code (for esd boards)
+ */
+#include "../common/fpga.c"
+
+
+/* Prototypes */
+int gunzip(void *, int, unsigned char *, int *);
+
+
+int board_pre_init (void)
+{
+ unsigned long cntrl0Reg;
+
+ /*
+ * IRQ 0-15 405GP internally generated; active high; level sensitive
+ * IRQ 16 405GP internally generated; active low; level sensitive
+ * IRQ 17-24 RESERVED
+ * IRQ 25 (EXT IRQ 0) CAN0; active low; level sensitive
+ * IRQ 26 (EXT IRQ 1) CAN1; active low; level sensitive
+ * IRQ 27 (EXT IRQ 2) CAN2; active low; level sensitive
+ * IRQ 28 (EXT IRQ 3) CAN3; active low; level sensitive
+ * IRQ 29 (EXT IRQ 4) unused; active low; level sensitive
+ * IRQ 30 (EXT IRQ 5) FPGA Timestamp; active low; level sensitive
+ * IRQ 31 (EXT IRQ 6) PCI Reset; active low; level sensitive
+ */
+ mtdcr(uicsr, 0xFFFFFFFF); /* clear all ints */
+ mtdcr(uicer, 0x00000000); /* disable all ints */
+ mtdcr(uiccr, 0x00000000); /* set all to be non-critical*/
+ mtdcr(uicpr, 0xFFFFFF80); /* set int polarities */
+ mtdcr(uictr, 0x10000000); /* set int trigger levels */
+ mtdcr(uicvcr, 0x00000001); /* set vect base=0,INT0 highest priority*/
+ mtdcr(uicsr, 0xFFFFFFFF); /* clear all ints */
+
+ /*
+ * Setup GPIO pins (IRQ4/GPIO21 as GPIO)
+ */
+ cntrl0Reg = mfdcr(cntrl0);
+ mtdcr(cntrl0, cntrl0Reg | 0x00008000);
+
+ return 0;
+}
+
+
+/* ------------------------------------------------------------------------- */
+
+int misc_init_f (void)
+{
+ return 0; /* dummy implementation */
+}
+
+
+int misc_init_r (void)
+{
+ unsigned char *dst;
+ ulong len = sizeof(fpgadata);
+ int status;
+ int index;
+ int i;
+ struct pci_config_regs *pci_regs;
+
+ /*
+ * On PCI-405 the environment is saved in eeprom!
+ * FPGA can be gzip compressed (malloc) and booted this late.
+ */
+
+ dst = malloc(CFG_FPGA_MAX_SIZE);
+ if (gunzip (dst, CFG_FPGA_MAX_SIZE, (uchar *)fpgadata, (int *)&len) != 0) {
+ printf ("GUNZIP ERROR - must RESET board to recover\n");
+ do_reset (NULL, 0, 0, NULL);
+ }
+
+ status = fpga_boot(dst, len);
+ if (status != 0) {
+ printf("\nFPGA: Booting failed ");
+ switch (status) {
+ case ERROR_FPGA_PRG_INIT_LOW:
+ printf("(Timeout: INIT not low after asserting PROGRAM*)\n ");
+ break;
+ case ERROR_FPGA_PRG_INIT_HIGH:
+ printf("(Timeout: INIT not high after deasserting PROGRAM*)\n ");
+ break;
+ case ERROR_FPGA_PRG_DONE:
+ printf("(Timeout: DONE not high after programming FPGA)\n ");
+ break;
+ }
+
+ /* display infos on fpgaimage */
+ index = 15;
+ for (i=0; i<4; i++) {
+ len = dst[index];
+ printf("FPGA: %s\n", &(dst[index+1]));
+ index += len+3;
+ }
+ putc ('\n');
+ /* delayed reboot */
+ for (i=20; i>0; i--) {
+ printf("Rebooting in %2d seconds \r",i);
+ for (index=0;index<1000;index++)
+ udelay(1000);
+ }
+ putc ('\n');
+ do_reset(NULL, 0, 0, NULL);
+ }
+
+ puts("FPGA: ");
+
+ /* display infos on fpgaimage */
+ index = 15;
+ for (i=0; i<4; i++) {
+ len = dst[index];
+ printf("%s ", &(dst[index+1]));
+ index += len+3;
+ }
+ putc ('\n');
+
+ /*
+ * Rewrite pci config regs (only after soft-reset with magic set)
+ */
+ pci_regs = (struct pci_config_regs *)0x10;
+ if (pci_regs->magic == PCI_RECONFIG_MAGIC) {
+ puts("PCI: Found magic, rewriting config regs...\n");
+ pci_write_config_word(PCIDEVID_405GP, PCI_COMMAND,
+ pci_regs->command);
+ pci_write_config_byte(PCIDEVID_405GP, PCI_LATENCY_TIMER,
+ pci_regs->latency_timer);
+ pci_write_config_byte(PCIDEVID_405GP, PCI_INTERRUPT_LINE,
+ pci_regs->int_line);
+ pci_write_config_dword(PCIDEVID_405GP, PCI_BASE_ADDRESS_1,
+ pci_regs->bar1);
+ pci_write_config_dword(PCIDEVID_405GP, PCI_BASE_ADDRESS_2,
+ pci_regs->bar2);
+ }
+ pci_regs->magic = 0; /* clear magic again */
+
+#if 0 /* test-only */
+ pci_read_config_word(PCIDEVID_405GP, PCI_COMMAND, &(pci_regs->command));
+ pci_read_config_byte(PCIDEVID_405GP, PCI_LATENCY_TIMER, &(pci_regs->latency_timer));
+ pci_read_config_byte(PCIDEVID_405GP, PCI_INTERRUPT_LINE, &(pci_regs->int_line));
+ pci_read_config_dword(PCIDEVID_405GP, PCI_BASE_ADDRESS_1, &(pci_regs->bar1));
+ pci_read_config_dword(PCIDEVID_405GP, PCI_BASE_ADDRESS_2, &(pci_regs->bar2));
+ pci_regs->magic = PCI_RECONFIG_MAGIC; /* set magic */
+#endif
+
+ free(dst);
+ return (0);
+}
+
+
+/*
+ * Check Board Identity:
+ */
+
+int checkboard (void)
+{
+ unsigned char str[64];
+ int i = getenv_r ("serial#", str, sizeof(str));
+
+ puts ("Board: ");
+
+ if (i == -1) {
+ puts ("### No HW ID - assuming CPCI405");
+ } else {
+ puts (str);
+ }
+ putc ('\n');
+
+ return 0;
+}
+
+/* ------------------------------------------------------------------------- */
+
+long int initdram (int board_type)
+{
+ unsigned long val;
+
+ mtdcr(memcfga, mem_mb0cf);
+ val = mfdcr(memcfgd);
+
+#if 0
+ printf("\nmb0cf=%x\n", val); /* test-only */
+ printf("strap=%x\n", mfdcr(strap)); /* test-only */
+#endif
+
+ return (4*1024*1024 << ((val & 0x000e0000) >> 17));
+}
+
+/* ------------------------------------------------------------------------- */
+
+int testdram (void)
+{
+ /* TODO: XXX XXX XXX */
+ printf ("test: 16 MB - ok\n");
+
+ return (0);
+}
+
+/* ------------------------------------------------------------------------- */
--- /dev/null
+#include <common.h>
+#include <malloc.h>
+#include <galileo/gt64260R.h>
+#include <galileo/core.h>
+#include <asm/cache.h>
+#include "eth.h"
+#include "eth_addrtbl.h"
+
+#define TRUE 1
+#define FALSE 0
+
+#define PRINTF printf
+
+#ifdef CONFIG_GT_USE_MAC_HASH_TABLE
+
+static u32 addressTableHashMode[ GAL_ETH_DEVS ] = { 0, };
+static u32 addressTableHashSize[ GAL_ETH_DEVS ] = { 0, };
+static addrTblEntry *addressTableBase[ GAL_ETH_DEVS ] = { 0, };
+static void *realAddrTableBase[ GAL_ETH_DEVS ] = { 0, };
+
+static const u32 hashLength[ 2 ] = {
+ (0x8000), /* 8K * 4 entries */
+ (0x8000/16), /* 512 * 4 entries */
+};
+
+/* Initialize the address table for a port, if needed */
+unsigned int initAddressTable( u32 port, u32 hashMode, u32 hashSizeSelector)
+{
+ unsigned int tableBase;
+
+ if( port < 0 || port >= GAL_ETH_DEVS ) {
+ printf("%s: Invalid port number %d\n", __FUNCTION__, port );
+ return 0;
+ }
+
+ if (hashMode > 1) {
+ printf("%s: Invalid Hash Mode %d\n", __FUNCTION__, port );
+ return 0;
+ }
+
+ if ( realAddrTableBase[port] &&
+ ( addressTableHashSize[port] != hashSizeSelector )) {
+ /* we have been here before,
+ * but now we want a different sized table
+ */
+ free( realAddrTableBase[port] );
+ realAddrTableBase[port] = 0;
+ addressTableBase[port] = 0;
+
+ }
+
+ tableBase = (unsigned int)addressTableBase[port];
+ /* we get called for every probe, so only do this once */
+ if ( !tableBase ) {
+ int bytes = hashLength[hashSizeSelector] * sizeof(addrTblEntry);
+
+ tableBase = (unsigned int)realAddrTableBase[port] = malloc(bytes+64);
+
+ if(!tableBase)
+ {
+ printf("%s: alloc memory failed \n", __FUNCTION__);
+ return 0;
+ }
+
+ /* align to octal byte */
+ if(tableBase&63) tableBase=(tableBase+63) & ~63;
+
+ addressTableHashMode[port] = hashMode;
+ addressTableHashSize[port] = hashSizeSelector;
+ addressTableBase[port] = (addrTblEntry *)tableBase;
+
+ memset((void *)tableBase,0,bytes);
+ }
+
+ return tableBase;
+}
+
+/*
+ * ----------------------------------------------------------------------------
+ * This function will calculate the hash function of the address.
+ * depends on the hash mode and hash size.
+ * Inputs
+ * macH - the 2 most significant bytes of the MAC address.
+ * macL - the 4 least significant bytes of the MAC address.
+ * hashMode - hash mode 0 or hash mode 1.
+ * hashSizeSelector - indicates number of hash table entries (0=0x8000,1=0x800)
+ * Outputs
+ * return the calculated entry.
+ */
+u32
+hashTableFunction( u32 macH, u32 macL, u32 HashSize, u32 hash_mode)
+{
+ u32 hashResult;
+ u32 addrH;
+ u32 addrL;
+ u32 addr0;
+ u32 addr1;
+ u32 addr2;
+ u32 addr3;
+ u32 addrHSwapped;
+ u32 addrLSwapped;
+
+
+ addrH = NIBBLE_SWAPPING_16_BIT( macH );
+ addrL = NIBBLE_SWAPPING_32_BIT( macL );
+
+ addrHSwapped = FLIP_4_BITS( addrH & 0xf )
+ + ((FLIP_4_BITS( (addrH >> 4) & 0xf)) << 4)
+ + ((FLIP_4_BITS( (addrH >> 8) & 0xf)) << 8)
+ + ((FLIP_4_BITS( (addrH >> 12) & 0xf)) << 12);
+
+ addrLSwapped = FLIP_4_BITS( addrL & 0xf )
+ + ((FLIP_4_BITS( (addrL >> 4) & 0xf)) << 4)
+ + ((FLIP_4_BITS( (addrL >> 8) & 0xf)) << 8)
+ + ((FLIP_4_BITS( (addrL >> 12) & 0xf)) << 12)
+ + ((FLIP_4_BITS( (addrL >> 16) & 0xf)) << 16)
+ + ((FLIP_4_BITS( (addrL >> 20) & 0xf)) << 20)
+ + ((FLIP_4_BITS( (addrL >> 24) & 0xf)) << 24)
+ + ((FLIP_4_BITS( (addrL >> 28) & 0xf)) << 28);
+
+ addrH = addrHSwapped;
+ addrL = addrLSwapped;
+
+ if( hash_mode == 0 ) {
+ addr0 = (addrL >> 2) & 0x03f;
+ addr1 = (addrL & 0x003) | ((addrL >> 8) & 0x7f) << 2;
+ addr2 = (addrL >> 15) & 0x1ff;
+ addr3 = ((addrL >> 24) & 0x0ff) | ((addrH & 1) << 8);
+ } else {
+ addr0 = FLIP_6_BITS( addrL & 0x03f );
+ addr1 = FLIP_9_BITS( ((addrL >> 6) & 0x1ff));
+ addr2 = FLIP_9_BITS( (addrL >> 15) & 0x1ff);
+ addr3 = FLIP_9_BITS( (((addrL >> 24) & 0x0ff) | ((addrH & 0x1) << 8)));
+ }
+
+ hashResult = (addr0 << 9) | (addr1 ^ addr2 ^ addr3);
+
+ if( HashSize == _8K_TABLE ) {
+ hashResult = hashResult & 0xffff;
+ } else {
+ hashResult = hashResult & 0x07ff;
+ }
+
+ return( hashResult );
+}
+
+
+/*
+ * ----------------------------------------------------------------------------
+ * This function will add an entry to the address table.
+ * depends on the hash mode and hash size that was initialized.
+ * Inputs
+ * port - ETHERNET port number.
+ * macH - the 2 most significant bytes of the MAC address.
+ * macL - the 4 least significant bytes of the MAC address.
+ * skip - if 1, skip this address.
+ * rd - the RD field in the address table.
+ * Outputs
+ * address table entry is added.
+ * TRUE if success.
+ * FALSE if table full
+ */
+int
+addAddressTableEntry(
+ u32 port,
+ u32 macH,
+ u32 macL,
+ u32 rd,
+ u32 skip )
+{
+ addrTblEntry *entry;
+ u32 newHi;
+ u32 newLo;
+ u32 i;
+
+ newLo = (((macH >> 4) & 0xf) << 15)
+ | (((macH >> 0) & 0xf) << 11)
+ | (((macH >> 12) & 0xf) << 7)
+ | (((macH >> 8) & 0xf) << 3)
+ | (((macL >> 20) & 0x1) << 31)
+ | (((macL >> 16) & 0xf) << 27)
+ | (((macL >> 28) & 0xf) << 23)
+ | (((macL >> 24) & 0xf) << 19)
+ | (skip << SKIP_BIT) | (rd << 2) | VALID;
+
+ newHi = (((macL >> 4) & 0xf) << 15)
+ | (((macL >> 0) & 0xf) << 11)
+ | (((macL >> 12) & 0xf) << 7)
+ | (((macL >> 8) & 0xf) << 3)
+ | (((macL >> 21) & 0x7) << 0);
+
+ /*
+ * Pick the appropriate table, start scanning for free/reusable
+ * entries at the index obtained by hashing the specified MAC address
+ */
+ entry = addressTableBase[port];
+ entry += hashTableFunction( macH, macL, addressTableHashSize[port],
+ addressTableHashMode[port] );
+ for( i = 0; i < HOP_NUMBER; i++, entry++ ) {
+ if( !(entry->lo & VALID) /*|| (entry->lo & SKIP)*/ ) {
+ break;
+ } else { /* if same address put in same position */
+ if( ((entry->lo & 0xfffffff8) == (newLo & 0xfffffff8))
+ && (entry->hi == newHi) )
+ {
+ break;
+ }
+ }
+ }
+
+ if( i == HOP_NUMBER ) {
+ PRINTF( "addGT64260addressTableEntry: table section is full\n" );
+ return( FALSE );
+ }
+
+ /*
+ * Update the selected entry
+ */
+ entry->hi = newHi;
+ entry->lo = newLo;
+ DCACHE_FLUSH_N_SYNC( (u32)entry, MAC_ENTRY_SIZE );
+ return( TRUE );
+}
+
+#endif /* CONFIG_GT_USE_MAC_HASH_TABLE */
--- /dev/null
+/* PCI.c - PCI functions */
+
+/* Copyright - Galileo technology. */
+
+#include <common.h>
+#include <pci.h>
+
+#include <galileo/pci.h>
+
+static const unsigned char pci_irq_swizzle[2][PCI_MAX_DEVICES] = {
+#ifdef CONFIG_ZUMA_V2
+ {0,0,0,0,0,0,0,29, [8 ... PCI_MAX_DEVICES-1]=0},
+ {0,0,0,0,0,0,0,28, [8 ... PCI_MAX_DEVICES-1]=0}
+#else /* EVB??? This is a guess */
+ {0,0,0,0,0,0,0,27,27, [9 ... PCI_MAX_DEVICES-1]=0},
+ {0,0,0,0,0,0,0,29,29, [9 ... PCI_MAX_DEVICES-1]=0}
+#endif
+};
+
+static const unsigned int pci_p2p_configuration_reg[]={
+ PCI_0P2P_CONFIGURATION, PCI_1P2P_CONFIGURATION};
+
+static const unsigned int pci_configuration_address[]={
+ PCI_0CONFIGURATION_ADDRESS, PCI_1CONFIGURATION_ADDRESS};
+
+static const unsigned int pci_configuration_data[]={
+ PCI_0CONFIGURATION_DATA_VIRTUAL_REGISTER,
+ PCI_1CONFIGURATION_DATA_VIRTUAL_REGISTER};
+
+static const unsigned int pci_error_cause_reg[]={
+ PCI_0ERROR_CAUSE, PCI_1ERROR_CAUSE};
+
+static const unsigned int pci_arbiter_control[]={
+ PCI_0ARBITER_CONTROL, PCI_1ARBITER_CONTROL};
+
+static const unsigned int pci_snoop_control_base_0_low[]={
+ PCI_0SNOOP_CONTROL_BASE_0_LOW, PCI_1SNOOP_CONTROL_BASE_0_LOW};
+static const unsigned int pci_snoop_control_top_0[]={
+ PCI_0SNOOP_CONTROL_TOP_0, PCI_1SNOOP_CONTROL_TOP_0};
+
+static const unsigned int pci_access_control_base_0_low[]={
+ PCI_0ACCESS_CONTROL_BASE_0_LOW, PCI_1ACCESS_CONTROL_BASE_0_LOW};
+static const unsigned int pci_access_control_top_0[]={
+ PCI_0ACCESS_CONTROL_TOP_0, PCI_1ACCESS_CONTROL_TOP_0};
+
+static const unsigned int pci_scs_bank_size[2][4] = {
+ {PCI_0SCS_0_BANK_SIZE, PCI_0SCS_1_BANK_SIZE,
+ PCI_0SCS_2_BANK_SIZE, PCI_0SCS_3_BANK_SIZE},
+ {PCI_1SCS_0_BANK_SIZE, PCI_1SCS_1_BANK_SIZE,
+ PCI_1SCS_2_BANK_SIZE, PCI_1SCS_3_BANK_SIZE}};
+
+static const unsigned int pci_p2p_configuration[] = {
+ PCI_0P2P_CONFIGURATION, PCI_1P2P_CONFIGURATION};
+
+/********************************************************************
+* pciWriteConfigReg - Write to a PCI configuration register
+* - Make sure the GT is configured as a master before writing
+* to another device on the PCI.
+* - The function takes care of Big/Little endian conversion.
+*
+*
+* Inputs: unsigned int regOffset: The register offset as it apears in the GT spec
+* (or any other PCI device spec)
+* pciDevNum: The device number needs to be addressed.
+*
+* Configuration Address 0xCF8:
+*
+* 31 30 24 23 16 15 11 10 8 7 2 0 <=bit Number
+* |congif|Reserved| Bus |Device|Function|Register|00|
+* |Enable| |Number|Number| Number | Number | | <=field Name
+*
+*********************************************************************/
+void pciWriteConfigReg(PCI_HOST host, unsigned int regOffset,unsigned int pciDevNum,unsigned int data)
+{
+ volatile unsigned int DataForAddrReg;
+ unsigned int functionNum;
+ unsigned int busNum = 0;
+ unsigned int addr;
+
+ if(pciDevNum > 32) /* illegal device Number */
+ return;
+ if(pciDevNum == SELF) /* configure our configuration space. */
+ {
+ pciDevNum = (GTREGREAD(pci_p2p_configuration_reg[host]) >> 24) & 0x1f;
+ busNum = GTREGREAD(pci_p2p_configuration_reg[host]) & 0xff0000;
+ }
+ functionNum = regOffset & 0x00000700;
+ pciDevNum = pciDevNum << 11;
+ regOffset = regOffset & 0xfc;
+ DataForAddrReg = ( regOffset | pciDevNum | functionNum | busNum) | BIT31;
+ GT_REG_WRITE(pci_configuration_address[host],DataForAddrReg);
+ GT_REG_READ(pci_configuration_address[host], &addr);
+ if (addr != DataForAddrReg) return;
+ GT_REG_WRITE(pci_configuration_data[host],data);
+}
+
+/********************************************************************
+* pciReadConfigReg - Read from a PCI0 configuration register
+* - Make sure the GT is configured as a master before reading
+* from another device on the PCI.
+* - The function takes care of Big/Little endian conversion.
+* INPUTS: regOffset: The register offset as it apears in the GT spec (or PCI
+* spec)
+* pciDevNum: The device number needs to be addressed.
+* RETURNS: data , if the data == 0xffffffff check the master abort bit in the
+* cause register to make sure the data is valid
+*
+* Configuration Address 0xCF8:
+*
+* 31 30 24 23 16 15 11 10 8 7 2 0 <=bit Number
+* |congif|Reserved| Bus |Device|Function|Register|00|
+* |Enable| |Number|Number| Number | Number | | <=field Name
+*
+*********************************************************************/
+unsigned int pciReadConfigReg (PCI_HOST host, unsigned int regOffset,unsigned int pciDevNum)
+{
+ volatile unsigned int DataForAddrReg;
+ unsigned int data;
+ unsigned int functionNum;
+ unsigned int busNum = 0;
+
+ if(pciDevNum > 32) /* illegal device Number */
+ return 0xffffffff;
+ if(pciDevNum == SELF) /* configure our configuration space. */
+ {
+ pciDevNum = (GTREGREAD(pci_p2p_configuration_reg[host]) >> 24) & 0x1f;
+ busNum = GTREGREAD(pci_p2p_configuration_reg[host]) & 0xff0000;
+ }
+ functionNum = regOffset & 0x00000700;
+ pciDevNum = pciDevNum << 11;
+ regOffset = regOffset & 0xfc;
+ DataForAddrReg = (regOffset | pciDevNum | functionNum | busNum) | BIT31 ;
+ GT_REG_WRITE(pci_configuration_address[host],DataForAddrReg);
+ GT_REG_READ(pci_configuration_address[host], &data);
+ if (data != DataForAddrReg)
+ return 0xffffffff;
+ GT_REG_READ(pci_configuration_data[host], &data);
+ return data;
+}
+
+/********************************************************************
+* pciOverBridgeWriteConfigReg - Write to a PCI configuration register where
+* the agent is placed on another Bus. For more
+* information read P2P in the PCI spec.
+*
+* Inputs: unsigned int regOffset - The register offset as it apears in the
+* GT spec (or any other PCI device spec).
+* unsigned int pciDevNum - The device number needs to be addressed.
+* unsigned int busNum - On which bus does the Target agent connect
+* to.
+* unsigned int data - data to be written.
+*
+* Configuration Address 0xCF8:
+*
+* 31 30 24 23 16 15 11 10 8 7 2 0 <=bit Number
+* |congif|Reserved| Bus |Device|Function|Register|01|
+* |Enable| |Number|Number| Number | Number | | <=field Name
+*
+* The configuration Address is configure as type-I (bits[1:0] = '01') due to
+* PCI spec referring to P2P.
+*
+*********************************************************************/
+void pciOverBridgeWriteConfigReg(PCI_HOST host,
+ unsigned int regOffset,
+ unsigned int pciDevNum,
+ unsigned int busNum,unsigned int data)
+{
+ unsigned int DataForReg;
+ unsigned int functionNum;
+
+ functionNum = regOffset & 0x00000700;
+ pciDevNum = pciDevNum << 11;
+ regOffset = regOffset & 0xff;
+ busNum = busNum << 16;
+ if(pciDevNum == SELF) /* This board */
+ {
+ DataForReg = ( regOffset | pciDevNum | functionNum) | BIT0;
+ }
+ else
+ {
+ DataForReg = ( regOffset | pciDevNum | functionNum | busNum) |
+ BIT31 | BIT0;
+ }
+ GT_REG_WRITE(pci_configuration_address[host],DataForReg);
+ if(pciDevNum == SELF) /* This board */
+ {
+ GT_REG_WRITE(pci_configuration_data[host],data);
+ }
+ else /* configuration Transaction over the pci. */
+ {
+ /* The PCI is working in LE Mode So it swap the Data. */
+ GT_REG_WRITE(pci_configuration_data[host],WORD_SWAP(data));
+ }
+}
+
+
+/********************************************************************
+* pciOverBridgeReadConfigReg - Read from a PCIn configuration register where
+* the agent target locate on another PCI bus.
+* - Make sure the GT is configured as a master
+* before reading from another device on the PCI.
+* - The function takes care of Big/Little endian
+* conversion.
+* INPUTS: regOffset: The register offset as it apears in the GT spec (or PCI
+* spec). (configuration register offset.)
+* pciDevNum: The device number needs to be addressed.
+* busNum: the Bus number where the agent is place.
+* RETURNS: data , if the data == 0xffffffff check the master abort bit in the
+* cause register to make sure the data is valid
+*
+* Configuration Address 0xCF8:
+*
+* 31 30 24 23 16 15 11 10 8 7 2 0 <=bit Number
+* |congif|Reserved| Bus |Device|Function|Register|01|
+* |Enable| |Number|Number| Number | Number | | <=field Name
+*
+*********************************************************************/
+unsigned int pciOverBridgeReadConfigReg(PCI_HOST host,
+ unsigned int regOffset,
+ unsigned int pciDevNum,
+ unsigned int busNum)
+{
+ unsigned int DataForReg;
+ unsigned int data;
+ unsigned int functionNum;
+
+ functionNum = regOffset & 0x00000700;
+ pciDevNum = pciDevNum << 11;
+ regOffset = regOffset & 0xff;
+ busNum = busNum << 16;
+ if (pciDevNum == SELF) /* This board */
+ {
+ DataForReg = (regOffset | pciDevNum | functionNum) | BIT31 ;
+ }
+ else /* agent on another bus */
+ {
+ DataForReg = (regOffset | pciDevNum | functionNum | busNum) |
+ BIT0 | BIT31 ;
+ }
+ GT_REG_WRITE(pci_configuration_address[host],DataForReg);
+ if (pciDevNum == SELF) /* This board */
+ {
+ GT_REG_READ(pci_configuration_data[host], &data);
+ return data;
+ }
+ else /* The PCI is working in LE Mode So it swap the Data. */
+ {
+ GT_REG_READ(pci_configuration_data[host], &data);
+ return WORD_SWAP(data);
+ }
+}
+
+/********************************************************************
+* pciGetRegOffset - Gets the register offset for this region config.
+*
+* INPUT: Bus, Region - The bus and region we ask for its base address.
+* OUTPUT: N/A
+* RETURNS: PCI register base address
+*********************************************************************/
+static unsigned int pciGetRegOffset(PCI_HOST host, PCI_REGION region)
+{
+ switch (host)
+ {
+ case PCI_HOST0:
+ switch(region) {
+ case PCI_IO: return PCI_0I_O_LOW_DECODE_ADDRESS;
+ case PCI_REGION0: return PCI_0MEMORY0_LOW_DECODE_ADDRESS;
+ case PCI_REGION1: return PCI_0MEMORY1_LOW_DECODE_ADDRESS;
+ case PCI_REGION2: return PCI_0MEMORY2_LOW_DECODE_ADDRESS;
+ case PCI_REGION3: return PCI_0MEMORY3_LOW_DECODE_ADDRESS;
+ }
+ case PCI_HOST1:
+ switch(region) {
+ case PCI_IO: return PCI_1I_O_LOW_DECODE_ADDRESS;
+ case PCI_REGION0: return PCI_1MEMORY0_LOW_DECODE_ADDRESS;
+ case PCI_REGION1: return PCI_1MEMORY1_LOW_DECODE_ADDRESS;
+ case PCI_REGION2: return PCI_1MEMORY2_LOW_DECODE_ADDRESS;
+ case PCI_REGION3: return PCI_1MEMORY3_LOW_DECODE_ADDRESS;
+ }
+ }
+ return PCI_0MEMORY0_LOW_DECODE_ADDRESS;
+}
+
+static unsigned int pciGetRemapOffset(PCI_HOST host, PCI_REGION region)
+{
+ switch (host)
+ {
+ case PCI_HOST0:
+ switch(region) {
+ case PCI_IO: return PCI_0I_O_ADDRESS_REMAP;
+ case PCI_REGION0: return PCI_0MEMORY0_ADDRESS_REMAP;
+ case PCI_REGION1: return PCI_0MEMORY1_ADDRESS_REMAP;
+ case PCI_REGION2: return PCI_0MEMORY2_ADDRESS_REMAP;
+ case PCI_REGION3: return PCI_0MEMORY3_ADDRESS_REMAP;
+ }
+ case PCI_HOST1:
+ switch(region) {
+ case PCI_IO: return PCI_1I_O_ADDRESS_REMAP;
+ case PCI_REGION0: return PCI_1MEMORY0_ADDRESS_REMAP;
+ case PCI_REGION1: return PCI_1MEMORY1_ADDRESS_REMAP;
+ case PCI_REGION2: return PCI_1MEMORY2_ADDRESS_REMAP;
+ case PCI_REGION3: return PCI_1MEMORY3_ADDRESS_REMAP;
+ }
+ }
+ return PCI_0MEMORY0_ADDRESS_REMAP;
+}
+
+bool pciMapSpace(PCI_HOST host, PCI_REGION region, unsigned int remapBase, unsigned int bankBase,unsigned int bankLength)
+{
+ unsigned int low=0xfff;
+ unsigned int high=0x0;
+ unsigned int regOffset=pciGetRegOffset(host, region);
+ unsigned int remapOffset=pciGetRemapOffset(host, region);
+
+ if(bankLength!=0) {
+ low = (bankBase >> 20) & 0xfff;
+ high=((bankBase+bankLength)>>20)-1;
+ }
+
+ GT_REG_WRITE(regOffset, low | (1<<24)); /* no swapping */
+ GT_REG_WRITE(regOffset+8, high);
+
+ if(bankLength!=0) { /* must do AFTER writing maps */
+ GT_REG_WRITE(remapOffset, remapBase>>20); /* sorry, 32 bits only.
+ dont support upper 32
+ in this driver */
+ }
+ return true;
+}
+
+unsigned int pciGetSpaceBase(PCI_HOST host, PCI_REGION region)
+{
+ unsigned int low;
+ unsigned int regOffset=pciGetRegOffset(host, region);
+ GT_REG_READ(regOffset,&low);
+ return (low&0xfff)<<20;
+}
+
+unsigned int pciGetSpaceSize(PCI_HOST host, PCI_REGION region)
+{
+ unsigned int low,high;
+ unsigned int regOffset=pciGetRegOffset(host, region);
+ GT_REG_READ(regOffset,&low);
+ GT_REG_READ(regOffset+8,&high);
+ high&=0xfff;
+ low&=0xfff;
+ if(high<=low) return 0;
+ return (high+1-low)<<20;
+}
+
+/********************************************************************
+* pciMapMemoryBank - Maps PCI_host memory bank "bank" for the slave.
+*
+* Inputs: base and size of PCI SCS
+*********************************************************************/
+void pciMapMemoryBank(PCI_HOST host, MEMORY_BANK bank, unsigned int pciDramBase,unsigned int pciDramSize)
+{
+ pciDramBase = pciDramBase & 0xfffff000;
+ pciDramBase = pciDramBase | (pciReadConfigReg(host,
+ PCI_SCS_0_BASE_ADDRESS + 4*bank,SELF) & 0x00000fff);
+ pciWriteConfigReg(host,PCI_SCS_0_BASE_ADDRESS + 4*bank,SELF,pciDramBase);
+ if(pciDramSize == 0)
+ pciDramSize ++;
+ GT_REG_WRITE(pci_scs_bank_size[host][bank], pciDramSize-1);
+}
+
+
+/********************************************************************
+* pciSetRegionFeatures - This function modifys one of the 8 regions with
+* feature bits given as an input.
+* - Be advised to check the spec before modifying them.
+* Inputs: PCI_PROTECT_REGION region - one of the eight regions.
+* unsigned int features - See file: pci.h there are defintion for those
+* region features.
+* unsigned int baseAddress - The region base Address.
+* unsigned int topAddress - The region top Address.
+* Returns: false if one of the parameters is erroneous true otherwise.
+*********************************************************************/
+bool pciSetRegionFeatures(PCI_HOST host, PCI_ACCESS_REGIONS region,unsigned int features,
+ unsigned int baseAddress,unsigned int regionLength)
+{
+ unsigned int accessLow;
+ unsigned int accessHigh;
+ unsigned int accessTop = baseAddress + regionLength;
+
+ if(regionLength == 0) /* close the region. */
+ {
+ pciDisableAccessRegion(host, region);
+ return true;
+ }
+ /* base Address is store is bits [11:0] */
+ accessLow = (baseAddress & 0xfff00000) >> 20;
+ /* All the features are update according to the defines in pci.h (to be on
+ the safe side we disable bits: [11:0] */
+ accessLow = accessLow | (features & 0xfffff000);
+ /* write to the Low Access Region register */
+ GT_REG_WRITE( pci_access_control_base_0_low[host] + 0x10*region,accessLow);
+
+ accessHigh = (accessTop & 0xfff00000) >> 20;
+
+ /* write to the High Access Region register */
+ GT_REG_WRITE(pci_access_control_top_0[host] + 0x10*region,accessHigh - 1);
+ return true;
+}
+
+/********************************************************************
+* pciDisableAccessRegion - Disable The given Region by writing MAX size
+* to its low Address and MIN size to its high Address.
+*
+* Inputs: PCI_ACCESS_REGIONS region - The region we to be Disabled.
+* Returns: N/A.
+*********************************************************************/
+void pciDisableAccessRegion(PCI_HOST host, PCI_ACCESS_REGIONS region)
+{
+ /* writing back the registers default values. */
+ GT_REG_WRITE(pci_access_control_base_0_low[host] + 0x10*region,0x01001fff);
+ GT_REG_WRITE(pci_access_control_top_0[host] + 0x10*region,0);
+}
+
+/********************************************************************
+* pciArbiterEnable - Enables PCI-0`s Arbitration mechanism.
+*
+* Inputs: N/A
+* Returns: true.
+*********************************************************************/
+bool pciArbiterEnable(PCI_HOST host)
+{
+ unsigned int regData;
+
+ GT_REG_READ(pci_arbiter_control[host],®Data);
+ GT_REG_WRITE(pci_arbiter_control[host],regData | BIT31);
+ return true;
+}
+
+/********************************************************************
+* pciArbiterDisable - Disable PCI-0`s Arbitration mechanism.
+*
+* Inputs: N/A
+* Returns: true
+*********************************************************************/
+bool pciArbiterDisable(PCI_HOST host)
+{
+ unsigned int regData;
+
+ GT_REG_READ(pci_arbiter_control[host],®Data);
+ GT_REG_WRITE(pci_arbiter_control[host],regData & 0x7fffffff);
+ return true;
+}
+
+/********************************************************************
+* pciParkingDisable - Park on last option disable, with this function you can
+* disable the park on last mechanism for each agent.
+* disabling this option for all agents results parking
+* on the internal master.
+*
+* Inputs: PCI_AGENT_PARK internalAgent - parking Disable for internal agent.
+* PCI_AGENT_PARK externalAgent0 - parking Disable for external#0 agent.
+* PCI_AGENT_PARK externalAgent1 - parking Disable for external#1 agent.
+* PCI_AGENT_PARK externalAgent2 - parking Disable for external#2 agent.
+* PCI_AGENT_PARK externalAgent3 - parking Disable for external#3 agent.
+* PCI_AGENT_PARK externalAgent4 - parking Disable for external#4 agent.
+* PCI_AGENT_PARK externalAgent5 - parking Disable for external#5 agent.
+* Returns: true
+*********************************************************************/
+bool pciParkingDisable(PCI_HOST host, PCI_AGENT_PARK internalAgent,
+ PCI_AGENT_PARK externalAgent0,
+ PCI_AGENT_PARK externalAgent1,
+ PCI_AGENT_PARK externalAgent2,
+ PCI_AGENT_PARK externalAgent3,
+ PCI_AGENT_PARK externalAgent4,
+ PCI_AGENT_PARK externalAgent5)
+{
+ unsigned int regData;
+ unsigned int writeData;
+
+ GT_REG_READ(pci_arbiter_control[host],®Data);
+ writeData = (internalAgent << 14) + (externalAgent0 << 15) + \
+ (externalAgent1 << 16) + (externalAgent2 << 17) + \
+ (externalAgent3 << 18) + (externalAgent4 << 19) + \
+ (externalAgent5 << 20);
+ regData = (regData & ~(0x7f<<14)) | writeData;
+ GT_REG_WRITE(pci_arbiter_control[host],regData);
+ return true;
+}
+
+/********************************************************************
+* pciSetRegionSnoopMode - This function modifys one of the 4 regions which
+* supports Cache Coherency in the PCI_n interface.
+* Inputs: region - One of the four regions.
+* snoopType - There is four optional Types:
+* 1. No Snoop.
+* 2. Snoop to WT region.
+* 3. Snoop to WB region.
+* 4. Snoop & Invalidate to WB region.
+* baseAddress - Base Address of this region.
+* regionLength - Region length.
+* Returns: false if one of the parameters is wrong otherwise return true.
+*********************************************************************/
+bool pciSetRegionSnoopMode(PCI_HOST host, PCI_SNOOP_REGION region,PCI_SNOOP_TYPE snoopType,
+ unsigned int baseAddress,
+ unsigned int regionLength)
+{
+ unsigned int snoopXbaseAddress;
+ unsigned int snoopXtopAddress;
+ unsigned int data;
+ unsigned int snoopHigh = baseAddress + regionLength;
+
+ if( (region > PCI_SNOOP_REGION3) || (snoopType > PCI_SNOOP_WB) )
+ return false;
+ snoopXbaseAddress = pci_snoop_control_base_0_low[host] + 0x10 * region;
+ snoopXtopAddress = pci_snoop_control_top_0[host] + 0x10 * region;
+ if(regionLength == 0) /* closing the region */
+ {
+ GT_REG_WRITE(snoopXbaseAddress,0x0000ffff);
+ GT_REG_WRITE(snoopXtopAddress,0);
+ return true;
+ }
+ baseAddress = baseAddress & 0xfff00000; /* Granularity of 1MByte */
+ data = (baseAddress >> 20) | snoopType << 12;
+ GT_REG_WRITE(snoopXbaseAddress,data);
+ snoopHigh = (snoopHigh & 0xfff00000) >> 20;
+ GT_REG_WRITE(snoopXtopAddress,snoopHigh - 1);
+ return true;
+}
+
+/*
+ *
+ */
+
+static int gt_read_config_dword(struct pci_controller *hose,
+ pci_dev_t dev,
+ int offset, u32* value)
+{
+ *value = pciReadConfigReg((PCI_HOST) hose->cfg_addr, offset, PCI_DEV(dev));
+ return 0;
+}
+
+static int gt_write_config_dword(struct pci_controller *hose,
+ pci_dev_t dev,
+ int offset, u32 value)
+{
+ pciWriteConfigReg((PCI_HOST)hose->cfg_addr, offset, PCI_DEV(dev), value);
+ return 0;
+}
+
+/*
+ *
+ */
+
+static void gt_setup_ide(struct pci_controller *hose,
+ pci_dev_t dev, struct pci_config_table *entry)
+{
+ static const int ide_bar[]={8,4,8,4,0,0};
+ u32 bar_response, bar_value;
+ int bar;
+
+ for (bar=0; bar<6; bar++)
+ {
+ pci_write_config_dword(dev, PCI_BASE_ADDRESS_0 + bar*4, 0x0);
+ pci_read_config_dword(dev, PCI_BASE_ADDRESS_0 + bar*4, &bar_response);
+
+ pciauto_region_allocate(bar_response & PCI_BASE_ADDRESS_SPACE_IO ?
+ hose->pci_io : hose->pci_mem, ide_bar[bar], &bar_value);
+
+ pci_write_config_dword(dev, PCI_BASE_ADDRESS_0 + bar*4, bar_value);
+ }
+}
+
+static void gt_fixup_irq(struct pci_controller *hose, pci_dev_t dev)
+{
+ unsigned char pin, irq;
+
+ pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
+
+ if(pin == 1) { /* only allow INT A */
+ irq = pci_irq_swizzle[(PCI_HOST)hose->cfg_addr][PCI_DEV(dev)];
+ if(irq)
+ pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
+ }
+}
+
+struct pci_config_table gt_config_table[] = {
+ { PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_STORAGE_IDE,
+ PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, gt_setup_ide},
+
+ { }
+};
+
+struct pci_controller pci0_hose = {
+ fixup_irq: gt_fixup_irq,
+ config_table: gt_config_table,
+};
+
+struct pci_controller pci1_hose = {
+ fixup_irq: gt_fixup_irq,
+ config_table: gt_config_table,
+};
+
+void
+pci_init(void)
+{
+ unsigned int command;
+
+ pci0_hose.first_busno = 0;
+ pci0_hose.last_busno = 0xff;
+
+ /* PCI memory space */
+ pci_set_region(pci0_hose.regions + 0,
+ CFG_PCI0_0_MEM_SPACE,
+ CFG_PCI0_0_MEM_SPACE,
+ CFG_PCI0_MEM_SIZE,
+ PCI_REGION_MEM);
+
+ /* PCI I/O space */
+ pci_set_region(pci0_hose.regions + 1,
+ CFG_PCI0_IO_SPACE_PCI,
+ CFG_PCI0_IO_SPACE,
+ CFG_PCI0_IO_SIZE,
+ PCI_REGION_IO);
+
+ pci_set_ops(&pci0_hose,
+ pci_hose_read_config_byte_via_dword,
+ pci_hose_read_config_word_via_dword,
+ gt_read_config_dword,
+ pci_hose_write_config_byte_via_dword,
+ pci_hose_write_config_word_via_dword,
+ gt_write_config_dword);
+
+ pci0_hose.region_count = 2;
+
+ pci0_hose.cfg_addr = (unsigned int*) PCI_HOST0;
+
+ pci_register_hose(&pci0_hose);
+
+ pciArbiterEnable(PCI_HOST0);
+ pciParkingDisable(PCI_HOST0,1,1,1,1,1,1,1);
+
+ command = pciReadConfigReg(PCI_HOST0, PCI_COMMAND, SELF);
+ command |= PCI_COMMAND_MASTER;
+ pciWriteConfigReg(PCI_HOST0, PCI_COMMAND, SELF, command);
+
+ pci0_hose.last_busno = pci_hose_scan(&pci0_hose);
+
+ command = pciReadConfigReg(PCI_HOST0, PCI_COMMAND, SELF);
+ command |= PCI_COMMAND_MEMORY;
+ pciWriteConfigReg(PCI_HOST0, PCI_COMMAND, SELF, command);
+
+ pci1_hose.first_busno = pci0_hose.last_busno + 1;
+ pci1_hose.last_busno = 0xff;
+
+ /* PCI memory space */
+ pci_set_region(pci1_hose.regions + 0,
+ CFG_PCI1_0_MEM_SPACE,
+ CFG_PCI1_0_MEM_SPACE,
+ CFG_PCI1_MEM_SIZE,
+ PCI_REGION_MEM);
+
+ /* PCI I/O space */
+ pci_set_region(pci1_hose.regions + 1,
+ CFG_PCI1_IO_SPACE_PCI,
+ CFG_PCI1_IO_SPACE,
+ CFG_PCI1_IO_SIZE,
+ PCI_REGION_IO);
+
+ pci_set_ops(&pci1_hose,
+ pci_hose_read_config_byte_via_dword,
+ pci_hose_read_config_word_via_dword,
+ gt_read_config_dword,
+ pci_hose_write_config_byte_via_dword,
+ pci_hose_write_config_word_via_dword,
+ gt_write_config_dword);
+
+ pci1_hose.region_count = 2;
+
+ pci1_hose.cfg_addr = (unsigned int*) PCI_HOST1;
+
+ pci_register_hose(&pci1_hose);
+
+ pciArbiterEnable(PCI_HOST1);
+ pciParkingDisable(PCI_HOST1,1,1,1,1,1,1,1);
+
+ command = pciReadConfigReg(PCI_HOST1, PCI_COMMAND, SELF);
+ command |= PCI_COMMAND_MASTER;
+ pciWriteConfigReg(PCI_HOST1, PCI_COMMAND, SELF, command);
+
+ pci1_hose.last_busno = pci_hose_scan(&pci1_hose);
+
+ command = pciReadConfigReg(PCI_HOST1, PCI_COMMAND, SELF);
+ command |= PCI_COMMAND_MEMORY;
+ pciWriteConfigReg(PCI_HOST1, PCI_COMMAND, SELF, command);
+}
--- /dev/null
+/*
+ * (C) Copyright 2001
+ * Josh Huber <huber@mclx.com>, Mission Critical Linux, 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
+ */
+
+/* sdram_init.c - automatic memory sizing */
+
+#include <common.h>
+#include <74xx_7xx.h>
+#include <galileo/memory.h>
+#include <galileo/pci.h>
+#include <galileo/gt64260R.h>
+#include <net.h>
+
+#include "eth.h"
+#include "mpsc.h"
+#include "i2c.h"
+#include "64260.h"
+
+/* #define DEBUG */
+#define MAP_PCI
+
+#ifdef DEBUG
+#define DP(x) x
+#else
+#define DP(x)
+#endif
+
+#define GB (1 << 30)
+
+/* structure to store the relevant information about an sdram bank */
+typedef struct sdram_info {
+ uchar drb_size;
+ uchar registered, ecc;
+ uchar tpar;
+ uchar tras_clocks;
+ uchar burst_len;
+ uchar banks, slot;
+ int size; /* detected size, not from I2C but from dram_size() */
+} sdram_info_t;
+
+#ifdef DEBUG
+void dump_dimm_info(struct sdram_info *d)
+{
+ static const char *ecc_legend[]={""," Parity"," ECC"};
+ printf("dimm%s %sDRAM: %dMibytes:\n",
+ ecc_legend[d->ecc],
+ d->registered?"R":"",
+ (d->size>>20));
+ printf(" drb=%d tpar=%d tras=%d burstlen=%d banks=%d slot=%d\n",
+ d->drb_size, d->tpar, d->tras_clocks, d->burst_len,
+ d->banks, d->slot);
+}
+#endif
+
+static int
+memory_map_bank(unsigned int bankNo,
+ unsigned int bankBase,
+ unsigned int bankLength)
+{
+#ifdef DEBUG
+ if (bankLength > 0) {
+ printf("mapping bank %d at %08x - %08x\n",
+ bankNo, bankBase, bankBase + bankLength - 1);
+ } else {
+ printf("unmapping bank %d\n", bankNo);
+ }
+#endif
+
+ memoryMapBank(bankNo, bankBase, bankLength);
+
+ return 0;
+}
+
+#ifdef MAP_PCI
+static int
+memory_map_bank_pci(unsigned int bankNo,
+ unsigned int bankBase,
+ unsigned int bankLength)
+{
+ PCI_HOST host;
+ for (host=PCI_HOST0;host<=PCI_HOST1;host++) {
+ const int features=
+ PREFETCH_ENABLE |
+ DELAYED_READ_ENABLE |
+ AGGRESSIVE_PREFETCH |
+ READ_LINE_AGGRESSIVE_PREFETCH |
+ READ_MULTI_AGGRESSIVE_PREFETCH |
+ MAX_BURST_4 |
+ PCI_NO_SWAP;
+
+ pciMapMemoryBank(host, bankNo, bankBase, bankLength);
+
+ pciSetRegionSnoopMode(host, bankNo, PCI_SNOOP_WB, bankBase,
+ bankLength);
+
+ pciSetRegionFeatures(host, bankNo, features, bankBase, bankLength);
+ }
+ return 0;
+}
+#endif
+
+/* ------------------------------------------------------------------------- */
+
+/* much of this code is based on (or is) the code in the pip405 port */
+/* thanks go to the authors of said port - Josh */
+
+
+/*
+ * translate ns.ns/10 coding of SPD timing values
+ * into 10 ps unit values
+ */
+static inline unsigned short
+NS10to10PS(unsigned char spd_byte)
+{
+ unsigned short ns, ns10;
+
+ /* isolate upper nibble */
+ ns = (spd_byte >> 4) & 0x0F;
+ /* isolate lower nibble */
+ ns10 = (spd_byte & 0x0F);
+
+ return(ns*100 + ns10*10);
+}
+
+/*
+ * translate ns coding of SPD timing values
+ * into 10 ps unit values
+ */
+static inline unsigned short
+NSto10PS(unsigned char spd_byte)
+{
+ return(spd_byte*100);
+}
+
+#ifdef CONFIG_ZUMA_V2
+static int
+check_dimm(uchar slot, sdram_info_t *info)
+{
+ /* assume 2 dimms, 2 banks each 256M - we dont have an
+ * dimm i2c so rely on the detection routines later */
+
+ memset(info, 0, sizeof(*info));
+
+ info->slot = slot;
+ info->banks = 2; /* Detect later */
+ info->registered = 0;
+ info->drb_size = 32; /* 16 - 256MBit, 32 - 512MBit
+ but doesn't matter, both do same
+ thing in setup_sdram() */
+ info->tpar = 3;
+ info->tras_clocks = 5;
+ info->burst_len = 4;
+#ifdef CONFIG_ECC
+ info->ecc = 0; /* Detect later */
+#endif /* CONFIG_ECC */
+ return 0;
+}
+
+#else /* ! CONFIG_ZUMA_V2 */
+
+/* This code reads the SPD chip on the sdram and populates
+ * the array which is passed in with the relevant information */
+static int
+check_dimm(uchar slot, sdram_info_t *info)
+{
+ DECLARE_GLOBAL_DATA_PTR;
+ uchar addr = slot == 0 ? DIMM0_I2C_ADDR : DIMM1_I2C_ADDR;
+ int ret;
+ uchar rows, cols, sdram_banks, supp_cal, width, cal_val;
+ ulong tmemclk;
+ uchar trp_clocks, trcd_clocks;
+ uchar data[128];
+
+ get_clocks ();
+
+ tmemclk = 1000000000 / (gd->bus_clk / 100); /* in 10 ps units */
+
+#ifdef CONFIG_EVB64260_750CX
+ if (0 != slot) {
+ printf("check_dimm: The EVB-64260-750CX only has 1 DIMM,");
+ printf(" called with slot=%d insetad!\n", slot);
+ return 0;
+ }
+#endif
+ DP(puts("before i2c read\n"));
+
+ ret = i2c_read(addr, 0, 128, data, 0);
+
+ DP(puts("after i2c read\n"));
+
+ /* zero all the values */
+ memset(info, 0, sizeof(*info));
+
+ if (ret) {
+ DP(printf("No DIMM in slot %d [err = %x]\n", slot, ret));
+ return 0;
+ }
+
+ /* first, do some sanity checks */
+ if (data[2] != 0x4) {
+ printf("Not SDRAM in slot %d\n", slot);
+ return 0;
+ }
+
+ /* get various information */
+ rows = data[3];
+ cols = data[4];
+ info->banks = data[5];
+ sdram_banks = data[17];
+ width = data[13] & 0x7f;
+
+ DP(printf("sdram_banks: %d, banks: %d\n", sdram_banks, info->banks));
+
+ /* check if the memory is registered */
+ if (data[21] & (BIT1 | BIT4))
+ info->registered = 1;
+
+#ifdef CONFIG_ECC
+ /* check for ECC/parity [0 = none, 1 = parity, 2 = ecc] */
+ info->ecc = (data[11] & 2) >> 1;
+#endif
+
+ /* bit 1 is CL2, bit 2 is CL3 */
+ supp_cal = (data[18] & 0x6) >> 1;
+
+ /* compute the relevant clock values */
+ trp_clocks = (NSto10PS(data[27])+(tmemclk-1)) / tmemclk;
+ trcd_clocks = (NSto10PS(data[29])+(tmemclk-1)) / tmemclk;
+ info->tras_clocks = (NSto10PS(data[30])+(tmemclk-1)) / tmemclk;
+
+ DP(printf("trp = %d\ntrcd_clocks = %d\ntras_clocks = %d\n",
+ trp_clocks, trcd_clocks, info->tras_clocks));
+
+ /* try a CAS latency of 3 first... */
+ cal_val = 0;
+ if (supp_cal & 3) {
+ if (NS10to10PS(data[9]) <= tmemclk)
+ cal_val = 3;
+ }
+
+ /* then 2... */
+ if (supp_cal & 2) {
+ if (NS10to10PS(data[23]) <= tmemclk)
+ cal_val = 2;
+ }
+
+ DP(printf("cal_val = %d\n", cal_val));
+
+ /* bummer, did't work... */
+ if (cal_val == 0) {
+ DP(printf("Couldn't find a good CAS latency\n"));
+ return 0;
+ }
+
+ /* get the largest delay -- these values need to all be the same
+ * see Res#6 */
+ info->tpar = cal_val;
+ if (trp_clocks > info->tpar)
+ info->tpar = trp_clocks;
+ if (trcd_clocks > info->tpar)
+ info->tpar = trcd_clocks;
+
+ DP(printf("tpar set to: %d\n", info->tpar));
+
+#ifdef CFG_BROKEN_CL2
+ if (info->tpar == 2){
+ info->tpar = 3;
+ DP(printf("tpar fixed-up to: %d\n", info->tpar));
+ }
+#endif
+ /* compute the module DRB size */
+ info->drb_size = (((1 << (rows + cols)) * sdram_banks) * width) / _16M;
+
+ DP(printf("drb_size set to: %d\n", info->drb_size));
+
+ /* find the burst len */
+ info->burst_len = data[16] & 0xf;
+ if ((info->burst_len & 8) == 8) {
+ info->burst_len = 1;
+ } else if ((info->burst_len & 4) == 4) {
+ info->burst_len = 0;
+ } else {
+ return 0;
+ }
+
+ info->slot = slot;
+ return 0;
+}
+#endif /* ! CONFIG_ZUMA_V2 */
+
+static int
+setup_sdram_common(sdram_info_t info[2])
+{
+ ulong tmp;
+ int tpar=2, tras_clocks=5, registered=1, ecc=2;
+
+ if(!info[0].banks && !info[1].banks) return 0;
+
+ if(info[0].banks) {
+ if(info[0].tpar>tpar) tpar=info[0].tpar;
+ if(info[0].tras_clocks>tras_clocks) tras_clocks=info[0].tras_clocks;
+ if(!info[0].registered) registered=0;
+ if(info[0].ecc!=2) ecc=0;
+ }
+
+ if(info[1].banks) {
+ if(info[1].tpar>tpar) tpar=info[1].tpar;
+ if(info[1].tras_clocks>tras_clocks) tras_clocks=info[1].tras_clocks;
+ if(!info[1].registered) registered=0;
+ if(info[1].ecc!=2) ecc=0;
+ }
+
+ /* SDRAM configuration */
+ tmp = GTREGREAD(SDRAM_CONFIGURATION);
+
+ /* Turn on physical interleave if both DIMMs
+ * have even numbers of banks. */
+ if( (info[0].banks == 0 || info[0].banks == 2) &&
+ (info[1].banks == 0 || info[1].banks == 2) ) {
+ /* physical interleave on */
+ tmp &= ~(1 << 15);
+ } else {
+ /* physical interleave off */
+ tmp |= (1 << 15);
+ }
+
+ tmp |= (registered << 17);
+
+ /* Use buffer 1 to return read data to the CPU
+ * See Res #12 */
+ tmp |= (1 << 26);
+
+ GT_REG_WRITE(SDRAM_CONFIGURATION, tmp);
+ DP(printf("SDRAM config: %08x\n",
+ GTREGREAD(SDRAM_CONFIGURATION)));
+
+ /* SDRAM timing */
+ tmp = (((tpar == 3) ? 2 : 1) |
+ (((tpar == 3) ? 2 : 1) << 2) |
+ (((tpar == 3) ? 2 : 1) << 4) |
+ (tras_clocks << 8));
+
+#ifdef CONFIG_ECC
+ /* Setup ECC */
+ if (ecc == 2) tmp |= 1<<13;
+#endif /* CONFIG_ECC */
+
+ GT_REG_WRITE(SDRAM_TIMING, tmp);
+ DP(printf("SDRAM timing: %08x (%d,%d,%d,%d)\n",
+ GTREGREAD(SDRAM_TIMING), tpar,tpar,tpar,tras_clocks));
+
+ /* SDRAM address decode register */
+ /* program this with the default value */
+ GT_REG_WRITE(SDRAM_ADDRESS_DECODE, 0x2);
+ DP(printf("SDRAM decode: %08x\n",
+ GTREGREAD(SDRAM_ADDRESS_DECODE)));
+
+ return 0;
+}
+
+/* sets up the GT properly with information passed in */
+static int
+setup_sdram(sdram_info_t *info)
+{
+ ulong tmp, check;
+ ulong *addr = 0;
+ int i;
+
+ /* sanity checking */
+ if (! info->banks) return 0;
+
+ /* ---------------------------- */
+ /* Program the GT with the discovered data */
+
+ /* bank parameters */
+ tmp = (0xf<<16); /* leave all virt bank pages open */
+
+ DP(printf("drb_size: %d\n", info->drb_size));
+ switch (info->drb_size) {
+ case 1:
+ tmp |= (1 << 14);
+ break;
+ case 4:
+ case 8:
+ tmp |= (2 << 14);
+ break;
+ case 16:
+ case 32:
+ tmp |= (3 << 14);
+ break;
+ default:
+ printf("Error in dram size calculation\n");
+ return 1;
+ }
+
+ /* SDRAM bank parameters */
+ /* the param registers for slot 1 (banks 2+3) are offset by 0x8 */
+ GT_REG_WRITE(SDRAM_BANK0PARAMETERS + (info->slot * 0x8), tmp);
+ GT_REG_WRITE(SDRAM_BANK1PARAMETERS + (info->slot * 0x8), tmp);
+ DP(printf("SDRAM bankparam slot %d (bank %d+%d): %08lx\n", info->slot, info->slot*2, (info->slot*2)+1, tmp));
+
+ /* set the SDRAM configuration for each bank */
+ for (i = info->slot * 2; i < ((info->slot * 2) + info->banks); i++) {
+ DP(printf("*** Running a MRS cycle for bank %d ***\n", i));
+
+ /* map the bank */
+ memory_map_bank(i, 0, GB/4);
+
+ /* set SDRAM mode */
+ GT_REG_WRITE(SDRAM_OPERATION_MODE, 0x3);
+ check = GTREGREAD(SDRAM_OPERATION_MODE);
+
+ /* dummy write */
+ *addr = 0;
+
+ /* wait for the command to complete */
+ while ((GTREGREAD(SDRAM_OPERATION_MODE) & (1 << 31)) == 0)
+ ;
+
+ /* switch back to normal operation mode */
+ GT_REG_WRITE(SDRAM_OPERATION_MODE, 0);
+ check = GTREGREAD(SDRAM_OPERATION_MODE);
+
+ /* unmap the bank */
+ memory_map_bank(i, 0, 0);
+ DP(printf("*** MRS cycle for bank %d done ***\n", i));
+ }
+
+ return 0;
+}
+
+/*
+ * Check memory range for valid RAM. A simple memory test determines
+ * the actually available RAM size between addresses `base' and
+ * `base + maxsize'. Some (not all) hardware errors are detected:
+ * - short between address lines
+ * - short between data lines
+ */
+static long int
+dram_size(long int *base, long int maxsize)
+{
+ volatile long int *addr, *b=base;
+ long int cnt, val, save1, save2;
+
+#define STARTVAL (1<<20) /* start test at 1M */
+ for (cnt = STARTVAL/sizeof(long); cnt < maxsize/sizeof(long); cnt <<= 1) {
+ addr = base + cnt; /* pointer arith! */
+
+ save1=*addr; /* save contents of addr */
+ save2=*b; /* save contents of base */
+
+ *addr=cnt; /* write cnt to addr */
+ *b=0; /* put null at base */
+
+ /* check at base address */
+ if ((*b) != 0) {
+ *addr=save1; /* restore *addr */
+ *b=save2; /* restore *b */
+ return (0);
+ }
+ val = *addr; /* read *addr */
+
+ *addr=save1;
+ *b=save2;
+
+ if (val != cnt) {
+ /* fix boundary condition.. STARTVAL means zero */
+ if(cnt==STARTVAL/sizeof(long)) cnt=0;
+ return (cnt * sizeof(long));
+ }
+ }
+ return maxsize;
+}
+
+/* ------------------------------------------------------------------------- */
+
+/* U-Boot interface function to SDRAM init - this is where all the
+ * controlling logic happens */
+long int
+initdram(int board_type)
+{
+ ulong checkbank[4] = { [0 ... 3] = 0 };
+ int bank_no;
+ ulong total;
+ int nhr;
+ sdram_info_t dimm_info[2];
+
+
+ /* first, use the SPD to get info about the SDRAM */
+
+ /* check the NHR bit and skip mem init if it's already done */
+ nhr = get_hid0() & (1 << 16);
+
+ if (nhr) {
+ printf("Skipping SDRAM setup due to NHR bit being set\n");
+ } else {
+ /* DIMM0 */
+ check_dimm(0, &dimm_info[0]);
+
+ /* DIMM1 */
+#ifndef CONFIG_EVB64260_750CX /* EVB64260_750CX has only 1 DIMM */
+ check_dimm(1, &dimm_info[1]);
+#else /* CONFIG_EVB64260_750CX */
+ memset(&dimm_info[1], 0, sizeof(sdram_info_t));
+#endif
+
+ /* unmap all banks */
+ memory_map_bank(0, 0, 0);
+ memory_map_bank(1, 0, 0);
+ memory_map_bank(2, 0, 0);
+ memory_map_bank(3, 0, 0);
+
+ /* Now, program the GT with the correct values */
+ if (setup_sdram_common(dimm_info)) {
+ printf("Setup common failed.\n");
+ }
+
+ if (setup_sdram(&dimm_info[0])) {
+ printf("Setup for DIMM1 failed.\n");
+ }
+
+ if (setup_sdram(&dimm_info[1])) {
+ printf("Setup for DIMM2 failed.\n");
+ }
+
+ /* set the NHR bit */
+ set_hid0(get_hid0() | (1 << 16));
+ }
+ /* next, size the SDRAM banks */
+
+ total = 0;
+ if (dimm_info[0].banks > 0) checkbank[0] = 1;
+ if (dimm_info[0].banks > 1) checkbank[1] = 1;
+ if (dimm_info[0].banks > 2)
+ printf("Error, SPD claims DIMM1 has >2 banks\n");
+
+ if (dimm_info[1].banks > 0) checkbank[2] = 1;
+ if (dimm_info[1].banks > 1) checkbank[3] = 1;
+ if (dimm_info[1].banks > 2)
+ printf("Error, SPD claims DIMM2 has >2 banks\n");
+
+ /* Generic dram sizer: works even if we don't have i2c DIMMs,
+ * as long as the timing settings are more or less correct */
+
+ /*
+ * pass 1: size all the banks, using first bat (0-256M)
+ * limitation: we only support 256M per bank due to
+ * us only having 1 BAT for all DRAM
+ */
+ for (bank_no = 0; bank_no < CFG_DRAM_BANKS; bank_no++) {
+ /* skip over banks that are not populated */
+ if (! checkbank[bank_no])
+ continue;
+
+ DP(printf("checking bank %d\n", bank_no));
+
+ memory_map_bank(bank_no, 0, GB/4);
+ checkbank[bank_no] = dram_size(NULL, GB/4);
+ memory_map_bank(bank_no, 0, 0);
+
+ DP(printf("bank %d %08lx\n", bank_no, checkbank[bank_no]));
+ }
+
+ /*
+ * pass 2: contiguously map each bank into physical address
+ * space.
+ */
+ dimm_info[0].banks=dimm_info[1].banks=0;
+ for (bank_no = 0; bank_no < CFG_DRAM_BANKS; bank_no++) {
+ if(!checkbank[bank_no]) continue;
+
+ dimm_info[bank_no/2].banks++;
+ dimm_info[bank_no/2].size+=checkbank[bank_no];
+
+ memory_map_bank(bank_no, total, checkbank[bank_no]);
+#ifdef MAP_PCI
+ memory_map_bank_pci(bank_no, total, checkbank[bank_no]);
+#endif
+ total += checkbank[bank_no];
+ }
+
+#ifdef CONFIG_ECC
+#ifdef CONFIG_ZUMA_V2
+ /*
+ * We always enable ECC when bank 2 and 3 are unpopulated
+ * If we 2 or 3 are populated, we CAN'T support ECC.
+ * (Zuma boards only support ECC in banks 0 and 1; assume that
+ * in that configuration, ECC chips are mounted, even for stacked
+ * chips)
+ */
+ if (checkbank[2]==0 && checkbank[3]==0) {
+ dimm_info[0].ecc=2;
+ GT_REG_WRITE(SDRAM_TIMING, GTREGREAD(SDRAM_TIMING) | (1 << 13));
+ /* TODO: do we have to run MRS cycles again? */
+ }
+#endif /* CONFIG_ZUMA_V2 */
+
+ if (GTREGREAD(SDRAM_TIMING) & (1 << 13)) {
+ puts("[ECC] ");
+ }
+#endif /* CONFIG_ECC */
+
+#ifdef DEBUG
+ dump_dimm_info(&dimm_info[0]);
+ dump_dimm_info(&dimm_info[1]);
+#endif
+ /* TODO: return at MOST 256M? */
+ /* return total > GB/4 ? GB/4 : total; */
+ return total;
+}
--- /dev/null
+/*
+ * (C) Copyright 2001
+ * Josh Huber <huber@mclx.com>, Mission Critical Linux, 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
+ */
+
+/*
+ * serial.c - serial support for the gal ev board
+ */
+
+/* supports both the 16650 duart and the MPSC */
+
+#include <common.h>
+#include <command.h>
+#include <galileo/memory.h>
+
+#if (defined CFG_INIT_CHAN1) || (defined CFG_INIT_CHAN2)
+#include <ns16550.h>
+#endif
+
+#include "serial.h"
+
+#include "mpsc.h"
+
+#if (defined CFG_INIT_CHAN1) || (defined CFG_INIT_CHAN2)
+const NS16550_t COM_PORTS[] = { (NS16550_t) CFG_NS16550_COM1,
+ (NS16550_t) CFG_NS16550_COM2 };
+#endif
+
+#ifdef CONFIG_MPSC
+
+int serial_init (void)
+{
+ DECLARE_GLOBAL_DATA_PTR;
+
+#if (defined CFG_INIT_CHAN1) || (defined CFG_INIT_CHAN2)
+ int clock_divisor = CFG_NS16550_CLK / 16 / gd->baudrate;
+#endif
+
+ mpsc_init(gd->baudrate);
+
+ /* init the DUART chans so that KGDB in the kernel can use them */
+#ifdef CFG_INIT_CHAN1
+ NS16550_reinit(COM_PORTS[0], clock_divisor);
+#endif
+#ifdef CFG_INIT_CHAN2
+ NS16550_reinit(COM_PORTS[1], clock_divisor);
+#endif
+ return (0);
+}
+
+void
+serial_putc(const char c)
+{
+ if (c == '\n')
+ mpsc_putchar('\r');
+
+ mpsc_putchar(c);
+}
+
+int
+serial_getc(void)
+{
+ return mpsc_getchar();
+}
+
+int
+serial_tstc(void)
+{
+ return mpsc_test_char();
+}
+
+void
+serial_setbrg (void)
+{
+ DECLARE_GLOBAL_DATA_PTR;
+
+ galbrg_set_baudrate(CONFIG_MPSC_PORT, gd->baudrate);
+}
+
+#else /* ! CONFIG_MPSC */
+
+int serial_init (void)
+{
+ DECLARE_GLOBAL_DATA_PTR;
+
+ int clock_divisor = CFG_NS16550_CLK / 16 / gd->baudrate;
+
+#ifdef CFG_INIT_CHAN1
+ (void)NS16550_init(COM_PORTS[0], clock_divisor);
+#endif
+#ifdef CFG_INIT_CHAN2
+ (void)NS16550_init(COM_PORTS[1], clock_divisor);
+#endif
+
+ return (0);
+}
+
+void
+serial_putc(const char c)
+{
+ if (c == '\n')
+ NS16550_putc(COM_PORTS[CFG_DUART_CHAN], '\r');
+
+ NS16550_putc(COM_PORTS[CFG_DUART_CHAN], c);
+}
+
+int
+serial_getc(void)
+{
+ return NS16550_getc(COM_PORTS[CFG_DUART_CHAN]);
+}
+
+int
+serial_tstc(void)
+{
+ return NS16550_tstc(COM_PORTS[CFG_DUART_CHAN]);
+}
+
+void
+serial_setbrg (void)
+{
+ DECLARE_GLOBAL_DATA_PTR;
+
+ int clock_divisor = CFG_NS16550_CLK / 16 / gd->baudrate;
+
+#ifdef CFG_INIT_CHAN1
+ NS16550_reinit(COM_PORTS[0], clock_divisor);
+#endif
+#ifdef CFG_INIT_CHAN2
+ NS16550_reinit(COM_PORTS[1], clock_divisor);
+#endif
+}
+
+#endif /* CONFIG_MPSC */
+
+void
+serial_puts (const char *s)
+{
+ while (*s) {
+ serial_putc (*s++);
+ }
+}
+
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+void
+kgdb_serial_init(void)
+{
+}
+
+void
+putDebugChar (int c)
+{
+ serial_putc (c);
+}
+
+void
+putDebugStr (const char *str)
+{
+ serial_puts (str);
+}
+
+int
+getDebugChar (void)
+{
+ return serial_getc();
+}
+
+void
+kgdb_interruptible (int yes)
+{
+ return;
+}
+#endif /* CFG_CMD_KGDB */
--- /dev/null
+
+This directory contains board specific code for a generic MPC860T based
+embedded computer, called 'GEN860T'. The design is generic in the sense that
+common, readily available components are used and that the architecture of the
+system is i(relatively) straightforward:
+
+ One eight bit wide boot (FLASH) memory
+ 32 bit main memory using SDRAM
+ DOC 2000+
+ Ethernet PHY
+ Some I2C peripheral devices: Atmel AT24C256 EEPROM, Maxim DS1337 RTC.
+ Some other miscellaneous peripherals
+
+NOTE: There are references to a XIlinx FPGA and Mil-Std 1553 databus in this
+port. I guess the computer is not as generic as I first said 8) However,
+these extras can be safely ignored.
+
+Given the GEN860T files, it should be pretty easy to reverse engineer the
+hardware configuration, if that's useful to you. Hopefully, this code will
+be useful to someone as a basis for a port to a new system or as a head start
+on a custom design. If you end up using any of this, I would appreciate
+hearing from you, especially if you discover bugs or find ways to improve the
+quality of this U-Boot port.
+
+Here are the salient features of the system:
+Clock : 33 Mhz oscillator
+Processor core frequency : 66 Mhz if in 1:2:1 mode; can also run 1:1
+Bus frequency : 33 Mhz
+
+Main memory:
+ Type : SDRAM
+ Width : 32 bits
+ Size : 64 megabytes
+ Chip : Two Micron MT48LC16M16A2TG-7E
+ CS : MPC860T CS1*/UPMA
+ UPMA CONNECTIONS:
+ SDRAM A10 : GPLA0*
+ SDRAM CAS* : GPLA2*
+ SDRAM WE* : GPLA3*
+ SDRAM RAS* : GPLA4*
+
+Boot memory:
+ Type : FLASH
+ Width : 8 bits
+ Size : 16 megabytes
+ Chip : One Intel 28F128J3A (StrataFlash)
+ CS : MPC860T CS0*/GPCM (this is the "boot" chip select)
+
+EEPROM memory:
+ Type : Serial I2C EEPROM
+ Width : 8 bits
+ Size : 32 kibibytes
+ Chip : One Atmel AT25C256
+ CS : 0x50 (external I2C address pins on device are tied to GND)
+
+Filesystem memory:
+ Type : NAND FLASH (Toshiba)
+ Width : 8 bits (i.e. interface to DOC is 8 bits)
+ Size : 32 megabytes
+ Chip : One DiskOnCHip Millenium Plus (DOC 2000+)
+ CS : MPC860T CS2*/GPCM
+
+Network support:
+ MAC : MPC86OT FEC (Fast Ethernet Controller)
+ PHY : Intel LXT971A
+ MII Addr: 0x0 (hardwired on the board)
+ MII IRQ :
+
+Console:
+ RS-232 on SMC1 (Maxim MAX3232 LVCMOS-RS232 level shifter)
+
+Real Time Clock:
+ Type : Low power, I2C interface
+ Chip : Maxim DS1337
+ CS : Address 0x68 on I2C bus
+
+ The MPC860T's internal RTC has a defect in Mask rev D that increases
+ the current drain on the KAPWR line to 10 mA. Since this is an
+ unreasonable amount of current draw for a RTC, and Motorola does not
+ plan to fix this in future mask revisions, a serial (I2C) RTC that
+ works has been included instead. NOTE that the DS1337 can be
+ configured to output a 32768 Hz clock while the main power is on.
+ This clock output has been routed to the MPC860T's EXTAL pin to allow
+ the internal RTC to be used. NOTE also that due to yet another
+ defect in the rev D mask, the RTC does not operate reliably when the
+ internal RTC divisor is set to use a 32768 Hz reference. So just use
+ the I2C RTC.
+
+Miscellaneous:
+ Xilinx Virtex FPGA on CS3*/GPCM.
+ Virtex FPGA slave SelectMap interface on cs4*/UPMB.
+ Mil-Std 1553 databus interface on CS5*/GPCM.
+ Audio sounder (beeper) with digital volume control connected to SPKROUT.
+
+Issues:
+ The DOC 2000+ returns 0x40 as its device ID when probed using the method
+ desxribed in the DOC datasheet. Unfortunately, the U-Boot DOC driver
+ does not recognize this device. As of this writing, it seems that MTD
+ does not support the DOC 2000+ either.
+
+Status:
+ Everything appears to work except DOC support. As of this writing,
+ David Woodhouse has stated on the MTD mailing list that he has no
+ knowledge of the DOC Millineum Plus and therfore there is no support
+ in MTD for this device. I wish I had known this sooner :(
+
+The GEN860T board specific files and configuration is based on the work
+of others who have contributed to U-Boot. The copright and license notices
+of these authors have been retained wherever their code has been reused.
+All new code to support the GEN860T board is:
+
+ (C) Copyright 2001-2002
+ Keith Outwater (keith_outwater@mvis.com)
+
+and the following license applies:
+
+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,
+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
+
+Thanks to Wolfgang Denk for a great software package and to everyone
+who contributed to its development.
+
+Keith Outwater
+Sr. Staff Engineer
+Microvision, Inc.
+<keith_outwater@mvis.com>
+<outwater@eskimo.com>
+
+vim: set ts=4 sw=4 tw=78:
+
--- /dev/null
+/*
+ * (C) Copyright 2002
+ * Keith Outwater, keith_outwater@mvis.com
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <mpc8xx.h>
+#include <asm/8xx_immap.h>
+#include <linux/ctype.h>
+
+/*
+ * Basic beeper support for the GEN860T board. The GEN860T includes
+ * an audio sounder driven by a Phillips TDA8551 amplifier. The
+ * TDA8551 features a digital volume control which uses a "trinary"
+ * input (high/high-Z/low) to set volume. The 860's SPKROUT pin
+ * drives the amplifier input.
+ */
+
+
+/*
+ * Initialize beeper-related hardware. Initialize timer 1 for use with
+ * the beeper. Use 66 Mhz internal clock with prescale of 33 to get
+ * 1 uS period per count.
+ * FIXME: we should really compute the prescale based on the reported
+ * core clock frequency.
+ */
+void
+init_beeper(void)
+{
+ volatile immap_t *immap = (immap_t *)CFG_IMMR;
+
+ immap->im_cpmtimer.cpmt_tgcr &= ~TGCR_RST1 | TGCR_STP1;
+ immap->im_cpmtimer.cpmt_tmr1 = ((33 << TMR_PS_SHIFT) & TMR_PS_MSK)
+ | TMR_OM | TMR_FRR | TMR_ICLK_IN_GEN;
+ immap->im_cpmtimer.cpmt_tcn1 = 0;
+ immap->im_cpmtimer.cpmt_ter1 = 0xffff;
+ immap->im_cpmtimer.cpmt_tgcr |= TGCR_RST1;
+}
+
+
+/*
+ * Set beeper frequency. Max allowed frequency is 2.5 KHz. This limit
+ * is mostly arbitrary, but the beeper isn't really much good beyond this
+ * frequency.
+ */
+void
+set_beeper_frequency(uint frequency)
+{
+#define FREQ_LIMIT 2500
+
+ volatile immap_t *immap = (immap_t *)CFG_IMMR;
+
+ /*
+ * Compute timer ticks given desired frequency. The timer is set up
+ * to count 0.5 uS per tick and it takes two ticks per cycle (Hz).
+ */
+ if (frequency > FREQ_LIMIT) frequency = FREQ_LIMIT;
+ frequency = 1000000/frequency;
+ immap->im_cpmtimer.cpmt_trr1 = (ushort)frequency;
+}
+
+
+/*
+ * Turn the beeper on
+ */
+void
+beeper_on(void)
+{
+ volatile immap_t *immap = (immap_t *)CFG_IMMR;
+
+ immap->im_cpmtimer.cpmt_tgcr &= ~TGCR_STP1;
+}
+
+
+/*
+ * Turn the beeper off
+ */
+void
+beeper_off(void)
+{
+ volatile immap_t *immap = (immap_t *)CFG_IMMR;
+
+ immap->im_cpmtimer.cpmt_tgcr |= TGCR_STP1;
+}
+
+
+/*
+ * Increase or decrease the beeper volume. Volume can be set
+ * from off to full in 64 steps. To increase volume, the output
+ * pin is actively driven high, then returned to tristate.
+ * To decrease volume, output a low on the port pin (no need to
+ * change pin mode to tristate) then output a high to go back to
+ * tristate.
+ */
+void
+set_beeper_volume(int steps)
+{
+ volatile immap_t *immap = (immap_t *)CFG_IMMR;
+ int i;
+
+ if (steps >= 0) {
+ for (i = 0; i < (steps >= 64 ? 64 : steps); i++) {
+ immap->im_cpm.cp_pbodr &= ~(0x80000000 >> 19);
+ udelay(1);
+ immap->im_cpm.cp_pbodr |= (0x80000000 >> 19);
+ udelay(1);
+ }
+ }
+ else {
+ for (i = 0; i > (steps <= -64 ? -64 : steps); i--) {
+ immap->im_cpm.cp_pbdat &= ~(0x80000000 >> 19);
+ udelay(1);
+ immap->im_cpm.cp_pbdat |= (0x80000000 >> 19);
+ udelay(1);
+ }
+ }
+}
+
+
+/*
+ * Check the environment to see if the beeper needs beeping.
+ * Controlled by a sequence of the form:
+ * freq/delta volume/on time/off time;... where:
+ * freq = frequency in Hz (0 - 2500)
+ * delta volume = volume steps up or down (-64 <= vol <= 64)
+ * on time = time in mS
+ * off time = time in mS
+ *
+ * Return 1 on success, 0 on failure
+ */
+int
+do_beeper(char *sequence)
+{
+#define DELIMITER ';'
+
+int args[4];
+int i;
+int val;
+char *p = sequence;
+char *tp;
+
+ /*
+ * Parse the control sequence. This is a really simple parser
+ * without any real error checking. You can probably blow it
+ * up really easily.
+ */
+ if (*p == '\0' || !isdigit(*p)) {
+ printf("%s:%d: null or invalid string (%s)\n",
+ __FILE__, __LINE__, p);
+ return 0;
+ }
+
+ i = 0;
+ while (*p != '\0') {
+ while (*p != DELIMITER) {
+ if (i > 3) i = 0;
+ val = (int) simple_strtol(p, &tp, 0);
+ if (tp == p) {
+ printf("%s:%d: no digits or bad format\n",
+ __FILE__,__LINE__);
+ return 0;
+ }
+ else {
+ args[i] = val;
+ }
+
+ i++;
+ if (*tp == DELIMITER)
+ p = tp;
+ else
+ p = ++tp;
+ }
+ p++;
+
+ /*
+ * Well, we got something that has a chance of being correct
+ */
+#if 0
+ for (i = 0; i < 4; i++) {
+ printf("%s:%d:arg %d = %d\n", __FILE__, __LINE__, i, args[i]);
+ }
+ printf("\n");
+#endif
+
+ set_beeper_frequency(args[0]);
+ set_beeper_volume(args[1]);
+ beeper_on();
+ udelay(1000 * args[2]);
+ beeper_off();
+ udelay(1000 * args[3]);
+ }
+ return 1;
+}
+
+/* vim: set ts=4 sw=4 tw=78: */
--- /dev/null
+/*
+ * (C) Copyright 2001
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ * Keith Outwater, keith_outwater@mvsi.com
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <mpc8xx.h>
+
+#if defined(CFG_ENV_IS_IN_FLASH)
+# ifndef CFG_ENV_ADDR
+# define CFG_ENV_ADDR (CFG_FLASH_BASE + CFG_ENV_OFFSET)
+# endif
+# ifndef CFG_ENV_SIZE
+# define CFG_ENV_SIZE CFG_ENV_SECT_SIZE
+# endif
+# ifndef CFG_ENV_SECT_SIZE
+# define CFG_ENV_SECT_SIZE CFG_ENV_SIZE
+# endif
+#endif
+
+/*
+ * Use buffered writes to flash by default - they are about 32x faster than
+ * single byte writes.
+ */
+#ifndef CFG_GEN860T_FLASH_USE_WRITE_BUFFER
+#define CFG_GEN860T_FLASH_USE_WRITE_BUFFER
+#endif
+
+/*
+ * Max time to wait (in mS) for flash device to allocate a write buffer.
+ */
+#ifndef CFG_FLASH_ALLOC_BUFFER_TOUT
+#define CFG_FLASH_ALLOC_BUFFER_TOUT 100
+#endif
+
+/*
+ * These functions support a single Intel StrataFlash device (28F128J3A)
+ * in byte mode only!. The flash routines are very basic and simple
+ * since there isn't really any remapping necessary.
+ */
+
+/*
+ * Intel SCS (Scalable Command Set) command definitions
+ * (taken from 28F128J3A datasheet)
+ */
+#define SCS_READ_CMD 0xff
+#define SCS_READ_ID_CMD 0x90
+#define SCS_QUERY_CMD 0x98
+#define SCS_READ_STATUS_CMD 0x70
+#define SCS_CLEAR_STATUS_CMD 0x50
+#define SCS_WRITE_BUF_CMD 0xe8
+#define SCS_PROGRAM_CMD 0x40
+#define SCS_BLOCK_ERASE_CMD 0x20
+#define SCS_BLOCK_ERASE_RESUME_CMD 0xd0
+#define SCS_PROGRAM_RESUME_CMD 0xd0
+#define SCS_BLOCK_ERASE_SUSPEND_CMD 0xb0
+#define SCS_SET_BLOCK_LOCK_CMD 0x60
+#define SCS_CLR_BLOCK_LOCK_CMD 0x60
+
+/*
+ * SCS status/extended status register bit definitions
+ */
+#define SCS_SR7 0x80
+#define SCS_XSR7 0x80
+
+/*---------------------------------------------------------------------*/
+#if 0
+#define DEBUG_FLASH
+#endif
+
+#ifdef DEBUG_FLASH
+#define PRINTF(fmt,args...) printf(fmt ,##args)
+#else
+#define PRINTF(fmt,args...)
+#endif
+/*---------------------------------------------------------------------*/
+
+flash_info_t flash_info[CFG_MAX_FLASH_BANKS];
+
+/*-----------------------------------------------------------------------
+ * Functions
+ */
+static ulong flash_get_size (vu_char *addr, flash_info_t *info);
+static int write_data8 (flash_info_t *info, ulong dest, uchar data);
+static void flash_get_offsets (ulong base, flash_info_t *info);
+
+/*-----------------------------------------------------------------------
+ * Initialize the flash memory.
+ */
+unsigned long
+flash_init (void)
+{
+ volatile immap_t *immap = (immap_t *)CFG_IMMR;
+ volatile memctl8xx_t *memctl = &immap->im_memctl;
+ unsigned long size_b0;
+ int i;
+
+ for (i= 0; i < CFG_MAX_FLASH_BANKS; ++i) {
+ flash_info[i].flash_id = FLASH_UNKNOWN;
+ }
+
+ /*
+ * The gen860t board only has one FLASH memory device, so the
+ * FLASH Bank configuration is done statically.
+ */
+ PRINTF("\n## Get flash bank 1 size @ 0x%08x\n", FLASH_BASE0_PRELIM);
+ size_b0 = flash_get_size((vu_char *)FLASH_BASE0_PRELIM, &flash_info[0]);
+ if (flash_info[0].flash_id == FLASH_UNKNOWN) {
+ printf ("## Unknown FLASH on Bank 0: "
+ "ID 0x%lx, Size = 0x%08lx = %ld MB\n",
+ flash_info[0].flash_id,size_b0, size_b0 << 20);
+ }
+
+ PRINTF("## Before remap:\n"
+ " BR0: 0x%08x OR0: 0x%08x\n BR1: 0x%08x OR1: 0x%08x\n",
+ memctl->memc_br0, memctl->memc_or0,
+ memctl->memc_br1, memctl->memc_or1);
+
+ /*
+ * Remap FLASH according to real size
+ */
+ memctl->memc_or0 |= (-size_b0 & 0xFFFF8000);
+ memctl->memc_br0 |= (CFG_FLASH_BASE & BR_BA_MSK);
+
+ PRINTF("## After remap:\n"
+ " BR0: 0x%08x OR0: 0x%08x\n", memctl->memc_br0, memctl->memc_or0);
+
+ /*
+ * Re-do sizing to get full correct info
+ */
+ size_b0 = flash_get_size ((vu_char *)CFG_FLASH_BASE, &flash_info[0]);
+ flash_get_offsets (CFG_FLASH_BASE, &flash_info[0]);
+ flash_info[0].size = size_b0;
+
+#if CFG_MONITOR_BASE >= CFG_FLASH_BASE
+ /*
+ * Monitor protection is ON by default
+ */
+ flash_protect(FLAG_PROTECT_SET,
+ CFG_MONITOR_BASE,
+ CFG_MONITOR_BASE + CFG_MONITOR_LEN - 1,
+ &flash_info[0]);
+#endif
+
+#ifdef CFG_ENV_IS_IN_FLASH
+ /*
+ * Environment protection ON by default
+ */
+ flash_protect(FLAG_PROTECT_SET,
+ CFG_ENV_ADDR,
+ CFG_ENV_ADDR + CFG_ENV_SECT_SIZE - 1,
+ &flash_info[0]);
+#endif
+
+ PRINTF("## Final Flash bank size: 0x%08lx\n",size_b0);
+ return (size_b0);
+}
+
+
+/*-----------------------------------------------------------------------
+ * Fill in the FLASH offset table
+ */
+static void
+flash_get_offsets (ulong base, flash_info_t *info)
+{
+ int i;
+
+ if (info->flash_id == FLASH_UNKNOWN) {
+ return;
+ }
+
+ switch (info->flash_id & FLASH_VENDMASK) {
+ case FLASH_MAN_INTEL:
+ for (i = 0; i < info->sector_count; i++) {
+ info->start[i] = base;
+ base += 1024 * 128;
+ }
+ return;
+
+ default:
+ printf ("Don't know sector offsets for FLASH"
+ " type 0x%lx\n", info->flash_id);
+ return;
+ }
+}
+
+
+/*-----------------------------------------------------------------------
+ * Display FLASH device info
+ */
+void
+flash_print_info (flash_info_t *info)
+{
+ int i;
+
+ if (info->flash_id == FLASH_UNKNOWN) {
+ printf ("Missing or unknown FLASH type\n");
+ return;
+ }
+
+ switch (info->flash_id & FLASH_VENDMASK) {
+ case FLASH_MAN_INTEL:
+ printf ("Intel ");
+ break;
+ default:
+ printf ("Unknown Vendor ");
+ break;
+ }
+
+ switch (info->flash_id & FLASH_TYPEMASK) {
+ case FLASH_28F128J3A:
+ printf ("28F128J3A (128Mbit = 128K x 128)\n");
+ break;
+ default:
+ printf ("Unknown Chip Type\n");
+ break;
+ }
+
+ if (info->size >= (1024 * 1024)) {
+ i = 20;
+ } else {
+ i = 10;
+ }
+ printf (" Size: %ld %cB in %d Sectors\n",
+ info->size >> i,
+ (i == 20) ? 'M' : 'k',
+ info->sector_count);
+
+ printf (" Sector Start Addresses:");
+ for (i=0; i<info->sector_count; ++i) {
+ if ((i % 5) == 0)
+ printf ("\n ");
+ printf (" %08lX%s",
+ info->start[i],
+ info->protect[i] ? " (RO)" : " "
+ );
+ }
+ printf ("\n");
+ return;
+}
+
+
+/*-----------------------------------------------------------------------
+ * Get size and other information for a FLASH device.
+ * NOTE: The following code cannot be run from FLASH!
+ */
+static
+ulong flash_get_size (vu_char *addr, flash_info_t *info)
+{
+#define NO_FLASH 0
+
+ vu_char value[2];
+
+ /*
+ * Try to read the manufacturer ID
+ */
+ addr[0] = SCS_READ_CMD;
+ addr[0] = SCS_READ_ID_CMD;
+ value[0] = addr[0];
+ value[1] = addr[2];
+ addr[0] = SCS_READ_CMD;
+
+ PRINTF("Manuf. ID @ 0x%08lx: 0x%02x\n", (ulong)addr, value[0]);
+ switch (value[0]) {
+ case (INTEL_MANUFACT & 0xff):
+ info->flash_id = FLASH_MAN_INTEL;
+ break;
+ default:
+ info->flash_id = FLASH_UNKNOWN;
+ info->sector_count = 0;
+ info->size = 0;
+ return (NO_FLASH);
+ }
+
+ /*
+ * Read the device ID
+ */
+ PRINTF("Device ID @ 0x%08lx: 0x%02x\n", (ulong)(&addr[2]), value[1]);
+ switch (value[1]) {
+ case (INTEL_ID_28F128J3A & 0xff):
+ info->flash_id += FLASH_28F128J3A;
+ info->sector_count = 128;
+ info->size = 16 * 1024 * 1024;
+ break;
+
+ default:
+ info->flash_id = FLASH_UNKNOWN;
+ return (NO_FLASH);
+ }
+
+ if (info->sector_count > CFG_MAX_FLASH_SECT) {
+ printf ("** ERROR: sector count %d > max (%d) **\n",
+ info->sector_count, CFG_MAX_FLASH_SECT);
+ info->sector_count = CFG_MAX_FLASH_SECT;
+ }
+ return (info->size);
+}
+
+
+/*-----------------------------------------------------------------------
+ * Erase the specified sectors in the specified FLASH device
+ */
+int
+flash_erase(flash_info_t *info, int s_first, int s_last)
+{
+ int flag, prot, sect;
+ ulong start, now, last;
+
+ if ((s_first < 0) || (s_first > s_last)) {
+ if (info->flash_id == FLASH_UNKNOWN) {
+ printf ("- missing\n");
+ } else {
+ printf ("- no sectors to erase\n");
+ }
+ return 1;
+ }
+
+ if ((info->flash_id & FLASH_VENDMASK) != FLASH_MAN_INTEL) {
+ printf ("Can erase only Intel flash types - aborted\n");
+ return 1;
+ }
+
+ prot = 0;
+ for (sect=s_first; sect<=s_last; ++sect) {
+ if (info->protect[sect]) {
+ prot++;
+ }
+ }
+
+ if (prot) {
+ printf ("- Warning: %d protected sectors will not be erased!\n",
+ prot);
+ } else {
+ printf ("\n");
+ }
+
+ start = get_timer (0);
+ last = start;
+
+ /*
+ * Start erase on unprotected sectors
+ */
+ for (sect = s_first; sect<=s_last; sect++) {
+ if (info->protect[sect] == 0) { /* not protected */
+ vu_char *addr = (uchar *)(info->start[sect]);
+ vu_char status;
+
+ /*
+ * Disable interrupts which might cause a timeout
+ */
+ flag = disable_interrupts();
+
+ *addr = SCS_CLEAR_STATUS_CMD;
+ *addr = SCS_BLOCK_ERASE_CMD;
+ *addr = SCS_BLOCK_ERASE_RESUME_CMD;
+
+ /*
+ * Re-enable interrupts if necessary
+ */
+ if (flag)
+ enable_interrupts();
+
+ /*
+ * Wait at least 80us - let's wait 1 ms
+ */
+ udelay (1000);
+
+ while (((status = *addr) & SCS_SR7) != SCS_SR7) {
+ if ((now=get_timer(start)) > CFG_FLASH_ERASE_TOUT) {
+ printf ("Timeout\n");
+ *addr = SCS_BLOCK_ERASE_SUSPEND_CMD;
+ *addr = SCS_READ_CMD;
+ return 1;
+ }
+
+ /*
+ * Show that we're waiting
+ */
+ if ((now - last) > 1000) { /* 1 second */
+ putc ('.');
+ last = now;
+ }
+ }
+ *addr = SCS_READ_CMD;
+ }
+ }
+ printf (" done\n");
+ return 0;
+}
+
+
+#ifdef CFG_GEN860T_FLASH_USE_WRITE_BUFFER
+/*
+ * Allocate a flash buffer, fill it with data and write it to the flash.
+ * 0 - OK
+ * 1 - Timeout on buffer request
+ *
+ * NOTE: After the last call to this function, WSM status needs to be checked!
+ */
+static int
+write_flash_buffer8(flash_info_t *info_p, vu_char *src_p, vu_char *dest_p,
+ uint count)
+{
+ vu_char *block_addr_p = NULL;
+ vu_char *start_addr_p = NULL;
+ ulong blocksize = info_p->size / (ulong)info_p->sector_count;
+
+ int i;
+ uint time = get_timer(0);
+
+ PRINTF("%s:%d: src: 0x%p dest: 0x%p count: %d\n",
+ __FUNCTION__, __LINE__, src_p, dest_p, count);
+
+ /*
+ * What block are we in? We already know that the source address is
+ * in the flash address range, but we also can't cross a block boundary.
+ * We assume that the block does not cross a boundary (we'll check before
+ * calling this function).
+ */
+ for (i = 0; i < info_p->sector_count; ++i) {
+ if ( ((ulong)dest_p >= info_p->start[i]) &&
+ ((ulong)dest_p < (info_p->start[i] + blocksize)) ) {
+ PRINTF("%s:%d: Dest addr 0x%p is in block %d @ 0x%.8lx\n",
+ __FUNCTION__, __LINE__, dest_p, i, info_p->start[i]);
+ block_addr_p = (vu_char *)info_p->start[i];
+ break;
+ }
+ }
+
+ /*
+ * Request a buffer
+ */
+ *block_addr_p = SCS_WRITE_BUF_CMD;
+ while ((*block_addr_p & SCS_XSR7) != SCS_XSR7) {
+ if (get_timer(time) > CFG_FLASH_ALLOC_BUFFER_TOUT) {
+ PRINTF("%s:%d: Buffer allocation timeout @ 0x%p (waited %d mS)\n",
+ __FUNCTION__, __LINE__, block_addr_p,
+ CFG_FLASH_ALLOC_BUFFER_TOUT);
+ return 1;
+ }
+ *block_addr_p = SCS_WRITE_BUF_CMD;
+ }
+
+ /*
+ * Fill the buffer with data
+ */
+ start_addr_p = dest_p;
+ *block_addr_p = count - 1; /* flash device wants count - 1 */
+ PRINTF("%s:%d: Fill buffer at block addr 0x%p\n",
+ __FUNCTION__, __LINE__, block_addr_p);
+ for (i = 0; i < count; i++) {
+ *start_addr_p++ = *src_p++;
+ }
+
+ /*
+ * Flush buffer to flash
+ */
+ *block_addr_p = SCS_PROGRAM_RESUME_CMD;
+#if 1
+ time = get_timer(0);
+ while ((*block_addr_p & SCS_SR7) != SCS_SR7) {
+ if (get_timer(time) > CFG_FLASH_WRITE_TOUT) {
+ PRINTF("%s:%d: Write timeout @ 0x%p (waited %d mS)\n",
+ __FUNCTION__, __LINE__, block_addr_p, CFG_FLASH_WRITE_TOUT);
+ return 1;
+ }
+ }
+
+#endif
+ return 0;
+}
+#endif
+
+
+/*-----------------------------------------------------------------------
+ * Copy memory to flash, returns:
+ * 0 - OK
+ * 1 - write timeout
+ * 2 - Flash not erased
+ * 4 - Flash not identified
+ */
+int
+write_buff(flash_info_t *info_p, uchar *src_p, ulong addr, ulong count)
+{
+ int rc = 0;
+#ifdef CFG_GEN860T_FLASH_USE_WRITE_BUFFER
+#define FLASH_WRITE_BUF_SIZE 0x00000020 /* 32 bytes */
+ int i;
+ uint bufs;
+ ulong buf_count;
+ vu_char *sp;
+ vu_char *dp;
+#else
+ ulong wp;
+#endif
+
+ PRINTF("\n%s:%d: src: 0x%.8lx dest: 0x%.8lx size: %d (0x%.8lx)\n",
+ __FUNCTION__, __LINE__, (ulong)src_p, addr, (uint)count, count);
+
+ if (info_p->flash_id == FLASH_UNKNOWN) {
+ return 4;
+ }
+
+#ifdef CFG_GEN860T_FLASH_USE_WRITE_BUFFER
+ sp = src_p;
+ dp = (uchar *)addr;
+
+ /*
+ * For maximum performance, we want to align the start address to
+ * the beginning of a write buffer boundary (i.e. A4-A0 of the
+ * start address = 0). See how many bytes are required to get to a
+ * write-buffer-aligned address. If that number is non-zero, do
+ * non buffered writes of the non-aligned data. By doing non-buffered
+ * writes, we avoid the problem of crossing a block (sector) boundary
+ * with buffered writes.
+ */
+ buf_count = FLASH_WRITE_BUF_SIZE - (addr & (FLASH_WRITE_BUF_SIZE - 1));
+ if (buf_count == FLASH_WRITE_BUF_SIZE) { /* already on a boundary */
+ buf_count = 0;
+ }
+ if (buf_count > count) { /* not a full buffers worth of data to write */
+ buf_count = count;
+ }
+ count -= buf_count;
+
+ PRINTF("%s:%d: Write buffer alignment count = %ld\n",
+ __FUNCTION__, __LINE__, buf_count);
+ while (buf_count-- >= 1) {
+ if ((rc = write_data8(info_p, (ulong)dp++, *sp++)) != 0) {
+ return (rc);
+ }
+ }
+
+ PRINTF("%s:%d: count = %ld\n", __FUNCTION__, __LINE__, count);
+ if (count == 0) { /* all done */
+ PRINTF("%s:%d: Less than 1 buffer (%d) worth of bytes\n",
+ __FUNCTION__, __LINE__, FLASH_WRITE_BUF_SIZE);
+ return (rc);
+ }
+
+ /*
+ * Now that we are write buffer aligned, write full or partial buffers.
+ * The fact that we are write buffer aligned automatically avoids
+ * crossing a block address during a write buffer operation.
+ */
+ bufs = count / FLASH_WRITE_BUF_SIZE;
+ PRINTF("%s:%d: %d (0x%x) buffers to write\n", __FUNCTION__, __LINE__,
+ bufs, bufs);
+ while (bufs >= 1) {
+ rc = write_flash_buffer8(info_p, sp, dp, FLASH_WRITE_BUF_SIZE);
+ if (rc != 0) {
+ PRINTF("%s:%d: ** Error writing buf %d\n",
+ __FUNCTION__, __LINE__, bufs);
+ return (rc);
+ }
+ bufs--;
+ sp += FLASH_WRITE_BUF_SIZE;
+ dp += FLASH_WRITE_BUF_SIZE;
+ }
+
+ /*
+ * Do the leftovers
+ */
+ i = count % FLASH_WRITE_BUF_SIZE;
+ PRINTF("%s:%d: %d (0x%x) leftover bytes\n", __FUNCTION__, __LINE__, i, i);
+ if (i > 0) {
+ rc = write_flash_buffer8(info_p, sp, dp, i);
+ }
+
+ sp = (vu_char*)info_p->start[0];
+ *sp = SCS_READ_CMD;
+ return (rc);
+
+#else
+ wp = addr;
+ while (count-- >= 1) {
+ if((rc = write_data8(info_p, wp++, *src_p++)) != 0)
+ return (rc);
+ }
+ return 0;
+#endif
+}
+
+
+/*-----------------------------------------------------------------------
+ * Write a byte to Flash, returns:
+ * 0 - OK
+ * 1 - write timeout
+ * 2 - Flash not erased
+ */
+static int
+write_data8 (flash_info_t *info, ulong dest, uchar data)
+{
+ vu_char *addr = (vu_char *)dest;
+ vu_char status;
+ ulong start;
+ 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();
+
+ *addr = SCS_PROGRAM_CMD;
+ *addr = data;
+
+ /* re-enable interrupts if necessary */
+ if (flag)
+ enable_interrupts();
+
+ start = get_timer (0);
+
+ while (((status = *addr) & SCS_SR7) != SCS_SR7) {
+ if (get_timer(start) > CFG_FLASH_WRITE_TOUT) {
+ *addr = SCS_READ_CMD;
+ return (1);
+ }
+ }
+ *addr = SCS_READ_CMD;
+ return (0);
+}
+
+/* vim: set ts=4 sw=4 tw=78: */
--- /dev/null
+/*
+ * (C) Copyright 2002
+ * Rich Ireland, Enterasys Networks, rireland@enterasys.com.
+ * Keith Outwater, keith_outwater@mvis.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
+ *
+ */
+
+/*
+ * Virtex2 FPGA configuration support for the GEN860T computer
+ */
+
+#include <common.h>
+#include <virtex2.h>
+#include <command.h>
+#include "fpga.h"
+
+#if (CONFIG_FPGA)
+
+#if 0
+#define GEN860T_FPGA_DEBUG
+#endif
+
+#ifdef GEN860T_FPGA_DEBUG
+#define PRINTF(fmt,args...) printf (fmt ,##args)
+#else
+#define PRINTF(fmt,args...)
+#endif
+
+/*
+ * Port bit numbers for the Selectmap controls
+ */
+#define FPGA_INIT_BIT_NUM 22 /* PB22 */
+#define FPGA_RESET_BIT_NUM 11 /* PC11 */
+#define FPGA_DONE_BIT_NUM 16 /* PB16 */
+#define FPGA_PROGRAM_BIT_NUM 7 /* PA7 */
+
+/* Note that these are pointers to code that is in Flash. They will be
+ * relocated at runtime.
+ */
+Xilinx_Virtex2_Slave_SelectMap_fns fpga_fns = {
+ fpga_pre_config_fn,
+ fpga_pgm_fn,
+ fpga_init_fn,
+ fpga_err_fn,
+ fpga_done_fn,
+ fpga_clk_fn,
+ fpga_cs_fn,
+ fpga_wr_fn,
+ fpga_read_data_fn,
+ fpga_write_data_fn,
+ fpga_busy_fn,
+ fpga_abort_fn,
+ fpga_post_config_fn
+};
+
+Xilinx_desc fpga[CONFIG_FPGA_COUNT] = {
+ { Xilinx_Virtex2,
+ slave_selectmap,
+ XILINX_XC2V3000_SIZE,
+ (void *)&fpga_fns,
+ 0
+ }
+};
+
+/*
+ * Display FPGA revision information
+ */
+void
+print_fpga_revision(void)
+{
+ vu_long *rev_p = (vu_long *)0x60000008;
+
+ printf("FPGA Revision 0x%.8lx"
+ " (Date %.2lx/%.2lx/%.2lx, Status \"%.1lx\", Version %.3lu)\n",
+ *rev_p,
+ ((*rev_p >> 28) & 0xf),
+ ((*rev_p >> 20) & 0xff),
+ ((*rev_p >> 12) & 0xff),
+ ((*rev_p >> 8) & 0xf),
+ (*rev_p & 0xff));
+}
+
+
+/*
+ * Perform a simple test of the FPGA to processor interface using the FPGA's
+ * inverting bus test register. The great thing about doing a read/write
+ * test on a register that inverts it's contents is that you avoid any
+ * problems with bus charging.
+ * Return 0 on failure, 1 on success.
+ */
+int
+test_fpga_ibtr(void)
+{
+ vu_long *ibtr_p = (vu_long *)0x60000010;
+ vu_long readback;
+ vu_long compare;
+ int i;
+ int j;
+ int k;
+ int pass = 1;
+
+ static const ulong bitpattern[] = {
+ 0xdeadbeef, /* magic ID pattern for debug */
+ 0x00000001, /* single bit */
+ 0x00000003, /* two adjacent bits */
+ 0x00000007, /* three adjacent bits */
+ 0x0000000F, /* four adjacent bits */
+ 0x00000005, /* two non-adjacent bits */
+ 0x00000015, /* three non-adjacent bits */
+ 0x00000055, /* four non-adjacent bits */
+ 0xaaaaaaaa, /* alternating 1/0 */
+ };
+
+ for (i = 0; i < 1024; i++) {
+ for (j = 0; j < 31; j++) {
+ for (k = 0; k < sizeof(bitpattern)/sizeof(bitpattern[0]); k++) {
+ *ibtr_p = compare = (bitpattern[k] << j);
+ readback = *ibtr_p;
+ if (readback != ~compare) {
+ printf("%s:%d: FPGA test fail: expected 0x%.8lx"
+ " actual 0x%.8lx\n",
+ __FUNCTION__, __LINE__, ~compare, readback);
+ pass = 0;
+ break;
+ }
+ }
+ if (!pass) break;
+ }
+ if (!pass) break;
+ }
+ if (pass) {
+ printf("FPGA inverting bus test passed\n");
+ print_fpga_revision();
+ }
+ else {
+ printf("** FPGA inverting bus test failed\n");
+ }
+ return pass;
+}
+
+
+/*
+ * Set the active-low FPGA reset signal.
+ */
+void
+fpga_reset(int assert)
+{
+ volatile immap_t *immap = (immap_t *)CFG_IMMR;
+
+ PRINTF("%s:%d: RESET ", __FUNCTION__, __LINE__);
+ if (assert) {
+ immap->im_ioport.iop_pcdat &= ~(0x8000 >> FPGA_RESET_BIT_NUM);
+ PRINTF("asserted\n");
+ }
+ else {
+ immap->im_ioport.iop_pcdat |= (0x8000 >> FPGA_RESET_BIT_NUM);
+ PRINTF("deasserted\n");
+ }
+}
+
+
+/*
+ * Initialize the SelectMap interface. We assume that the mode and the
+ * initial state of all of the port pins have already been set!
+ */
+void
+fpga_selectmap_init(void)
+{
+ PRINTF("%s:%d: Initialize SelectMap interface\n", __FUNCTION__, __LINE__);
+ fpga_pgm_fn(FALSE, FALSE, 0); /* make sure program pin is inactive */
+}
+
+
+/*
+ * Initialize the fpga. Return 1 on success, 0 on failure.
+ */
+int
+gen860t_init_fpga(void)
+{
+ DECLARE_GLOBAL_DATA_PTR;
+
+ int i;
+
+ PRINTF("%s:%d: Initialize FPGA interface (relocation offset = 0x%.8lx)\n",
+ __FUNCTION__, __LINE__, gd->reloc_off);
+ fpga_init(gd->reloc_off);
+ fpga_selectmap_init();
+
+ for(i=0; i < CONFIG_FPGA_COUNT; i++) {
+ PRINTF("%s:%d: Adding fpga %d\n", __FUNCTION__, __LINE__, i);
+ fpga_add(fpga_xilinx, &fpga[i]);
+ }
+ return 1;
+}
+
+
+/*
+ * Set the FPGA's active-low SelectMap program line to the specified level
+ */
+int
+fpga_pgm_fn(int assert, int flush, int cookie)
+{
+ volatile immap_t *immap = (immap_t *)CFG_IMMR;
+
+ PRINTF("%s:%d: FPGA PROGRAM ", __FUNCTION__, __LINE__);
+
+ if (assert) {
+ immap->im_ioport.iop_padat &= ~(0x8000 >> FPGA_PROGRAM_BIT_NUM);
+ PRINTF("asserted\n");
+ }
+ else {
+ immap->im_ioport.iop_padat |= (0x8000 >> FPGA_PROGRAM_BIT_NUM);
+ PRINTF("deasserted\n");
+ }
+ return assert;
+}
+
+
+/*
+ * Test the state of the active-low FPGA INIT line. Return 1 on INIT
+ * asserted (low).
+ */
+int
+fpga_init_fn(int cookie)
+{
+ volatile immap_t *immap = (immap_t *)CFG_IMMR;
+
+ PRINTF("%s:%d: INIT check... ", __FUNCTION__, __LINE__);
+ if(immap->im_cpm.cp_pbdat & (0x80000000 >> FPGA_INIT_BIT_NUM)) {
+ PRINTF("high\n");
+ return 0;
+ }
+ else {
+ PRINTF("low\n");
+ return 1;
+ }
+}
+
+
+/*
+ * Test the state of the active-high FPGA DONE pin
+ */
+int
+fpga_done_fn(int cookie)
+{
+ volatile immap_t *immap = (immap_t *)CFG_IMMR;
+
+ PRINTF("%s:%d: DONE check... ", __FUNCTION__, __LINE__);
+ if (immap->im_cpm.cp_pbdat & (0x80000000 >> FPGA_DONE_BIT_NUM)) {
+ PRINTF("high\n");
+ return FPGA_SUCCESS;
+ }
+ else {
+ PRINTF("low\n");
+ return FPGA_FAIL;
+ }
+}
+
+
+/*
+ * Read FPGA SelectMap data.
+ */
+int
+fpga_read_data_fn(unsigned char *data, int cookie)
+{
+ vu_char *p = (vu_char *)SELECTMAP_BASE;
+
+ *data = *p;
+#if 0
+ PRINTF("%s: Read 0x%x into 0x%p\n", __FUNCTION__, (int)data, data);
+#endif
+ return (int)data;
+}
+
+
+/*
+ * Write data to the FPGA SelectMap port
+ */
+int
+fpga_write_data_fn(unsigned char data, int flush, int cookie)
+{
+ vu_char *p = (vu_char *)SELECTMAP_BASE;
+
+#if 0
+ PRINTF("%s: Write Data 0x%x\n", __FUNCTION__, (int)data);
+#endif
+ *p = data;
+ return (int)data;
+}
+
+
+/*
+ * Abort and FPGA operation
+ */
+int
+fpga_abort_fn(int cookie)
+{
+ PRINTF("%s:%d: FPGA program sequence aborted\n",
+ __FUNCTION__, __LINE__);
+ return FPGA_FAIL;
+}
+
+
+/*
+ * FPGA pre-configuration function. Just make sure that
+ * FPGA reset is asserted to keep the FPGA from starting up after
+ * configuration.
+ */
+int
+fpga_pre_config_fn(int cookie)
+{
+ PRINTF("%s:%d: FPGA pre-configuration\n", __FUNCTION__, __LINE__);
+ fpga_reset(TRUE);
+ return 0;
+}
+
+
+/*
+ * FPGA post configuration function. Blip the FPGA reset line and then see if
+ * the FPGA appears to be running.
+ */
+int
+fpga_post_config_fn(int cookie)
+{
+ int rc;
+
+ PRINTF("%s:%d: FPGA post configuration\n", __FUNCTION__, __LINE__);
+ fpga_reset(TRUE);
+ udelay(1000);
+ fpga_reset(FALSE);
+ udelay (1000);
+
+ /*
+ * Use the FPGA,s inverting bus test register to do a simple test of the
+ * processor interface.
+ */
+ rc = test_fpga_ibtr();
+ return rc;
+}
+
+
+/*
+ * Clock, chip select and write signal assert functions and error check
+ * and busy functions. These are only stubs because the GEN860T selectmap
+ * interface handles sequencing of control signals automatically (it uses
+ * a memory-mapped interface to the FPGA SelectMap port). The design of
+ * the interface guarantees that the SelectMap port cannot be overrun so
+ * no busy check is needed. A configuration error is signalled by INIT
+ * going low during configuration, so there is no need for a separate error
+ * function.
+ */
+int
+fpga_clk_fn(int assert_clk, int flush, int cookie)
+{
+ return assert_clk;
+}
+
+int
+fpga_cs_fn(int assert_cs, int flush, int cookie)
+{
+ return assert_cs;
+}
+
+int
+fpga_wr_fn(int assert_write, int flush, int cookie)
+{
+ return assert_write;
+}
+
+int
+fpga_err_fn(int cookie)
+{
+ return 0;
+}
+
+int
+fpga_busy_fn(int cookie)
+{
+ return 0;
+}
+#endif
+
+/* vim: set ts=4 tw=78 sw=4: */
--- /dev/null
+/*
+ * (C) Copyright 2000
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ * Keith Outwater, keith_outwater@mvis.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 <virtex2.h>
+#include <common.h>
+#include <mpc8xx.h>
+#include <asm/8xx_immap.h>
+#include "beeper.h"
+#include "fpga.h"
+#include "ioport.h"
+
+#ifdef CONFIG_STATUS_LED
+#include <status_led.h>
+#endif
+
+#if defined(CFG_CMD_MII) && defined(CONFIG_MII)
+#include <net.h>
+#endif
+
+#if 0
+#define GEN860T_DEBUG
+#endif
+
+#ifdef GEN860T_DEBUG
+#define PRINTF(fmt,args...) printf (fmt ,##args)
+#else
+#define PRINTF(fmt,args...)
+#endif
+
+/*
+ * The following UPM init tables were generated automatically by
+ * Motorola's MCUINIT program. See the README file for UPM to
+ * SDRAM pin assignments if you want to type this data into
+ * MCUINIT in order to reverse engineer the waveforms.
+ */
+
+/*
+ * UPM initialization tables for MICRON MT48LC16M16A2TG SDRAM devices
+ * (UPMA) and Virtex FPGA SelectMap interface (UPMB).
+ * NOTE that unused areas of the table are used to hold NOP, precharge
+ * and mode register set sequences.
+ *
+ */
+#define UPMA_NOP_ADDR 0x5
+#define UPMA_PRECHARGE_ADDR 0x6
+#define UPMA_MRS_ADDR 0x12
+
+#define UPM_SINGLE_READ_ADDR 0x00
+#define UPM_BURST_READ_ADDR 0x08
+#define UPM_SINGLE_WRITE_ADDR 0x18
+#define UPM_BURST_WRITE_ADDR 0x20
+#define UPM_REFRESH_ADDR 0x30
+
+const uint sdram_upm_table[] = {
+ /* single read (offset 0x00 in upm ram) */
+ 0x0e0fdc04, 0x01adfc04, 0x0fbffc00, 0x1fff5c05,
+ 0xffffffff, 0x0fffffcd, 0x0fff0fce, 0xefcfffff,
+ /* burst read (offset 0x08 in upm ram) */
+ 0x0f0fdc04, 0x00fdfc04, 0xf0fffc00, 0xf0fffc00,
+ 0xf1fffc00, 0xfffffc00, 0xfffffc05, 0xffffffff,
+ 0xffffffff, 0xffffffff, 0x0ffffff4, 0x1f3d5ff4,
+ 0xfffffff4, 0xfffffff5, 0xffffffff, 0xffffffff,
+ /* single write (offset 0x18 in upm ram) */
+ 0x0f0fdc04, 0x00ad3c00, 0x1fff5c05, 0xffffffff,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+ /* burst write (offset 0x20 in upm ram) */
+ 0x0f0fdc00, 0x10fd7c00, 0xf0fffc00, 0xf0fffc00,
+ 0xf1fffc04, 0xfffffc05, 0xffffffff, 0xffffffff,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xfffff7ff,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+ /* refresh (offset 0x30 in upm ram) */
+ 0x1ffddc84, 0xfffffc04, 0xfffffc04, 0xfffffc84,
+ 0xfffffc05, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+ /* exception (offset 0x3C in upm ram) */
+ };
+
+const uint selectmap_upm_table[] = {
+ /* single read (offset 0x00 in upm ram) */
+ 0x88fffc06, 0x00fff404, 0x00fffc04, 0x33fffc00,
+ 0xfffffc05, 0xffffffff, 0xffffffff, 0xffffffff,
+ /* burst read (offset 0x08 in upm ram) */
+ 0xfffffc04, 0xfffffc05, 0xffffffff, 0xffffffff,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+ /* single write (offset 0x18 in upm ram) */
+ 0x88fffc04, 0x00fff400, 0x77fffc05, 0xffffffff,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+ /* burst write (offset 0x20 in upm ram) */
+ 0xfffffc04, 0xfffffc05, 0xffffffff, 0xffffffff,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+ /* refresh (offset 0x30 in upm ram) */
+ 0xfffffc04, 0xfffffc05, 0xffffffff, 0xffffffff,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+ /* exception (offset 0x3C in upm ram) */
+ 0xfffffc05, 0xffffffff, 0xffffffff, 0xffffffff
+};
+
+/*
+ * Check board identity. Always successful (gives information only)
+ */
+int
+checkboard(void)
+{
+ DECLARE_GLOBAL_DATA_PTR;
+
+ unsigned char *s;
+ unsigned char buf[64];
+ int i;
+
+ i = getenv_r("board_id", buf, sizeof(buf));
+ s = (i>0) ? buf : NULL;
+
+ if (s) {
+ printf("%s ", s);
+ } else {
+ printf("<unknown> ");
+ }
+
+ i = getenv_r("serial#", buf, sizeof(buf));
+ s = (i>0) ? buf : NULL;
+
+ if (s) {
+ printf("S/N %s\n", s);
+ } else {
+ printf("S/N <unknown>\n");
+ }
+
+ printf("CPU at %s MHz, ",strmhz(buf, gd->cpu_clk));
+ printf("local bus at %s MHz\n", strmhz(buf, gd->bus_clk));
+ return (0);
+}
+
+/*
+ * Initialize SDRAM
+ */
+long int
+initdram(int board_type)
+{
+ volatile immap_t *immr = (immap_t *)CFG_IMMR;
+ volatile memctl8xx_t *memctl = &immr->im_memctl;
+
+ upmconfig(UPMA,
+ (uint *)sdram_upm_table,
+ sizeof(sdram_upm_table) / sizeof(uint)
+ );
+
+ /*
+ * Setup MAMR register
+ */
+ memctl->memc_mptpr = CFG_MPTPR_1BK_8K;
+ memctl->memc_mamr = CFG_MAMR_8COL & (~(MAMR_PTAE)); /* no refresh yet */
+
+ /*
+ * Map CS1* to SDRAM bank
+ */
+ memctl->memc_or1 = CFG_OR1;
+ memctl->memc_br1 = CFG_BR1;
+
+ /*
+ * Perform SDRAM initialization sequence:
+ * 1. Apply at least one NOP command
+ * 2. 100 uS delay (JEDEC standard says 200 uS)
+ * 3. Issue 4 precharge commands
+ * 4. Perform two refresh cycles
+ * 5. Program mode register
+ *
+ * Program SDRAM for standard operation, sequential burst, burst length
+ * of 4, CAS latency of 2.
+ */
+ memctl->memc_mar = 0x00000000;
+ memctl->memc_mcr = MCR_UPM_A | MCR_OP_RUN | MCR_MB_CS1 |
+ MCR_MLCF(0) | UPMA_NOP_ADDR;
+ udelay(200);
+ memctl->memc_mar = 0x00000000;
+ memctl->memc_mcr = MCR_UPM_A | MCR_OP_RUN | MCR_MB_CS1 |
+ MCR_MLCF(4) | UPMA_PRECHARGE_ADDR;
+
+ memctl->memc_mar = 0x00000000;
+ memctl->memc_mcr = MCR_UPM_A | MCR_OP_RUN | MCR_MB_CS1 |
+ MCR_MLCF(2) | UPM_REFRESH_ADDR;
+
+ memctl->memc_mar = 0x00000088;
+ memctl->memc_mcr = MCR_UPM_A | MCR_OP_RUN | MCR_MB_CS1 |
+ MCR_MLCF(1) | UPMA_MRS_ADDR;
+
+ memctl->memc_mar = 0x00000000;
+ memctl->memc_mcr = MCR_UPM_A | MCR_OP_RUN | MCR_MB_CS1 |
+ MCR_MLCF(0) | UPMA_NOP_ADDR;
+ /*
+ * Enable refresh
+ */
+ memctl->memc_mamr |= MAMR_PTAE;
+
+ return (SDRAM_SIZE);
+}
+
+/*
+ * Disk On Chip (DOC) Millenium initialization.
+ * The DOC lives in the CS2* space
+ */
+#if (CONFIG_COMMANDS & CFG_CMD_DOC)
+extern void
+doc_probe(ulong physadr);
+
+void
+doc_init(void)
+{
+ printf("Probing at 0x%.8x: ", DOC_BASE);
+ doc_probe(DOC_BASE);
+}
+#endif
+
+/*
+ * Miscellaneous intialization
+ */
+int
+misc_init_r (void)
+{
+ volatile immap_t *immr = (immap_t *)CFG_IMMR;
+ volatile memctl8xx_t *memctl = &immr->im_memctl;
+
+ /*
+ * Set up UPMB to handle the Virtex FPGA SelectMap interface
+ */
+ upmconfig(UPMB, (uint *)selectmap_upm_table,
+ sizeof(selectmap_upm_table) / sizeof(uint));
+
+ memctl->memc_mbmr = 0x0;
+
+ config_mpc8xx_ioports(immr);
+
+#if (CONFIG_COMMANDS & CFG_CMD_MII)
+ mii_init();
+#endif
+
+#if (CONFIG_FPGA)
+ gen860t_init_fpga();
+#endif
+ return 0;
+}
+
+/*
+ * Final init hook before entering command loop.
+ */
+int
+last_stage_init(void)
+{
+ unsigned char buf[256];
+ int i;
+
+ /*
+ * Set LEDs here since status LED init code has already run
+ */
+ status_led_set(STATUS_LED_BIT1, STATUS_LED_ON);
+ status_led_set(STATUS_LED_BIT3, STATUS_LED_ON);
+
+ /*
+ * Turn the beeper volume all the way down in case this is a warm
+ * boot.
+ */
+ set_beeper_volume(-64);
+ init_beeper();
+
+ /*
+ * Read the environment to see what to do with the beeper
+ */
+ i = getenv_r("beeper", buf, sizeof(buf));
+ if (i > 0) {
+ do_beeper(buf);
+ }
+ return 0;
+}
+/* vim: set ts=4 sw=4 tw=78 : */
--- /dev/null
+/*
+ * (C) Copyright 2000
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <mpc8xx.h>
+#include <asm/8xx_immap.h>
+#include "ioport.h"
+
+#if 0
+#define IOPORT_DEBUG
+#endif
+
+#ifdef IOPORT_DEBUG
+#define PRINTF(fmt,args...) printf (fmt ,##args)
+#else
+#define PRINTF(fmt,args...)
+#endif
+
+/*
+ * The ioport configuration table.
+ */
+const mpc8xx_iop_conf_t iop_conf_tab[NUM_PORTS][PORT_BITS] = {
+ /*
+ * Port A configuration
+ * Pin Signal Type Active Initial state
+ * PA7 fpgaProgramLowOut Out Low High
+ */
+ { /* conf ppar psor pdir podr pdat pint function */
+ /* N/A */ { 0, 0, 0, 0, 0, 0, 0 }, /* No pin */
+ /* N/A */ { 0, 0, 0, 0, 0, 0, 0 }, /* No pin */
+ /* PA15 */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
+ /* PA14 */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
+ /* PA13 */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
+ /* PA12 */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
+ /* PA11 */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
+ /* PA10 */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
+ /* PA9 */ { 1, 0, 0, 1, 0, 0, 0 }, /* grn bicolor LED 1*/
+ /* PA8 */ { 1, 0, 0, 1, 0, 0, 0 }, /* red bicolor LED 1*/
+ /* PA7 */ { 1, 0, 0, 1, 0, 1, 0 }, /* fpgaProgramLow */
+ /* PA6 */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
+ /* PA5 */ { 1, 0, 0, 1, 0, 0, 0 }, /* grn bicolor LED 0*/
+ /* PA4 */ { 1, 0, 0, 1, 0, 0, 0 }, /* red bicolor LED 0*/
+ /* PA3 */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
+ /* PA2 */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
+ /* PA1 */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
+ /* PA0 */ { 0, 0, 0, 0, 0, 0, 0 } /* */
+ },
+
+ /*
+ * Pin Signal Type Active Initial state
+ * PB14 docBusyLowIn In Low X
+ * PB15 gpio1Sig Out High Low
+ * PB16 fpgaDoneBi In High X
+ * PB17 swBitOkLowOut Out Low Low
+ * PB19 speakerVolSig Out/Hi-Z High/Low High (Hi-Z)
+ * PB22 fpgaInitLowBi In Low X
+ * PB23 batteryOkSig In High X
+ */
+ { /* conf ppar psor pdir podr pdat pint function */
+ /* PB31 */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
+ /* PB30 */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
+ /* PB29 */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
+ /* PB28 */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
+ /* PB27 */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
+ /* PB26 */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
+ /* PB25 */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
+ /* PB24 */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
+ /* PB23 */ { 1, 0, 0, 0, 0, 0, 0 }, /* batteryOk */
+ /* PB22 */ { 1, 0, 0, 0, 0, 0, 0 }, /* fpgaInitLowBi */
+ /* PB21 */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
+ /* PB20 */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
+ /* PB19 */ { 1, 0, 0, 1, 1, 1, 0 }, /* speakerVol */
+ /* PB18 */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
+ /* PB17 */ { 1, 0, 0, 1, 0, 0, 0 }, /* swBitOkLow */
+ /* PB16 */ { 1, 0, 0, 0, 0, 0, 0 }, /* fpgaDone */
+ /* PB15 */ { 1, 0, 0, 1, 0, 0, 0 }, /* gpio1 */
+ /* PB14 */ { 1, 0, 0, 0, 0, 0, 0 } /* docBusyLow */
+ },
+
+ /*
+ * Pin Signal Type Active Initial state
+ * PC4 i2cBus1EnSig Out High High
+ * PC5 i2cBus2EnSig Out High High
+ * PC6 gpio0Sig Out High Low
+ * PC8 i2cBus3EnSig Out High High
+ * PC10 i2cBus4EnSig Out High High
+ * PC11 fpgaResetLowOut Out Low High
+ * PC12 systemBitOkIn In High X
+ * PC15 selfDreqLow In Low X
+ */
+ { /* conf ppar psor pdir podr pdat pint function */
+ /* N/A */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
+ /* N/A */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
+ /* PC15 */ { 1, 0, 0, 0, 0, 0, 0 }, /* selfDreqLowIn */
+ /* PC14 */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
+ /* PC13 */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
+ /* PC12 */ { 1, 0, 0, 0, 0, 0, 0 }, /* systemBitOkIn */
+ /* PC11 */ { 1, 0, 0, 1, 0, 1, 0 }, /* fpgaResetLowOut */
+ /* PC10 */ { 1, 0, 0, 1, 0, 1, 0 }, /* i2cBus4EnSig */
+ /* PC9 */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
+ /* PC8 */ { 1, 0, 0, 1, 0, 1, 0 }, /* i2cBus3EnSig */
+ /* PC7 */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
+ /* PC6 */ { 1, 0, 0, 1, 0, 1, 0 }, /* gpio0 */
+ /* PC5 */ { 1, 0, 0, 1, 0, 1, 0 }, /* i2cBus2EnSig */
+ /* PC4 */ { 1, 0, 0, 1, 0, 1, 0 }, /* i2cBus1EnSig */
+ /* N/A */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
+ /* N/A */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
+ /* N/A */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
+ /* N/A */ { 0, 0, 0, 0, 0, 0, 0 } /* */
+ },
+
+ /* Port D configuration */
+ { /* conf ppar psor pdir podr pdat pint function */
+ /* N/A */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
+ /* N/A */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
+ /* PD15 */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
+ /* PD14 */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
+ /* PD13 */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
+ /* PD12 */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
+ /* PD11 */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
+ /* PD10 */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
+ /* PD9 */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
+ /* PD8 */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
+ /* PD7 */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
+ /* PD6 */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
+ /* PD5 */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
+ /* PD4 */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
+ /* PD3 */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
+ /* N/A */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
+ /* N/A */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
+ /* N/A */ { 0, 0, 0, 0, 0, 0, 0 } /* */
+ }
+};
+
+/*
+ * Configure the MPC8XX I/O ports per the ioport configuration table
+ * (taken from ./cpu/mpc8260/cpu_init.c)
+ */
+void
+config_mpc8xx_ioports(volatile immap_t *immr)
+{
+ int portnum;
+
+ for (portnum = 0; portnum < NUM_PORTS; portnum++) {
+ uint pmsk = 0, ppar = 0, psor = 0, pdir = 0;
+ uint podr = 0, pdat = 0, pint = 0;
+ uint msk = 1;
+ mpc8xx_iop_conf_t *iopc = (mpc8xx_iop_conf_t *)&iop_conf_tab[portnum][0];
+ mpc8xx_iop_conf_t *eiopc = iopc + PORT_BITS;
+
+ /*
+ * For all ports except port B, ignore the two don't care entries
+ * in the configuration tables.
+ */
+ if (portnum != 1) {
+ iopc = (mpc8xx_iop_conf_t *)&iop_conf_tab[portnum][2];
+ }
+
+ /*
+ * NOTE: index 0 refers to pin 17, index 17 refers to pin 0
+ */
+ while (iopc < eiopc) {
+ if (iopc->conf) {
+ pmsk |= msk;
+ if (iopc->ppar) ppar |= msk;
+ if (iopc->psor) psor |= msk;
+ if (iopc->pdir) pdir |= msk;
+ if (iopc->podr) podr |= msk;
+ if (iopc->pdat) pdat |= msk;
+ if (iopc->pint) pint |= msk;
+ }
+ msk <<= 1;
+ iopc++;
+ }
+
+ PRINTF("%s:%d:\n portnum=%d ", __FUNCTION__, __LINE__, portnum);
+#ifdef IOPORT_DEBUG
+ switch(portnum) {
+ case 0: printf("(A)\n"); break;
+ case 1: printf("(B)\n"); break;
+ case 2: printf("(C)\n"); break;
+ case 3: printf("(D)\n"); break;
+ default: printf("(?)\n"); break;
+ }
+#endif
+ PRINTF(" ppar=0x%.8x pdir=0x%.8x podr=0x%.8x\n"
+ " pdat=0x%.8x psor=0x%.8x pint=0x%.8x pmsk=0x%.8x\n",
+ ppar, pdir, podr, pdat, psor, pint, pmsk);
+
+ /*
+ * Have to handle the ioports on a port-by-port basis since there
+ * are three different flavors.
+ */
+ if (pmsk != 0) {
+ uint tpmsk = ~pmsk;
+
+ if (0 == portnum) { /* port A */
+ immr->im_ioport.iop_papar &= tpmsk;
+ immr->im_ioport.iop_padat =
+ (immr->im_ioport.iop_padat & tpmsk) | pdat;
+ immr->im_ioport.iop_padir =
+ (immr->im_ioport.iop_padir & tpmsk) | pdir;
+ immr->im_ioport.iop_paodr =
+ (immr->im_ioport.iop_paodr & tpmsk) | podr;
+ immr->im_ioport.iop_papar |= ppar;
+ }
+ else if (1 == portnum) { /* port B */
+ immr->im_cpm.cp_pbpar &= tpmsk;
+ immr->im_cpm.cp_pbdat = (immr->im_cpm.cp_pbdat & tpmsk) | pdat;
+ immr->im_cpm.cp_pbdir = (immr->im_cpm.cp_pbdir & tpmsk) | pdir;
+ immr->im_cpm.cp_pbodr = (immr->im_cpm.cp_pbodr & tpmsk) | podr;
+ immr->im_cpm.cp_pbpar |= ppar;
+ }
+ else if (2 == portnum) { /* port C */
+ immr->im_ioport.iop_pcpar &= tpmsk;
+ immr->im_ioport.iop_pcdat =
+ (immr->im_ioport.iop_pcdat & tpmsk) | pdat;
+ immr->im_ioport.iop_pcdir =
+ (immr->im_ioport.iop_pcdir & tpmsk) | pdir;
+ immr->im_ioport.iop_pcint =
+ (immr->im_ioport.iop_pcint & tpmsk) | pint;
+ immr->im_ioport.iop_pcso =
+ (immr->im_ioport.iop_pcso & tpmsk) | psor;
+ immr->im_ioport.iop_pcpar |= ppar;
+ }
+ else if (3 == portnum) { /* port D */
+ immr->im_ioport.iop_pdpar &= tpmsk;
+ immr->im_ioport.iop_pddat =
+ (immr->im_ioport.iop_pddat & tpmsk) | pdat;
+ immr->im_ioport.iop_pddir =
+ (immr->im_ioport.iop_pddir & tpmsk) | pdir;
+ immr->im_ioport.iop_pdpar |= ppar;
+ }
+ }
+ }
+
+ PRINTF("%s:%d: Port A:\n papar=0x%.4x padir=0x%.4x"
+ " paodr=0x%.4x\n padat=0x%.4x\n", __FUNCTION__, __LINE__,
+ immr->im_ioport.iop_papar, immr->im_ioport.iop_padir,
+ immr->im_ioport.iop_paodr, immr->im_ioport.iop_padat);
+ PRINTF("%s:%d: Port B:\n pbpar=0x%.8x pbdir=0x%.8x"
+ " pbodr=0x%.8x\n pbdat=0x%.8x\n", __FUNCTION__, __LINE__,
+ immr->im_cpm.cp_pbpar, immr->im_cpm.cp_pbdir,
+ immr->im_cpm.cp_pbodr, immr->im_cpm.cp_pbdat);
+ PRINTF("%s:%d: Port C:\n pcpar=0x%.4x pcdir=0x%.4x"
+ " pcdat=0x%.4x\n pcso=0x%.4x pcint=0x%.4x\n ",
+ __FUNCTION__, __LINE__, immr->im_ioport.iop_pcpar,
+ immr->im_ioport.iop_pcdir, immr->im_ioport.iop_pcdat,
+ immr->im_ioport.iop_pcso, immr->im_ioport.iop_pcint);
+ PRINTF("%s:%d: Port D:\n pdpar=0x%.4x pddir=0x%.4x"
+ " pddat=0x%.4x\n", __FUNCTION__, __LINE__,
+ immr->im_ioport.iop_pdpar, immr->im_ioport.iop_pddir,
+ immr->im_ioport.iop_pddat);
+}
+
+/* vim: set ts=4 sw=4 tw=78: */
--- /dev/null
+/*
+ * Linker command file for the GEN860T board.
+ *
+ * (C) Copyright 2000
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+OUTPUT_ARCH(powerpc)
+SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/local/powerpc-any-elf/lib);
+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)
+ common/dlmalloc.o (.text)
+ lib_ppc/ppcstring.o (.text)
+ lib_generic/vsprintf.o (.text)
+ lib_generic/crc32.o (.text)
+ lib_generic/zlib.o (.text)
+
+/* . = env_offset;
+ common/environment.o(.text) */
+
+ *(.text)
+ *(.fixup)
+ *(.got1)
+ }
+ _etext = .;
+ PROVIDE (etext = .);
+ .rodata :
+ {
+ *(.rodata)
+ *(.rodata1)
+ }
+ .fini : { *(.fini) } =0
+ .ctors : { *(.ctors) }
+ .dtors : { *(.dtors) }
+
+ /*
+ * Read-write section, merged into data segment:
+ */
+ . = (. + 0x00FF) & 0xFFFFFF00;
+ _erotext = .;
+ PROVIDE (erotext = .);
+ .reloc :
+ {
+ *(.got)
+ _GOT2_TABLE_ = .;
+ *(.got2)
+ _FIXUP_TABLE_ = .;
+ *(.fixup)
+ }
+ __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2;
+ __fixup_entries = (. - _FIXUP_TABLE_)>>2;
+
+ .data :
+ {
+ *(.data)
+ *(.data1)
+ *(.sdata)
+ *(.sdata2)
+ *(.dynamic)
+ CONSTRUCTORS
+ }
+ _edata = .;
+ PROVIDE (edata = .);
+
+ __start___ex_table = .;
+ __ex_table : { *(__ex_table) }
+ __stop___ex_table = .;
+
+ . = ALIGN(256);
+ __init_begin = .;
+ .text.init : { *(.text.init) }
+ .data.init : { *(.data.init) }
+ . = ALIGN(256);
+ __init_end = .;
+
+ __bss_start = .;
+ .bss :
+ {
+ *(.sbss) *(.scommon)
+ *(.dynbss)
+ *(.bss)
+ *(COMMON)
+ }
+
+ _end = . ;
+ PROVIDE (end = .);
+}
+
--- /dev/null
+/*
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Marius Groeger <mgroeger@sysgo.de>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+
+#define FLASH_BANK_SIZE 0x800000
+#define MAIN_SECT_SIZE 0x20000
+#define PARAM_SECT_SIZE 0x4000
+
+flash_info_t flash_info[CFG_MAX_FLASH_BANKS];
+
+
+/*-----------------------------------------------------------------------
+ */
+
+ulong flash_init(void)
+{
+ int i, j;
+ ulong size = 0;
+
+ for (i = 0; i < CFG_MAX_FLASH_BANKS; i++)
+ {
+ ulong flashbase = 0;
+ flash_info[i].flash_id =
+ (INTEL_MANUFACT & FLASH_VENDMASK) |
+ (INTEL_ID_28F320B3T & FLASH_TYPEMASK);
+ flash_info[i].size = FLASH_BANK_SIZE;
+ flash_info[i].sector_count = CFG_MAX_FLASH_SECT;
+ memset(flash_info[i].protect, 0, CFG_MAX_FLASH_SECT);
+ if (i == 0)
+ flashbase = PHYS_FLASH_1;
+ else if (i == 1)
+ flashbase = PHYS_FLASH_2;
+ else
+ panic("configured to many flash banks!\n");
+ for (j = 0; j < flash_info[i].sector_count; j++)
+ {
+ if (j <= 7)
+ {
+ flash_info[i].start[j] = flashbase + j * PARAM_SECT_SIZE;
+ }
+ else
+ {
+ flash_info[i].start[j] = flashbase + (j - 7)*MAIN_SECT_SIZE;
+ }
+ }
+ size += flash_info[i].size;
+ }
+
+ /* Protect monitor and environment sectors
+ */
+ flash_protect(FLAG_PROTECT_SET,
+ CFG_FLASH_BASE,
+ CFG_FLASH_BASE + _armboot_end_data - _armboot_start,
+ &flash_info[0]);
+
+ flash_protect(FLAG_PROTECT_SET,
+ CFG_ENV_ADDR,
+ CFG_ENV_ADDR + CFG_ENV_SIZE - 1,
+ &flash_info[0]);
+
+ return size;
+}
+
+/*-----------------------------------------------------------------------
+ */
+void flash_print_info (flash_info_t *info)
+{
+ int i;
+
+ switch (info->flash_id & FLASH_VENDMASK)
+ {
+ case (INTEL_MANUFACT & FLASH_VENDMASK):
+ printf("Intel: ");
+ break;
+ default:
+ printf("Unknown Vendor ");
+ break;
+ }
+
+ switch (info->flash_id & FLASH_TYPEMASK)
+ {
+ case (INTEL_ID_28F320B3T & FLASH_TYPEMASK):
+ printf("28F320F3B (16Mbit)\n");
+ break;
+ default:
+ printf("Unknown Chip Type\n");
+ goto Done;
+ break;
+ }
+
+ printf(" Size: %ld MB in %d Sectors\n",
+ info->size >> 20, info->sector_count);
+
+ printf(" Sector Start Addresses:");
+ for (i = 0; i < info->sector_count; i++)
+ {
+ if ((i % 5) == 0)
+ {
+ printf ("\n ");
+ }
+ printf (" %08lX%s", info->start[i],
+ info->protect[i] ? " (RO)" : " ");
+ }
+ printf ("\n");
+
+Done:
+}
+
+/*-----------------------------------------------------------------------
+ */
+
+int flash_erase (flash_info_t *info, int s_first, int s_last)
+{
+ int flag, prot, sect;
+ int rc = ERR_OK;
+
+ if (info->flash_id == FLASH_UNKNOWN)
+ return ERR_UNKNOWN_FLASH_TYPE;
+
+ if ((s_first < 0) || (s_first > s_last)) {
+ return ERR_INVAL;
+ }
+
+ if ((info->flash_id & FLASH_VENDMASK) !=
+ (INTEL_MANUFACT & FLASH_VENDMASK)) {
+ return ERR_UNKNOWN_FLASH_VENDOR;
+ }
+
+ prot = 0;
+ for (sect=s_first; sect<=s_last; ++sect) {
+ if (info->protect[sect]) {
+ prot++;
+ }
+ }
+ if (prot)
+ return ERR_PROTECTED;
+
+ /*
+ * Disable interrupts which might cause a timeout
+ * here. Remember that our exception vectors are
+ * at address 0 in the flash, and we don't want a
+ * (ticker) exception to happen while the flash
+ * chip is in programming mode.
+ */
+ flag = disable_interrupts();
+
+ /* Start erase on unprotected sectors */
+ for (sect = s_first; sect<=s_last && !ctrlc(); sect++) {
+
+ printf("Erasing sector %2d ... ", sect);
+
+ /* arm simple, non interrupt dependent timer */
+ reset_timer_masked();
+
+ if (info->protect[sect] == 0) { /* not protected */
+ vu_long *addr = (vu_long *)(info->start[sect]);
+
+ *addr = 0x00200020; /* erase setup */
+ *addr = 0x00D000D0; /* erase confirm */
+
+ while ((*addr & 0x00800080) != 0x00800080) {
+ if (get_timer_masked() > CFG_FLASH_ERASE_TOUT) {
+ *addr = 0x00B000B0; /* suspend erase */
+ *addr = 0x00FF00FF; /* reset to read mode */
+ rc = ERR_TIMOUT;
+ goto outahere;
+ }
+ }
+
+ *addr = 0x00FF00FF; /* reset to read mode */
+ }
+ printf("ok.\n");
+ }
+ if (ctrlc())
+ printf("User Interrupt!\n");
+
+outahere:
+
+ /* allow flash to settle - wait 10 ms */
+ udelay_masked(10000);
+
+ if (flag)
+ enable_interrupts();
+
+ return rc;
+}
+
+/*-----------------------------------------------------------------------
+ * Copy memory to flash
+ */
+
+static int write_word (flash_info_t *info, ulong dest, ulong data)
+{
+ vu_long *addr = (vu_long *)dest;
+ ulong barf;
+ int rc = ERR_OK;
+ int flag;
+
+ /* Check if Flash is (sufficiently) erased
+ */
+ if ((*addr & data) != data)
+ return ERR_NOT_ERASED;
+
+ /*
+ * Disable interrupts which might cause a timeout
+ * here. Remember that our exception vectors are
+ * at address 0 in the flash, and we don't want a
+ * (ticker) exception to happen while the flash
+ * chip is in programming mode.
+ */
+ flag = disable_interrupts();
+
+ /* clear status register command */
+ *addr = 0x00500050;
+
+ /* program set-up command */
+ *addr = 0x00400040;
+
+ /* latch address/data */
+ *addr = data;
+
+ /* arm simple, non interrupt dependent timer */
+ reset_timer_masked();
+
+ /* read status register command */
+ *addr = 0x00700070;
+
+ /* wait while polling the status register */
+ while((*addr & 0x00800080) != 0x00800080)
+ {
+ if (get_timer_masked() > CFG_FLASH_WRITE_TOUT) {
+ rc = ERR_TIMOUT;
+ /* suspend program command */
+ *addr = 0x00B000B0;
+ goto outahere;
+ }
+
+ if( *addr & 0x003A003A) { /* check for error */
+ barf = *addr;
+ if( barf & 0x003A0000) {
+ barf >>=16;
+ } else {
+ barf &= 0x0000003A;
+ }
+ printf("\nFlash write error %02lx at address %08lx\n",
+ barf, (unsigned long)dest);
+ if(barf & 0x0002) {
+ printf("Block locked, not erased.\n");
+ rc = ERR_NOT_ERASED;
+ goto outahere;
+ }
+ if(barf & 0x0010) {
+ printf("Programming error.\n");
+ rc = ERR_PROG_ERROR;
+ goto outahere;
+ }
+ if(barf & 0x0008) {
+ printf("Vpp Low error.\n");
+ rc = ERR_PROG_ERROR;
+ goto outahere;
+ }
+ rc = ERR_PROG_ERROR;
+ goto outahere;
+ }
+ }
+
+
+outahere:
+ /* read array command */
+ *addr = 0x00FF00FF;
+
+ if (flag)
+ enable_interrupts();
+
+ return rc;
+}
+
+/*-----------------------------------------------------------------------
+ * Copy memory to flash.
+ */
+
+int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
+{
+ ulong cp, wp, data;
+ int l;
+ int i, 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 << 24);
+ }
+ for (; i<4 && cnt>0; ++i) {
+ data = (data >> 8) | (*src++ << 24);
+ --cnt;
+ ++cp;
+ }
+ for (; cnt==0 && i<4; ++i, ++cp) {
+ data = (data >> 8) | (*(uchar *)cp << 24);
+ }
+
+ if ((rc = write_word(info, wp, data)) != 0) {
+ return (rc);
+ }
+ wp += 4;
+ }
+
+ /*
+ * handle word aligned part
+ */
+ while (cnt >= 4) {
+ data = *((vu_long*)src);
+ if ((rc = write_word(info, wp, data)) != 0) {
+ return (rc);
+ }
+ src += 4;
+ wp += 4;
+ cnt -= 4;
+ }
+
+ if (cnt == 0) {
+ return ERR_OK;
+ }
+
+ /*
+ * handle unaligned tail bytes
+ */
+ data = 0;
+ for (i=0, cp=wp; i<4 && cnt>0; ++i, ++cp) {
+ data = (data >> 8) | (*src++ << 24);
+ --cnt;
+ }
+ for (; i<4; ++i, ++cp) {
+ data = (data >> 8) | (*(uchar *)cp << 24);
+ }
+
+ return write_word(info, wp, data);
+}
--- /dev/null
+/*
+ * (C) Copyright 2000
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
+OUTPUT_ARCH(arm)
+ENTRY(_start)
+SECTIONS
+{
+ . = 0x00000000;
+
+ . = ALIGN(4);
+ .text :
+ {
+ cpu/arm720t/start.o (.text)
+ *(.text)
+ }
+
+ . = ALIGN(4);
+ .rodata : { *(.rodata) }
+
+ . = ALIGN(4);
+ .data : { *(.data) }
+
+ . = ALIGN(4);
+ .got : { *(.got) }
+
+ armboot_end_data = .;
+
+ . = ALIGN(4);
+ .bss : { *(.bss) }
+
+ armboot_end = .;
+}
--- /dev/null
+/*
+ * (C) Copyright 2000
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
+OUTPUT_ARCH(arm)
+ENTRY(_start)
+SECTIONS
+{
+ . = 0x00000000;
+
+ . = ALIGN(4);
+ .text :
+ {
+ cpu/sa1100/start.o (.text)
+ *(.text)
+ }
+
+ . = ALIGN(4);
+ .rodata : { *(.rodata) }
+
+ . = ALIGN(4);
+ .data : { *(.data) }
+
+ . = ALIGN(4);
+ .got : { *(.got) }
+
+ armboot_end_data = .;
+
+ . = ALIGN(4);
+ .bss : { *(.bss) }
+
+ armboot_end = .;
+}
--- /dev/null
+/*
+ * (C) Copyright 2000
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Marius Groeger <mgroeger@sysgo.de>
+ *
+ * Board specific routines for the MBX
+ *
+ * - initialisation
+ * - interface to VPD data (mac address, clock speeds)
+ * - memory controller
+ * - serial io initialisation
+ * - ethernet io initialisation
+ *
+ * -----------------------------------------------------------------
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <commproc.h>
+#include <mpc8xx.h>
+#include "dimm.h"
+#include "vpd.h"
+#include "csr.h"
+
+/* ------------------------------------------------------------------------- */
+
+static const uint sdram_table_40[] = {
+ /* DRAM - single read. (offset 0 in upm RAM)
+ */
+ 0xCFAFC004, 0x0FAFC404, 0x0CAF0C04, 0x30AF0C00,
+ 0xF1BF4805, 0xFFFFC005, 0xFFFFC005, 0xFFFFC005,
+
+ /* DRAM - burst read. (offset 8 in upm RAM)
+ */
+ 0xCFAFC004, 0x0FAFC404, 0x0CAF0C04, 0x03AF0C08,
+ 0x0CAF0C04, 0x03AF0C08, 0x0CAF0C04, 0x03AF0C08,
+ 0x0CAF0C04, 0x30AF0C00, 0xF3BF4805, 0xFFFFC005,
+ 0xFFFFC005, 0xFFFFC005, 0xFFFFC005, 0xFFFFC005,
+
+ /* DRAM - single write. (offset 18 in upm RAM)
+ */
+ 0xCFFF0004, 0x0FFF0404, 0x0CFF0C00, 0x33FF4804,
+ 0xFFFFC005, 0xFFFFC005, 0xFFFFC005, 0xFFFFC005,
+
+ /* DRAM - burst write. (offset 20 in upm RAM)
+ */
+ 0xCFFF0004, 0x0FFF0404, 0x0CFF0C00, 0x03FF0C0C,
+ 0x0CFF0C00, 0x03FF0C0C, 0x0CFF0C00, 0x03FF0C0C,
+ 0x0CFF0C00, 0x33FF4804, 0xFFFFC005, 0xFFFFC005,
+ 0xFFFFC005, 0xFFFFC005, 0xFFFFC005, 0xFFFFC005,
+
+ /* refresh (offset 30 in upm RAM)
+ */
+ 0xFCFFC004, 0xC0FFC004, 0x01FFC004, 0x0FFFC004,
+ 0x3FFFC004, 0xFFFFC005, 0xFFFFC005, 0xFFFFC005,
+ 0xFFFFC005, 0xFFFFC005, 0xFFFFC005, 0xFFFFC005,
+
+ /* exception. (offset 3c in upm RAM)
+ */
+ 0xFFFFC007, 0xFFFFC007, 0xFFFFC007, 0xFFFFC007,
+};
+
+static const uint sdram_table_50[] = {
+ /* DRAM - single read. (offset 0 in upm RAM)
+ */
+ 0xCFAFC004, 0x0FAFC404, 0x0CAF8C04, 0x10AF0C04,
+ 0xF0AF0C00, 0xF3BF4805, 0xFFFFC005, 0xFFFFC005,
+
+ /* DRAM - burst read. (offset 8 in upm RAM)
+ */
+ 0xCFAFC004, 0X0FAFC404, 0X0CAF8C04, 0X00AF0C04,
+ /* 0X07AF0C08, 0X0CAF0C04, 0X01AF0C04, 0X0FAF0C04, */
+ 0X07AF0C08, 0X0CAF0C04, 0X01AF0C04, 0X0FAF0C08,
+ 0X0CAF0C04, 0X01AF0C04, 0X0FAF0C08, 0X0CAF0C04,
+ /* 0X10AF0C04, 0XF0AFC000, 0XF3FF4805, 0XFFFFC005, */
+ 0X10AF0C04, 0XF0AFC000, 0XF3BF4805, 0XFFFFC005,
+
+ /* DRAM - single write. (offset 18 in upm RAM)
+ */
+ 0xCFFF0004, 0x0FFF0404, 0x0CFF0C00, 0x13FF4804,
+ 0xFFFFC004, 0xFFFFC005, 0xFFFFC005, 0xFFFFC005,
+
+ /* DRAM - burst write. (offset 20 in upm RAM)
+ */
+ 0xCFFF0004, 0x0FFF0404, 0x0CFF0C00, 0x03FF0C0C,
+ 0x0CFF0C00, 0x03FF0C0C, 0x0CFF0C00, 0x03FF0C0C,
+ 0x0CFF0C00, 0x13FF4804, 0xFFFFC004, 0xFFFFC005,
+ 0xFFFFC005, 0xFFFFC005, 0xFFFFC005, 0xFFFFC005,
+
+ /* refresh (offset 30 in upm RAM)
+ */
+ 0xFCFFC004, 0xC0FFC004, 0x01FFC004, 0x0FFFC004,
+ 0x1FFFC004, 0xFFFFC004, 0xFFFFC005, 0xFFFFC005,
+ 0xFFFFC005, 0xFFFFC005, 0xFFFFC005, 0xFFFFC005,
+
+ /* exception. (offset 3c in upm RAM)
+ */
+ 0xFFFFC007, 0xFFFFC007, 0xFFFFC007, 0xFFFFC007,
+};
+
+/* ------------------------------------------------------------------------- */
+
+static unsigned int get_reffreq(void);
+static unsigned int board_get_cpufreq(void);
+
+void mbx_init (void)
+{
+ volatile immap_t *immr = (immap_t *) CFG_IMMR;
+ volatile memctl8xx_t *memctl = &immr->im_memctl;
+ ulong speed, refclock, plprcr, sccr;
+ ulong br0_32 = memctl->memc_br0 & 0x400;
+
+ /* real-time clock status and control register */
+ immr->im_sitk.sitk_rtcsck = KAPWR_KEY;
+ immr->im_sit.sit_rtcsc = 0x00C3;
+
+ /* SIEL and SIMASK Registers (see MBX PRG 2-3) */
+ immr->im_siu_conf.sc_simask = 0x00000000;
+ immr->im_siu_conf.sc_siel = 0xAAAA0000;
+ immr->im_siu_conf.sc_tesr = 0xFFFFFFFF;
+
+ /*
+ * Prepare access to i2c bus. The MBX offers 3 devices on the i2c bus:
+ * 1. Vital Product Data (contains clock speeds, MAC address etc, see vpd.h)
+ * 2. RAM Specs (see dimm.h)
+ * 2. DIMM Specs (see dimm.h)
+ */
+ vpd_init ();
+
+ /* system clock and reset control register */
+ immr->im_clkrstk.cark_sccrk = KAPWR_KEY;
+ sccr = immr->im_clkrst.car_sccr;
+ sccr &= SCCR_MASK;
+ sccr |= CFG_SCCR;
+ immr->im_clkrst.car_sccr = sccr;
+
+ speed = board_get_cpufreq ();
+ refclock = get_reffreq ();
+
+#if ((CFG_PLPRCR & PLPRCR_MF_MSK) != 0)
+ plprcr = CFG_PLPRCR;
+#else
+ plprcr = immr->im_clkrst.car_plprcr;
+ plprcr &= PLPRCR_MF_MSK; /* isolate MF field */
+ plprcr |= CFG_PLPRCR; /* reset control bits */
+#endif
+
+#ifdef CFG_USE_OSCCLK /* See doc/README.MBX ! */
+ plprcr |= ((speed + refclock / 2) / refclock - 1) << 20;
+#endif
+
+ immr->im_clkrstk.cark_plprcrk = KAPWR_KEY;
+ immr->im_clkrst.car_plprcr = plprcr;
+
+ /*
+ * preliminary setup of memory controller:
+ * - map Flash, otherwise configuration/status
+ * registers won't be accessible when read
+ * by board_init_f.
+ * - map NVRAM and configuation/status registers.
+ * - map pci registers.
+ * - DON'T map ram yet, this is done in initdram().
+ */
+ switch (speed / 1000000) {
+ case 40:
+ memctl->memc_br0 = 0xFE000000 | br0_32 | 1;
+ memctl->memc_or0 = 0xFF800930;
+ memctl->memc_or4 = CFG_NVRAM_OR | 0x920;
+ memctl->memc_br4 = CFG_NVRAM_BASE | 0x401;
+ break;
+ case 50:
+ memctl->memc_br0 = 0xFE000000 | br0_32 | 1;
+ memctl->memc_or0 = 0xFF800940;
+ memctl->memc_or4 = CFG_NVRAM_OR | 0x930;
+ memctl->memc_br4 = CFG_NVRAM_BASE | 0x401;
+ break;
+ default:
+ hang ();
+ break;
+ }
+#ifdef CONFIG_USE_PCI
+ memctl->memc_or5 = CFG_PCIMEM_OR;
+ memctl->memc_br5 = CFG_PCIMEM_BASE | 0x001;
+ memctl->memc_or6 = CFG_PCIBRIDGE_OR;
+ memctl->memc_br6 = CFG_PCIBRIDGE_BASE | 0x001;
+#endif
+ /*
+ * FIXME: I do not understand why I have to call this to
+ * initialise the control register here before booting from
+ * the PCMCIA card but if I do not the Linux kernel falls
+ * over in a big heap. If you can answer this question I
+ * would like to know about it.
+ */
+ board_ether_init();
+}
+
+void board_serial_init (void)
+{
+ MBX_CSR1 &= ~(CSR1_COM1EN | CSR1_XCVRDIS);
+}
+
+void board_ether_init (void)
+{
+ MBX_CSR1 &= ~(CSR1_EAEN | CSR1_ELEN);
+ MBX_CSR1 |= CSR1_ETEN | CSR1_TPEN | CSR1_FDDIS;
+}
+
+static unsigned int board_get_cpufreq (void)
+{
+#ifndef CONFIG_8xx_GCLK_FREQ
+ vpd_packet_t *packet;
+
+ packet = vpd_find_packet (VPD_PID_ICS);
+ return *((ulong *) packet->data);
+#else
+ return((unsigned int)CONFIG_8xx_GCLK_FREQ );
+#endif /* CONFIG_8xx_GCLK_FREQ */
+}
+
+static unsigned int get_reffreq (void)
+{
+ vpd_packet_t *packet;
+
+ packet = vpd_find_packet (VPD_PID_RCS);
+ return *((ulong *) packet->data);
+}
+
+void board_get_enetaddr (uchar * addr)
+{
+ int i;
+ vpd_packet_t *packet;
+
+ packet = vpd_find_packet (VPD_PID_EA);
+ for (i = 0; i < 6; i++)
+ addr[i] = packet->data[i];
+}
+
+/*
+ * Check Board Identity:
+ */
+
+int checkboard (void)
+{
+ vpd_packet_t *packet;
+ int i;
+ const char *const fmt =
+ "\n *** Warning: Low Battery Status - %s Battery ***";
+
+ puts ("Board: ");
+
+ packet = vpd_find_packet (VPD_PID_PID);
+ for (i = 0; i < packet->size; i++) {
+ serial_putc (packet->data[i]);
+ }
+ packet = vpd_find_packet (VPD_PID_MT);
+ for (i = 0; i < packet->size; i++) {
+ serial_putc (packet->data[i]);
+ }
+ serial_putc ('(');
+ packet = vpd_find_packet (VPD_PID_FAN);
+ for (i = 0; i < packet->size; i++) {
+ serial_putc (packet->data[i]);
+ }
+ serial_putc (')');
+
+ if (!(MBX_CSR2 & SR2_BATGD))
+ printf (fmt, "On-Board");
+ if (!(MBX_CSR2 & SR2_NVBATGD))
+ printf (fmt, "NVRAM");
+
+ serial_putc ('\n');
+
+ return (0);
+}
+
+/* ------------------------------------------------------------------------- */
+
+static ulong get_ramsize (dimm_t * dimm)
+{
+ ulong size = 0;
+
+ if (dimm->fmt == 1 || dimm->fmt == 2 || dimm->fmt == 3
+ || dimm->fmt == 4) {
+ size = (1 << (dimm->n_row + dimm->n_col)) * dimm->n_banks *
+ ((dimm->data_w_hi << 8 | dimm->data_w_lo) / 8);
+ }
+
+ return size;
+}
+
+long int initdram (int board_type)
+{
+ volatile immap_t *immap = (immap_t *) CFG_IMMR;
+ volatile memctl8xx_t *memctl = &immap->im_memctl;
+ unsigned long ram_sz = 0;
+ unsigned long dimm_sz = 0;
+ dimm_t vpd_dimm, vpd_dram;
+ unsigned int speed = board_get_cpufreq () / 1000000;
+
+ if (vpd_read (0xa2, (uchar *) & vpd_dimm, sizeof (vpd_dimm), 0) > 0) {
+ dimm_sz = get_ramsize (&vpd_dimm);
+ }
+ if (vpd_read (0xa6, (uchar *) & vpd_dram, sizeof (vpd_dram), 0) > 0) {
+ ram_sz = get_ramsize (&vpd_dram);
+ }
+
+ /*
+ * Only initialize memory controller when running from FLASH.
+ * When running from RAM, don't touch it.
+ */
+ if ((ulong) initdram & 0xff000000) {
+ ulong dimm_bank;
+ ulong br0_32 = memctl->memc_br0 & 0x400;
+
+ switch (speed) {
+ case 40:
+ upmconfig (UPMA, (uint *) sdram_table_40,
+ sizeof (sdram_table_40) / sizeof (uint));
+ memctl->memc_mptpr = 0x0200;
+ memctl->memc_mamr = dimm_sz ? 0x06801000 : 0x13801000;
+ memctl->memc_or7 = 0xff800930;
+ memctl->memc_br7 = 0xfc000000 | (br0_32 ^ br0_32) | 1;
+ break;
+ case 50:
+ upmconfig (UPMA, (uint *) sdram_table_50,
+ sizeof (sdram_table_50) / sizeof (uint));
+ memctl->memc_mptpr = 0x0200;
+ memctl->memc_mamr = dimm_sz ? 0x08801000 : 0x1880100;
+ memctl->memc_or7 = 0xff800940;
+ memctl->memc_br7 = 0xfc000000 | (br0_32 ^ br0_32) | 1;
+ break;
+ default:
+ hang ();
+ break;
+ }
+
+ /* now map ram and dimm, largest one first */
+ dimm_bank = dimm_sz / 2;
+ if (!dimm_sz) {
+ memctl->memc_or1 = ~(ram_sz - 1) | 0x400;
+ memctl->memc_br1 = CFG_SDRAM_BASE | 0x81;
+ memctl->memc_br2 = 0;
+ memctl->memc_br3 = 0;
+ } else if (ram_sz > dimm_bank) {
+ memctl->memc_or1 = ~(ram_sz - 1) | 0x400;
+ memctl->memc_br1 = CFG_SDRAM_BASE | 0x81;
+ memctl->memc_or2 = ~(dimm_bank - 1) | 0x400;
+ memctl->memc_br2 = (CFG_SDRAM_BASE + ram_sz) | 0x81;
+ memctl->memc_or3 = ~(dimm_bank - 1) | 0x400;
+ memctl->memc_br3 = (CFG_SDRAM_BASE + ram_sz + dimm_bank) \
+ | 0x81;
+ } else {
+ memctl->memc_or2 = ~(dimm_bank - 1) | 0x400;
+ memctl->memc_br2 = CFG_SDRAM_BASE | 0x81;
+ memctl->memc_or3 = ~(dimm_bank - 1) | 0x400;
+ memctl->memc_br3 = (CFG_SDRAM_BASE + dimm_bank) | 0x81;
+ memctl->memc_or1 = ~(ram_sz - 1) | 0x400;
+ memctl->memc_br1 = (CFG_SDRAM_BASE + dimm_sz) | 0x81;
+ }
+ }
+
+ return ram_sz + dimm_sz;
+}
--- /dev/null
+/*
+ * (C) Copyright 2002
+ * Peter De Schrijver (p2@mind.be), Mind Linux Solutions, NV.
+ *
+ * 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 <asm/u-boot.h>
+#include <asm/processor.h>
+#include <common.h>
+#include <command.h>
+#include <configs/ML2.h>
+
+#if (defined CFG_INIT_CHAN1) || (defined CFG_INIT_CHAN2)
+#include <ns16550.h>
+#endif
+
+#if 0
+#include "serial.h"
+#endif
+
+#if (defined CFG_INIT_CHAN1) || (defined CFG_INIT_CHAN2)
+const NS16550_t COM_PORTS[] = { (NS16550_t) CFG_NS16550_COM1,
+ (NS16550_t) CFG_NS16550_COM2 };
+#endif
+
+int
+serial_init (void)
+{
+ DECLARE_GLOBAL_DATA_PTR;
+
+ int clock_divisor = CFG_NS16550_CLK / 16 / gd->baudrate;
+
+#ifdef CFG_INIT_CHAN1
+ (void)NS16550_init(COM_PORTS[0], clock_divisor);
+#endif
+#ifdef CFG_INIT_CHAN2
+ (void)NS16550_init(COM_PORTS[1], clock_divisor);
+#endif
+ return 0;
+
+}
+
+void
+serial_putc(const char c)
+{
+ if (c == '\n')
+ NS16550_putc(COM_PORTS[CFG_DUART_CHAN], '\r');
+
+ NS16550_putc(COM_PORTS[CFG_DUART_CHAN], c);
+}
+
+int
+serial_getc(void)
+{
+ return NS16550_getc(COM_PORTS[CFG_DUART_CHAN]);
+}
+
+int
+serial_tstc(void)
+{
+ return NS16550_tstc(COM_PORTS[CFG_DUART_CHAN]);
+}
+
+void
+serial_setbrg (void)
+{
+ DECLARE_GLOBAL_DATA_PTR;
+
+ int clock_divisor = CFG_NS16550_CLK / 16 / gd->baudrate;
+
+#ifdef CFG_INIT_CHAN1
+ NS16550_reinit(COM_PORTS[0], clock_divisor);
+#endif
+#ifdef CFG_INIT_CHAN2
+ NS16550_reinit(COM_PORTS[1], clock_divisor);
+#endif
+}
+
+void
+serial_puts (const char *s)
+{
+ while (*s) {
+ serial_putc (*s++);
+ }
+}
+
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+void
+kgdb_serial_init(void)
+{
+}
+
+void
+putDebugChar (int c)
+{
+ serial_putc (c);
+}
+
+void
+putDebugStr (const char *str)
+{
+ serial_puts (str);
+}
+
+int
+getDebugChar (void)
+{
+ return serial_getc();
+}
+
+void
+kgdb_interruptible (int yes)
+{
+ return;
+}
+#endif /* CFG_CMD_KGDB */
--- /dev/null
+/*
+ *
+ * (C) Copyright 2000
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * (C) Copyright 2001
+ * James Dougherty (jfd@cs.stanford.edu)
+ *
+ * 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
+ */
+
+/*
+ * PCI Configuration space access support for MPC824x/MPC107 PCI Bridge
+ */
+#include <common.h>
+#include <mpc824x.h>
+#include <pci.h>
+
+#include "mousse.h"
+
+/*
+ * Promise ATA/66 support.
+ */
+#define XFER_PIO_4 0x0C /* 0000|1100 */
+#define XFER_PIO_3 0x0B /* 0000|1011 */
+#define XFER_PIO_2 0x0A /* 0000|1010 */
+#define XFER_PIO_1 0x09 /* 0000|1001 */
+#define XFER_PIO_0 0x08 /* 0000|1000 */
+#define XFER_PIO_SLOW 0x00 /* 0000|0000 */
+
+/* Promise Regs */
+#define REG_A 0x01
+#define REG_B 0x02
+#define REG_C 0x04
+#define REG_D 0x08
+
+void
+pdc202xx_decode_registers (unsigned char registers, unsigned char value)
+{
+ unsigned char bit = 0, bit1 = 0, bit2 = 0;
+ switch(registers) {
+ case REG_A:
+ bit2 = 0;
+ printf(" A Register ");
+ if (value & 0x80) printf("SYNC_IN ");
+ if (value & 0x40) printf("ERRDY_EN ");
+ if (value & 0x20) printf("IORDY_EN ");
+ if (value & 0x10) printf("PREFETCH_EN ");
+ if (value & 0x08) { printf("PA3 ");bit2 |= 0x08; }
+ if (value & 0x04) { printf("PA2 ");bit2 |= 0x04; }
+ if (value & 0x02) { printf("PA1 ");bit2 |= 0x02; }
+ if (value & 0x01) { printf("PA0 ");bit2 |= 0x01; }
+ printf("PIO(A) = %d ", bit2);
+ break;
+ case REG_B:
+ bit1 = 0;bit2 = 0;
+ printf(" B Register ");
+ if (value & 0x80) { printf("MB2 ");bit1 |= 0x80; }
+ if (value & 0x40) { printf("MB1 ");bit1 |= 0x40; }
+ if (value & 0x20) { printf("MB0 ");bit1 |= 0x20; }
+ printf("DMA(B) = %d ", bit1 >> 5);
+ if (value & 0x10) printf("PIO_FORCED/PB4 ");
+ if (value & 0x08) { printf("PB3 ");bit2 |= 0x08; }
+ if (value & 0x04) { printf("PB2 ");bit2 |= 0x04; }
+ if (value & 0x02) { printf("PB1 ");bit2 |= 0x02; }
+ if (value & 0x01) { printf("PB0 ");bit2 |= 0x01; }
+ printf("PIO(B) = %d ", bit2);
+ break;
+ case REG_C:
+ bit2 = 0;
+ printf(" C Register ");
+ if (value & 0x80) printf("DMARQp ");
+ if (value & 0x40) printf("IORDYp ");
+ if (value & 0x20) printf("DMAR_EN ");
+ if (value & 0x10) printf("DMAW_EN ");
+
+ if (value & 0x08) { printf("MC3 ");bit2 |= 0x08; }
+ if (value & 0x04) { printf("MC2 ");bit2 |= 0x04; }
+ if (value & 0x02) { printf("MC1 ");bit2 |= 0x02; }
+ if (value & 0x01) { printf("MC0 ");bit2 |= 0x01; }
+ printf("DMA(C) = %d ", bit2);
+ break;
+ case REG_D:
+ printf(" D Register ");
+ break;
+ default:
+ return;
+ }
+ printf("\n %s ", (registers & REG_D) ? "DP" :
+ (registers & REG_C) ? "CP" :
+ (registers & REG_B) ? "BP" :
+ (registers & REG_A) ? "AP" : "ERROR");
+ for (bit=128;bit>0;bit/=2)
+ printf("%s", (value & bit) ? "1" : "0");
+ printf("\n");
+}
+
+/*
+ * Promise ATA/66 Support: configure Promise ATA66 card in specified mode.
+ */
+int
+pdc202xx_tune_chipset (pci_dev_t dev, int drive, unsigned char speed)
+{
+ unsigned short drive_conf;
+ int err = 0;
+ unsigned char drive_pci, AP, BP, CP, DP;
+ unsigned char TA = 0, TB = 0;
+
+ switch (drive) {
+ case 0: drive_pci = 0x60; break;
+ case 1: drive_pci = 0x64; break;
+ case 2: drive_pci = 0x68; break;
+ case 3: drive_pci = 0x6c; break;
+ default: return -1;
+ }
+
+ pci_read_config_word(dev, drive_pci, &drive_conf);
+ pci_read_config_byte(dev, (drive_pci), &AP);
+ pci_read_config_byte(dev, (drive_pci)|0x01, &BP);
+ pci_read_config_byte(dev, (drive_pci)|0x02, &CP);
+ pci_read_config_byte(dev, (drive_pci)|0x03, &DP);
+
+ if ((AP & 0x0F) || (BP & 0x07)) {
+ /* clear PIO modes of lower 8421 bits of A Register */
+ pci_write_config_byte(dev, (drive_pci), AP & ~0x0F);
+ pci_read_config_byte(dev, (drive_pci), &AP);
+
+ /* clear PIO modes of lower 421 bits of B Register */
+ pci_write_config_byte(dev, (drive_pci)|0x01, BP & ~0x07);
+ pci_read_config_byte(dev, (drive_pci)|0x01, &BP);
+
+ pci_read_config_byte(dev, (drive_pci), &AP);
+ pci_read_config_byte(dev, (drive_pci)|0x01, &BP);
+ }
+
+ pci_read_config_byte(dev, (drive_pci), &AP);
+ pci_read_config_byte(dev, (drive_pci)|0x01, &BP);
+ pci_read_config_byte(dev, (drive_pci)|0x02, &CP);
+
+ switch(speed) {
+ case XFER_PIO_4: TA = 0x01; TB = 0x04; break;
+ case XFER_PIO_3: TA = 0x02; TB = 0x06; break;
+ case XFER_PIO_2: TA = 0x03; TB = 0x08; break;
+ case XFER_PIO_1: TA = 0x05; TB = 0x0C; break;
+ case XFER_PIO_0:
+ default: TA = 0x09; TB = 0x13; break;
+ }
+
+ pci_write_config_byte(dev, (drive_pci), AP|TA);
+ pci_write_config_byte(dev, (drive_pci)|0x01, BP|TB);
+
+ pci_read_config_byte(dev, (drive_pci), &AP);
+ pci_read_config_byte(dev, (drive_pci)|0x01, &BP);
+ pci_read_config_byte(dev, (drive_pci)|0x02, &CP);
+ pci_read_config_byte(dev, (drive_pci)|0x03, &DP);
+
+
+#ifdef PDC202XX_DEBUG
+ pdc202xx_decode_registers(REG_A, AP);
+ pdc202xx_decode_registers(REG_B, BP);
+ pdc202xx_decode_registers(REG_C, CP);
+ pdc202xx_decode_registers(REG_D, DP);
+#endif
+ return err;
+}
+/*
+ * Show/Init PCI devices on the specified bus number.
+ */
+
+void pci_mousse_fixup_irq(struct pci_controller *hose, pci_dev_t dev)
+{
+ unsigned int line;
+
+ switch(PCI_DEV(dev)) {
+ case 0x0d:
+ line = 0x00000101;
+ break;
+
+ case 0x0e:
+ default:
+ line = 0x00000303;
+ break;
+ }
+
+ pci_write_config_dword(dev, PCI_INTERRUPT_LINE, line);
+}
+
+void pci_mousse_setup_pdc202xx(struct pci_controller *hose, pci_dev_t dev,
+ struct pci_config_table *_)
+{
+ unsigned short vendorId;
+ unsigned int mbar0, cmd;
+ int bar, a;
+
+ pci_read_config_word(dev, PCI_VENDOR_ID, &vendorId);
+
+ if(vendorId == PCI_VENDOR_ID_PROMISE || vendorId == PCI_VENDOR_ID_CMD){
+ /* PDC 202xx card is handled differently, it is a bootable
+ * device and needs all 5 MBAR's configured
+ */
+ for(bar = 0; bar < 5; bar++){
+ pci_read_config_dword(dev, PCI_BASE_ADDRESS_0+bar*4, &mbar0);
+ pci_write_config_dword(dev, PCI_BASE_ADDRESS_0+bar*4, ~0);
+ pci_read_config_dword(dev, PCI_BASE_ADDRESS_0+bar*4, &mbar0);
+#ifdef DEBUG
+ printf(" ATA_bar[%d] = %dbytes\n", bar,
+ ~(mbar0 & PCI_BASE_ADDRESS_MEM_MASK) + 1);
+#endif
+ }
+
+ /* Program all BAR's */
+ pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, PROMISE_MBAR0);
+ pci_write_config_dword(dev, PCI_BASE_ADDRESS_1, PROMISE_MBAR1);
+ pci_write_config_dword(dev, PCI_BASE_ADDRESS_2, PROMISE_MBAR2);
+ pci_write_config_dword(dev, PCI_BASE_ADDRESS_3, PROMISE_MBAR3);
+ pci_write_config_dword(dev, PCI_BASE_ADDRESS_4, PROMISE_MBAR4);
+ pci_write_config_dword(dev, PCI_BASE_ADDRESS_5, PROMISE_MBAR5);
+
+ for(bar = 0; bar < 5; bar++){
+ pci_read_config_dword(dev, PCI_BASE_ADDRESS_0+bar*4, &mbar0);
+#ifdef DEBUG
+ printf(" ATA_bar[%d]@0x%x\n", bar, mbar0);
+#endif
+ }
+
+ /* Enable ROM Expansion base */
+ pci_write_config_dword(dev, PCI_ROM_ADDRESS, PROMISE_MBAR5|1);
+
+ /* Io enable, Memory enable, master enable */
+ pci_read_config_dword(dev, PCI_COMMAND, &cmd);
+ cmd &= ~0xffff0000;
+ cmd |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY | PCI_COMMAND_IO;
+ pci_write_config_dword(dev, PCI_COMMAND, cmd);
+
+ /* Breath some life into the controller */
+ for( a = 0; a < 4; a++)
+ pdc202xx_tune_chipset(dev, a, XFER_PIO_0);
+ }
+}
+
+static struct pci_config_table pci_sandpoint_config_table[] = {
+ { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, 0x00, 0x0e, 0x00,
+ pci_mousse_setup_pdc202xx },
+#ifndef CONFIG_PCI_PNP
+ { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, 0x00, 0x0d, 0x00,
+ pci_cfgfunc_config_device, {PCI_ENET_IOADDR,
+ PCI_ENET_MEMADDR,
+ PCI_COMMAND_MEMORY |
+ PCI_COMMAND_MASTER}},
+ { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
+ pci_cfgfunc_config_device, {PCI_SLOT_IOADDR,
+ PCI_SLOT_MEMADDR,
+ PCI_COMMAND_MEMORY |
+ PCI_COMMAND_MASTER}},
+#endif
+ { }
+};
+
+struct pci_controller hose = {
+ config_table: pci_sandpoint_config_table,
+ fixup_irq: pci_mousse_fixup_irq,
+};
+
+void pci_init(void)
+{
+ pci_mpc824x_init(&hose);
+}
--- /dev/null
+/*
+ * (C) Copyright 2001
+ * Denis Peter, MPL AG Switzerland, d.peter@mpl.ch
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ */
+
+#include <common.h>
+#include <command.h>
+#include <video_fb.h>
+#include "common_util.h"
+#include <asm/processor.h>
+#include <i2c.h>
+#include <devices.h>
+#include <pci.h>
+
+extern int gunzip (void *, int, unsigned char *, int *);
+extern int mem_test(unsigned long start, unsigned long ramsize, int quiet);
+
+#define I2C_BACKUP_ADDR 0x7C00 /* 0x200 bytes for backup */
+#define IMAGE_SIZE 0x80000
+
+extern flash_info_t flash_info[]; /* info for FLASH chips */
+
+image_header_t header;
+
+
+
+int mpl_prg(unsigned long src,unsigned long size)
+{
+ unsigned long start;
+ flash_info_t *info;
+ int i,rc;
+ unsigned long *magic = (unsigned long *)src;
+
+ info = &flash_info[0];
+ start = 0 - size;
+ for(i=info->sector_count-1;i>0;i--)
+ {
+ info->protect[i] = 0; /* unprotect this sector */
+ if(start>=info->start[i])
+ break;
+ }
+ /* set-up flash location */
+ /* now erase flash */
+ if(magic[0]!=IH_MAGIC) {
+ printf("Bad Magic number\n");
+ return -1;
+ }
+ printf("Erasing at %lx (sector %d) (start %lx)\n",
+ start,i,info->start[i]);
+ flash_erase (info, i, info->sector_count-1);
+ printf("flash erased, programming from 0x%lx 0x%lx Bytes\n",src,size);
+ if ((rc = flash_write ((uchar *)src, start, size)) != 0) {
+ puts ("ERROR ");
+ flash_perror (rc);
+ return (1);
+ }
+ puts ("OK programming done\n");
+ return 0;
+}
+
+
+int mpl_prg_image(unsigned long ld_addr)
+{
+ unsigned long data,len,checksum;
+ image_header_t *hdr=&header;
+ /* Copy header so we can blank CRC field for re-calculation */
+ memcpy (&header, (char *)ld_addr, sizeof(image_header_t));
+ if (hdr->ih_magic != IH_MAGIC) {
+ printf ("Bad Magic Number\n");
+ return 1;
+ }
+ print_image_hdr(hdr);
+ if (hdr->ih_os != IH_OS_U_BOOT) {
+ printf ("No U-Boot Image\n");
+ return 1;
+ }
+ if (hdr->ih_type != IH_TYPE_FIRMWARE) {
+ printf ("No Firmware Image\n");
+ return 1;
+ }
+ data = (ulong)&header;
+ len = sizeof(image_header_t);
+ checksum = hdr->ih_hcrc;
+ hdr->ih_hcrc = 0;
+ if (crc32 (0, (char *)data, len) != checksum) {
+ printf ("Bad Header Checksum\n");
+ return 1;
+ }
+ data = ld_addr + sizeof(image_header_t);
+ len = hdr->ih_size;
+ printf ("Verifying Checksum ... ");
+ if (crc32 (0, (char *)data, len) != hdr->ih_dcrc) {
+ printf ("Bad Data CRC\n");
+ return 1;
+ }
+ switch (hdr->ih_comp) {
+ case IH_COMP_NONE:
+ break;
+ case IH_COMP_GZIP:
+ printf (" Uncompressing ... ");
+ if (gunzip ((void *)(data+0x100000), 0x400000,
+ (uchar *)data, (int *)&len) != 0) {
+ printf ("GUNZIP ERROR\n");
+ return 1;
+ }
+ data+=0x100000;
+ break;
+ default:
+ printf (" Unimplemented compression type %d\n", hdr->ih_comp);
+ return 1;
+ }
+
+ printf (" OK\n");
+ return(mpl_prg(data,len));
+}
+
+
+void get_backup_values(backup_t *buf)
+{
+ i2c_read(CFG_DEF_EEPROM_ADDR, I2C_BACKUP_ADDR,2,(void *)buf,sizeof(backup_t));
+}
+
+void set_backup_values(int overwrite)
+{
+ backup_t back;
+ int i;
+
+ get_backup_values(&back);
+ if(!overwrite) {
+ if(strncmp(back.signature,"MPL\0",4)==0) {
+ printf("Not possible to write Backup\n");
+ return;
+ }
+ }
+ memcpy(back.signature,"MPL\0",4);
+ i=getenv_r("serial#",back.serial_name,16);
+ if(i==0) {
+ printf("Not possible to write Backup\n");
+ return;
+ }
+ back.serial_name[16]=0;
+ i=getenv_r("ethaddr",back.eth_addr,20);
+ if(i==0) {
+ printf("Not possible to write Backup\n");
+ return;
+ }
+ back.eth_addr[20]=0;
+ i2c_write(CFG_DEF_EEPROM_ADDR, I2C_BACKUP_ADDR,2,(void *)&back,sizeof(backup_t));
+}
+
+void clear_env_values(void)
+{
+ backup_t back;
+ unsigned char env_crc[4];
+
+ memset(&back,0xff,sizeof(backup_t));
+ memset(env_crc,0x00,4);
+ i2c_write(CFG_DEF_EEPROM_ADDR,I2C_BACKUP_ADDR,2,(void *)&back,sizeof(backup_t));
+ i2c_write(CFG_DEF_EEPROM_ADDR,CFG_ENV_OFFSET,2,(void *)env_crc,4);
+}
+
+/*
+ * check crc of "older" environment
+ */
+int check_env_old_size(ulong oldsize)
+{
+ ulong crc, len, new;
+ unsigned off;
+ uchar buf[64];
+
+ /* read old CRC */
+ eeprom_read (CFG_DEF_EEPROM_ADDR,
+ CFG_ENV_OFFSET,
+ (uchar *)&crc, sizeof(ulong));
+
+ new = 0;
+ len = oldsize;
+ off = sizeof(long);
+ len = oldsize-off;
+ while (len > 0) {
+ int n = (len > sizeof(buf)) ? sizeof(buf) : len;
+
+ eeprom_read (CFG_DEF_EEPROM_ADDR, CFG_ENV_OFFSET+off, buf, n);
+ new = crc32 (new, buf, n);
+ len -= n;
+ off += n;
+ }
+
+ return (crc == new);
+}
+
+static ulong oldsizes[] = {
+ 0x200,
+ 0x800,
+ 0
+};
+
+void copy_old_env(ulong size)
+{
+ uchar name_buf[64];
+ uchar value_buf[0x800];
+ uchar c;
+ ulong len;
+ unsigned off;
+ uchar *name, *value;
+
+ name=&name_buf[0];
+ value=&value_buf[0];
+ len=size;
+ off = sizeof(long);
+ while (len > off) {
+ eeprom_read (CFG_DEF_EEPROM_ADDR, CFG_ENV_OFFSET+off, &c, 1);
+ if(c != '=') {
+ *name++=c;
+ off++;
+ }
+ else {
+ *name++='\0';
+ off++;
+ do {
+ eeprom_read (CFG_DEF_EEPROM_ADDR, CFG_ENV_OFFSET+off, &c, 1);
+ *value++=c;
+ off++;
+ if(c == '\0')
+ break;
+ } while(len > off);
+ name=&name_buf[0];
+ value=&value_buf[0];
+ if(strncmp(name,"baudrate",8)!=0) {
+ setenv(name,value);
+ }
+
+ }
+ }
+}
+
+
+void check_env(void)
+{
+ unsigned char *s;
+ int i=0;
+ char buf[32];
+ backup_t back;
+
+ s=getenv("serial#");
+ if(!s) {
+ while(oldsizes[i]) {
+ if(check_env_old_size(oldsizes[i]))
+ break;
+ i++;
+ }
+ if(!oldsizes[i]) {
+ /* no old environment has been found */
+ get_backup_values (&back);
+ if (strncmp (back.signature, "MPL\0", 4) == 0) {
+ sprintf (buf, "%s", back.serial_name);
+ setenv ("serial#", buf);
+ sprintf (buf, "%s", back.eth_addr);
+ setenv ("ethaddr", buf);
+ printf ("INFO: serial# and ethaddr recovered, use saveenv\n");
+ return;
+ }
+ }
+ else {
+ copy_old_env(oldsizes[i]);
+ printf ("INFO: old environment ajusted, use saveenv\n");
+ }
+ }
+ else {
+ /* check if back up is set */
+ get_backup_values(&back);
+ if(strncmp(back.signature,"MPL\0",4)!=0) {
+ set_backup_values(0);
+ }
+ }
+}
+
+
+
+extern device_t *stdio_devices[];
+extern char *stdio_names[];
+
+void show_stdio_dev(void)
+{
+ /* Print informations */
+ printf ("In: ");
+ if (stdio_devices[stdin] == NULL) {
+ printf ("No input devices available!\n");
+ } else {
+ printf ("%s\n", stdio_devices[stdin]->name);
+ }
+
+ printf ("Out: ");
+ if (stdio_devices[stdout] == NULL) {
+ printf ("No output devices available!\n");
+ } else {
+ printf ("%s\n", stdio_devices[stdout]->name);
+ }
+
+ printf ("Err: ");
+ if (stdio_devices[stderr] == NULL) {
+ printf ("No error devices available!\n");
+ } else {
+ printf ("%s\n", stdio_devices[stderr]->name);
+ }
+}
+
+/* ------------------------------------------------------------------------- */
+
+ /* switches the cs0 and the cs1 to the locations.
+ When boot is TRUE, the the mapping is switched
+ to the boot configuration, If it is FALSE, the
+ flash will be switched in the boot area */
+
+#undef SW_CS_DBG
+#ifdef SW_CS_DBG
+#define SW_CS_PRINTF(fmt,args...) printf (fmt ,##args)
+#else
+#define SW_CS_PRINTF(fmt,args...)
+#endif
+
+
+int switch_cs(unsigned char boot)
+{
+ unsigned long pbcr;
+ mtdcr(ebccfga, pb0cr); /* get cs0 config reg */
+ pbcr = mfdcr(ebccfgd);
+ if((pbcr&0x00002000)==0) {
+ /* we need only to switch if boot from MPS */
+ /*printf(" MPS boot mode detected. ");*/
+ /* printf("cs0 cfg: %lx\n",pbcr); */
+ if(boot) {
+ /* switch to boot configuration */
+ /* this is a 8bit boot, switch cs0 to flash location */
+ SW_CS_PRINTF("switch to boot mode (MPS on High address\n");
+ pbcr&=0x000FFFFF; /*mask base address of the cs0 */
+ pbcr|=(FLASH_BASE0_PRELIM & 0xFFF00000);
+ mtdcr(ebccfga, pb0cr);
+ mtdcr(ebccfgd, pbcr);
+ SW_CS_PRINTF(" new cs0 cfg: %lx\n",pbcr);
+ mtdcr(ebccfga, pb1cr); /* get cs1 config reg (flash) */
+ pbcr = mfdcr(ebccfgd);
+ SW_CS_PRINTF(" old cs1 cfg: %lx\n",pbcr);
+ pbcr&=0x000FFFFF; /*mask base address of the cs1 */
+ pbcr|=(MULTI_PURPOSE_SOCKET_ADDR & 0xFFF00000);
+ mtdcr(ebccfga, pb1cr);
+ mtdcr(ebccfgd, pbcr);
+ SW_CS_PRINTF(" new cs1 cfg: %lx, MPS is on High Address\n",pbcr);
+ }
+ else
+ {
+ /* map flash to boot area, */
+ SW_CS_PRINTF("map Flash to boot area\n");
+ pbcr&=0x000FFFFF; /*mask base address of the cs0 */
+ pbcr|=(MULTI_PURPOSE_SOCKET_ADDR & 0xFFF00000);
+ mtdcr(ebccfga, pb0cr);
+ mtdcr(ebccfgd, pbcr);
+ SW_CS_PRINTF(" new cs0 cfg: %lx\n",pbcr);
+ mtdcr(ebccfga, pb1cr); /* get cs1 config reg (flash) */
+ pbcr = mfdcr(ebccfgd);
+ SW_CS_PRINTF(" cs1 cfg: %lx\n",pbcr);
+ pbcr&=0x000FFFFF; /*mask base address of the cs1 */
+ pbcr|=(FLASH_BASE0_PRELIM & 0xFFF00000);
+ mtdcr(ebccfga, pb1cr);
+ mtdcr(ebccfgd, pbcr);
+ SW_CS_PRINTF(" new cs1 cfg: %lx Flash is on High Address\n",pbcr);
+ }
+ return 1;
+ }
+ else {
+ SW_CS_PRINTF("Normal boot, no switching necessary\n");
+ return 0;
+ }
+}
+
+
+int do_mplcommon(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+ ulong size,src,ld_addr;
+ int result;
+ backup_t back;
+ char sw;
+ src = MULTI_PURPOSE_SOCKET_ADDR;
+ size = IMAGE_SIZE;
+
+ if (strcmp(argv[1], "flash") == 0)
+ {
+ sw = switch_cs(0); /* Switch flash to normal location */
+#if (CONFIG_COMMANDS & CFG_CMD_FDC)
+ if (strcmp(argv[2], "floppy") == 0) {
+ char *local_args[3];
+ extern int do_fdcboot (cmd_tbl_t *, int, int, char *[]);
+ printf ("\nupdating bootloader image from floppy\n");
+ local_args[0] = argv[0];
+ if(argc==4) {
+ local_args[1] = argv[3];
+ local_args[2] = NULL;
+ ld_addr=simple_strtoul(argv[3], NULL, 16);
+ result=do_fdcboot(cmdtp, 0, 2, local_args);
+ }
+ else {
+ local_args[1] = NULL;
+ ld_addr=CFG_LOAD_ADDR;
+ result=do_fdcboot(cmdtp, 0, 1, local_args);
+ }
+ result=mpl_prg_image(ld_addr);
+ switch_cs(sw); /* Switch flash back */
+ return result;
+ }
+#endif /* (CONFIG_COMMANDS & CFG_CMD_FDC) */
+ if (strcmp(argv[2], "mem") == 0) {
+ if(argc==4) {
+ ld_addr=simple_strtoul(argv[3], NULL, 16);
+ }
+ else {
+ ld_addr=load_addr;
+ }
+ printf ("\nupdating bootloader image from memory at %lX\n",ld_addr);
+ result=mpl_prg_image(ld_addr);
+ switch_cs(sw); /* Switch flash back */
+ return result;
+ }
+ if (strcmp(argv[2], "mps") == 0) {
+ printf ("\nupdating bootloader image from MSP\n");
+ result=mpl_prg(src,size);
+ switch_cs(sw); /* Switch flash back */
+ return result;
+ }
+ switch_cs(sw); /* Switch flash back */
+
+ }
+ if (strcmp(argv[1], "mem") == 0)
+ {
+ result=0;
+ if(argc==3)
+ {
+ result = (int)simple_strtol(argv[2], NULL, 16);
+ }
+ src=(unsigned long)&result;
+ src-=CFG_MEMTEST_START;
+ src-=(100*1024); /* - 100k */
+ src&=0xfff00000;
+ size=0;
+ do {
+ size++;
+ printf("\n\nPass %ld\n",size);
+ mem_test(CFG_MEMTEST_START,src,1);
+ if(ctrlc())
+ break;
+ if(result>0)
+ result--;
+
+ }while(result);
+ return 0;
+ }
+ if (strcmp(argv[1], "clearenvvalues") == 0)
+ {
+ if (strcmp(argv[2], "yes") == 0)
+ {
+ clear_env_values();
+ return 0;
+ }
+ }
+ if (strcmp(argv[1], "getback") == 0) {
+ get_backup_values(&back);
+ back.signature[3]=0;
+ back.serial_name[16]=0;
+ back.eth_addr[20]=0;
+ printf("GetBackUp: signature: %s\n",back.signature);
+ printf(" serial#: %s\n",back.serial_name);
+ printf(" ethaddr: %s\n",back.eth_addr);
+ return 0;
+ }
+ if (strcmp(argv[1], "setback") == 0) {
+ set_backup_values(1);
+ return 0;
+ }
+ printf("Usage:\n%s\n", cmdtp->usage);
+ return 1;
+}
+
+
+#if (CONFIG_COMMANDS & CFG_CMD_DOC)
+extern void doc_probe(ulong physadr);
+void doc_init (void)
+{
+ doc_probe(MULTI_PURPOSE_SOCKET_ADDR);
+}
+#endif
+
+
+#ifdef CONFIG_VIDEO
+/******************************************************
+ * Routines to display the Board information
+ * to the screen (since the VGA will be initialized as last,
+ * we must resend the infos)
+ */
+
+#ifdef CONFIG_CONSOLE_EXTRA_INFO
+extern GraphicDevice ctfb;
+
+void video_get_info_str (int line_number, char *info)
+{
+ /* init video info strings for graphic console */
+ DECLARE_GLOBAL_DATA_PTR;
+ PPC405_SYS_INFO sys_info;
+ char rev;
+ int i;
+ unsigned long pvr;
+ char buf[64];
+ char tmp[16];
+ unsigned char *s, *e, bc, sw;
+ switch (line_number)
+ {
+ case 2:
+ /* CPU and board infos */
+ pvr=get_pvr();
+ get_sys_info (&sys_info);
+ switch (pvr) {
+ case PVR_405GP_RB: rev='B'; break;
+ case PVR_405GP_RC: rev='C'; break;
+ case PVR_405GP_RD: rev='D'; break;
+ case PVR_405GP_RE: rev='E'; break;
+ default: rev='?'; break;
+ }
+ /* Board info */
+ i=0;
+ s=getenv ("serial#");
+#ifdef CONFIG_PIP405
+ if (!s || strncmp (s, "PIP405", 6)) {
+ sprintf(buf,"### No HW ID - assuming PIP405");
+ }
+#endif
+#ifdef CONFIG_MIP405
+ if (!s || strncmp (s, "MIP405", 6)) {
+ sprintf(buf,"### No HW ID - assuming MIP405");
+ }
+#endif
+ else {
+ for (e = s; *e; ++e) {
+ if (*e == ' ')
+ break;
+ }
+ for (; s < e; ++s) {
+ if (*s == '_') {
+ ++s;
+ break;
+ }
+ buf[i++]=*s;
+ }
+ sprintf(&buf[i]," SN ");
+ i+=4;
+ for (; s < e; ++s) {
+ buf[i++]=*s;
+ }
+ buf[i++]=0;
+ }
+ sprintf (info," %s PPC405GP %c %s MHz (%lu/%lu/%lu MHz)",
+ buf,rev,
+ strmhz (tmp, gd->cpu_clk), sys_info.freqPLB / 1000000,
+ sys_info.freqPLB / sys_info.pllOpbDiv / 1000000,
+ sys_info.freqPLB / sys_info.pllExtBusDiv / 1000000);
+ return;
+ case 3:
+ /* Memory Info */
+ sw = switch_cs (0);
+ switch_cs (sw);
+ bc = in8 (CONFIG_PORT_ADDR);
+ sprintf(info, " %luMB RAM, %luMB Flash Cfg 0x%02X %s %s",
+ gd->bd->bi_memsize / 0x100000,
+ gd->bd->bi_flashsize / 0x100000,
+ bc,
+ sw ? "MPS boot" : "Flash boot",
+ ctfb.modeIdent);
+ return;
+ case 1:
+ sprintf (buf, "%s",CONFIG_IDENT_STRING);
+ sprintf (info, " %s", &buf[1]);
+ return;
+ }
+ /* no more info lines */
+ *info = 0;
+ return;
+}
+#endif /* CONFIG_CONSOLE_EXTRA_INFO */
+
+#endif /* CONFIG_VIDEO */
--- /dev/null
+/*-----------------------------------------------------------------------------+
+|
+| 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
++-----------------------------------------------------------------------------*/
+/*
+ * Adapted for PIP405 03.07.01
+ * Denis Peter, MPL AG Switzerland, d.peter@mpl.ch
+ *
+ * TODO: Clean-up
+ */
+
+#include <common.h>
+#include <pci.h>
+#include "isa.h"
+
+#ifdef CONFIG_405GP
+#ifdef CONFIG_PCI
+
+#undef DEBUG
+
+#include "piix4_pci.h"
+#include "pci_parts.h"
+
+void pci_pip405_write_regs(struct pci_controller *hose, pci_dev_t dev,
+ struct pci_config_table *entry)
+{
+ struct pci_pip405_config_entry *table;
+ int i;
+
+ table = (struct pci_pip405_config_entry*) entry->priv[0];
+
+ for (i=0; table[i].width; i++)
+ {
+#ifdef DEBUG
+ printf("Reg 0x%02X Value 0x%08lX Width %02d written\n",
+ table[i].index, table[i].val, table[i].width);
+#endif
+
+ switch(table[i].width)
+ {
+ case 1: pci_hose_write_config_byte(hose, dev, table[i].index, table[i].val); break;
+ case 2: pci_hose_write_config_word(hose, dev, table[i].index, table[i].val); break;
+ case 4: pci_hose_write_config_dword(hose, dev, table[i].index, table[i].val); break;
+ }
+ }
+}
+
+
+static void pci_pip405_fixup_irq(struct pci_controller *hose, pci_dev_t dev)
+{
+ unsigned char int_line = 0xff;
+ /*
+ * Write pci interrupt line register
+ */
+ if(PCI_DEV(dev)==0) /* Device0 = PPC405 -> skip */
+ return;
+ if(PCI_FUNC(dev)==0)
+ {
+ /* assuming all function 0 are using their INTA# Pin*/
+ int_line=PCI_IRQ_VECTOR(dev);
+ pci_hose_write_config_byte(hose, dev, PCI_INTERRUPT_LINE, int_line);
+#ifdef DEBUG
+ printf("Fixup IRQ: dev %d (%x) int line %d 0x%x\n",
+ PCI_DEV(dev),dev,int_line,int_line);
+#endif
+ }
+}
+
+extern void pci_405gp_init(struct pci_controller *hose);
+
+
+static struct pci_controller hose = {
+ config_table: pci_pip405_config_table,
+ fixup_irq: pci_pip405_fixup_irq,
+};
+
+void pci_init(void)
+{
+ /*we want the ptrs to RAM not flash (ie don't use init list)*/
+ hose.fixup_irq = pci_pip405_fixup_irq;
+ hose.config_table = pci_pip405_config_table;
+ pci_405gp_init(&hose);
+}
+
+#endif /* CONFIG_PCI */
+#endif /* CONFIG_405GP */
--- /dev/null
+ /*
+ * (C) Copyright 2001
+ * Denis Peter, MPL AG Switzerland, d.peter@mpl.ch
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ */
+#ifndef _PCI_PARTS_H_
+#define _PCI_PARTS_H_
+
+
+/* Board specific file containing:
+ * - PCI Memory Mapping
+ * - PCI IO Mapping
+ * - PCI Interrupt Mapping
+ */
+
+/* PIP405 PCI INT Routing:
+ * IRQ0 VECTOR
+ * PIXX4 IDSEL = AD16 INTA# 28 (Function 2 USB is INTD# = 31)
+ * VGA IDSEL = AD17 INTB# 29
+ * SCSI IDSEL = AD18 INTC# 30
+ * PC104 IDSEL0 = AD20 INTA# 28
+ * PC104 IDSEL1 = AD21 INTB# 29
+ * PC104 IDSEL2 = AD22 INTC# 30
+ * PC104 IDSEL3 = AD23 INTD# 31
+ *
+ * busdevfunc = EXXX XXXX BBBB BBBB DDDD DFFF RRRR RR00
+ * ^ ^ ^ ^ ^
+ * 31 23 15 10 7
+ * E = Enabled
+ * B = Bussnumber
+ * D = Devicenumber (Device0 = AD10)
+ * F = Functionnumber
+ * R = Registernumber
+ *
+ * Device = (busdevfunc>>11) + 10
+ * Vector = devicenumber % 4 + 28
+ *
+ */
+#define PCI_HIGHEST_ON_BOARD_ID 19
+/*#define PCI_DEV_NUMBER(x) (((x>>11) & 0x1f) + 10) */
+#define PCI_IRQ_VECTOR(x) ((PCI_DEV(x) + 10) % 4) + 28
+
+
+
+/* PCI Device List for PIP405 */
+
+/* Mapping:
+ * +-------------+------------+------------+--------------------------------+
+ * ¦ PCI MemAddr | PCI IOAddr | Local Addr | Device / Function |
+ * +-------------+------------+------------+--------------------------------+
+ * | 0x00000000 | | 0xA0000000 | ISA Memory (hard wired) |
+ * | 0x00FFFFFF | | 0xA0FFFFFF | |
+ * +-------------+------------+------------+--------------------------------+
+ * | | 0x00000000 | 0xE8000000 | ISA IO (hard wired) |
+ * | | 0x0000FFFF | 0xE800FFFF | |
+ * +-------------+------------+------------+--------------------------------+
+ * | 0x80000000 | | 0x80000000 | VGA Controller Memory |
+ * | 0x80FFFFFF | | 0x80FFFFFF | |
+ * +-------------+------------+------------+--------------------------------+
+ * | 0x81000000 | | 0x81000000 | SCSI Controller Memory |
+ * | 0x81FFFFFF | | 0x81FFFFFF | |
+ * +-------------+------------+------------+--------------------------------+
+ */
+
+struct pci_pip405_config_entry {
+ int index; /* address */
+ unsigned long val; /* value */
+ int width; /* data size */
+};
+
+extern void pci_pip405_write_regs(struct pci_controller *,
+ pci_dev_t,
+ struct pci_config_table *);
+
+/* PIIX4 ISA Bridge Function 0 */
+static struct pci_pip405_config_entry piix4_isa_bridge_f0[] = {
+ {PCI_CFG_PIIX4_SERIRQ, 0xD0, 1}, /* enable Continous SERIRQ Pin */
+ {PCI_CFG_PIIX4_GENCFG, 0x00010041, 4}, /* enable SERIRQs, ISA, PNP */
+ {PCI_CFG_PIIX4_TOM, 0xFE, 1}, /* Top of Memory */
+ {PCI_CFG_PIIX4_XBCS, 0x02C4, 2}, /* disable all peri CS */
+ {PCI_CFG_PIIX4_RTCCFG, 0x21, 1}, /* enable RTC */
+#if defined(CONFIG_PIP405)
+ {PCI_CFG_PIIX4_MBDMA, 0x82, 1}, /* set MBDMA0 to DMA 2 */
+ {PCI_CFG_PIIX4_MBDMA+1, 0x83, 1}, /* set MBDMA1 to DMA 3 */
+#endif
+ {PCI_CFG_PIIX4_DLC, 0x0, 1}, /* disable passive release feature */
+ { } /* end of device table */
+};
+
+/* PIIX4 IDE Controller Function 1 */
+static struct pci_pip405_config_entry piix4_ide_cntrl_f1[] = {
+ {PCI_COMMAND, 0x0001, 2}, /* enable IO access */
+ {PCI_CFG_PIIX4_IDETIM, 0x80008000, 4}, /* enable Both IDE channels */
+ { } /* end of device table */
+};
+
+/* PIIX4 USB Controller Function 2 */
+static struct pci_pip405_config_entry piix4_usb_cntrl_f2[] = {
+ {PCI_INTERRUPT_LINE, 31, 1}, /* Int vector = 31 */
+ {PCI_BASE_ADDRESS_4, 0x0000E001, 4}, /* Set IO Address to 0xe000 to 0xe01F */
+ {PCI_LATENCY_TIMER, 0x80, 1}, /* Latency Timer 0x80 */
+ {0xC0, 0x2000, 2}, /* Legacy support */
+ {PCI_COMMAND, 0x0005, 2}, /* enable IO access and Master */
+ { } /* end of device table */
+};
+
+/* PIIX4 Power Management Function 3 */
+static struct pci_pip405_config_entry piix4_pmm_cntrl_f3[] = {
+ {PCI_COMMAND, 0x0001, 2}, /* enable IO access */
+ {PCI_CFG_PIIX4_PMAB, 0x00004000, 4}, /* set PMBA to "valid" value */
+ {PCI_CFG_PIIX4_PMMISC, 0x01, 1}, /* enable PMBA IO access */
+ {PCI_CFG_PIIX4_SMBBA, 0x00005000, 4}, /* set SMBBA to "valid" value */
+ { } /* end of device table */
+};
+/* PPC405 Dummy only used to prevent autosetup on this host bridge */
+static struct pci_pip405_config_entry ibm405_dummy[] = {
+ { } /* end of device table */
+};
+
+void pci_405gp_setup_vga(struct pci_controller *hose, pci_dev_t dev,
+ struct pci_config_table *entry);
+
+
+static struct pci_config_table pci_pip405_config_table[]={
+ {PCI_VENDOR_ID_IBM, /* 405 dummy */
+ PCI_DEVICE_ID_IBM_405GP,
+ PCI_ANY_ID,
+ PCI_ANY_ID, PCI_ANY_ID, 0,
+ pci_pip405_write_regs, {(unsigned long) ibm405_dummy}},
+
+ {PCI_VENDOR_ID_INTEL, /* PIIX4 ISA Bridge Function 0 */
+ PCI_DEVICE_ID_INTEL_82371AB_0,
+ PCI_ANY_ID,
+ PCI_ANY_ID, PCI_ANY_ID, 0,
+ pci_pip405_write_regs, {(unsigned long) piix4_isa_bridge_f0}},
+
+ {PCI_VENDOR_ID_INTEL, /* PIIX4 IDE Controller Function 1 */
+ PCI_DEVICE_ID_INTEL_82371AB,
+ PCI_ANY_ID,
+ PCI_ANY_ID, PCI_ANY_ID, 1,
+ pci_pip405_write_regs, {(unsigned long) piix4_ide_cntrl_f1}},
+
+ {PCI_VENDOR_ID_INTEL, /* PIIX4 USB Controller Function 2 */
+ PCI_DEVICE_ID_INTEL_82371AB_2,
+ PCI_ANY_ID,
+ PCI_ANY_ID, PCI_ANY_ID, 2,
+ pci_pip405_write_regs, {(unsigned long) piix4_usb_cntrl_f2}},
+
+ {PCI_VENDOR_ID_INTEL, /* PIIX4 USB Controller Function 3 */
+ PCI_DEVICE_ID_INTEL_82371AB_3,
+ PCI_ANY_ID,
+ PCI_ANY_ID, PCI_ANY_ID, 3,
+ pci_pip405_write_regs, {(unsigned long) piix4_pmm_cntrl_f3}},
+
+ {PCI_ANY_ID,
+ PCI_ANY_ID,
+ PCI_CLASS_DISPLAY_VGA,
+ PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
+ pci_405gp_setup_vga},
+
+ {PCI_ANY_ID,
+ PCI_ANY_ID,
+ PCI_CLASS_NOT_DEFINED_VGA,
+ PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
+ pci_405gp_setup_vga},
+
+ { }
+};
+#endif /* _PCI_PARTS_H_ */
+
+
+
+
+
--- /dev/null
+#
+# (C) Copyright 2000, 2001
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+include $(TOPDIR)/config.mk
+
+LIB = lib$(BOARD).a
+
+OBJS = $(BOARD).o ../common/flash.o cmd_mip405.o ../common/pci.o \
+ ../common/usb_uhci.o ../common/memtst.o ../common/common_util.o
+
+SOBJS = init.o
+
+$(LIB): $(OBJS) $(SOBJS)
+ $(AR) crv $@ $^
+
+clean:
+ rm -f $(SOBJS) $(OBJS)
+
+distclean: clean
+ rm -f $(LIB) core *.bak .depend
+
+#########################################################################
+
+.depend: Makefile $(SOBJS:.o=.S) $(OBJS:.o=.c)
+ $(CC) -M $(CFLAGS) $(SOBJS:.o=.S) $(OBJS:.o=.c) > $@
+
+sinclude .depend
+
+#########################################################################
--- /dev/null
+#
+# (C) Copyright 2000, 2001
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+include $(TOPDIR)/config.mk
+
+LIB = lib$(BOARD).a
+
+OBJS = $(BOARD).o \
+ ../common/flash.o cmd_pip405.o ../common/pci.o \
+ ../common/isa.o ../common/kbd.o \
+ ../common/usb_uhci.o \
+ ../common/memtst.o ../common/common_util.o
+
+SOBJS = init.o
+
+$(LIB): $(OBJS) $(SOBJS)
+ $(AR) crv $@ $^
+
+clean:
+ rm -f $(SOBJS) $(OBJS)
+
+distclean: clean
+ rm -f $(LIB) core *.bak .depend
+
+#########################################################################
+
+.depend: Makefile $(SOBJS:.o=.S) $(OBJS:.o=.c)
+ $(CC) -M $(CFLAGS) $(SOBJS:.o=.S) $(OBJS:.o=.c) > $@
+
+sinclude .depend
+
+#########################################################################
--- /dev/null
+/*
+ * (C) Copyright 2001
+ * Rob Taylor, Flying Pig Systems. robt@flyingpig.com.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <mpc824x.h>
+#include <pci.h>
+
+int checkboard (void)
+{
+ ulong busfreq = get_bus_freq(0);
+ char buf[32];
+
+ printf("Board: MUSENKI Local Bus at %s MHz\n", strmhz(buf, busfreq));
+ return 0;
+
+}
+
+#if 0 /* NOT USED */
+int checkflash (void)
+{
+ /* TODO: XXX XXX XXX */
+ printf ("## Test not implemented yet ##\n");
+
+ return (0);
+}
+#endif
+
+long int initdram (int board_type)
+{
+ int i, cnt;
+ volatile uchar * base= CFG_SDRAM_BASE;
+ volatile ulong * addr;
+ ulong save[32];
+ ulong val, ret = 0;
+
+ for (i=0, cnt=(CFG_MAX_RAM_SIZE / sizeof(long)) >> 1; cnt > 0; cnt >>= 1) {
+ addr = (volatile ulong *)base + cnt;
+ save[i++] = *addr;
+ *addr = ~cnt;
+ }
+
+ addr = (volatile ulong *)base;
+ save[i] = *addr;
+ *addr = 0;
+
+ if (*addr != 0) {
+ *addr = save[i];
+ goto Done;
+ }
+
+ for (cnt = 1; cnt <= CFG_MAX_RAM_SIZE / sizeof(long); cnt <<= 1) {
+ addr = (volatile ulong *)base + cnt;
+ val = *addr;
+ *addr = save[--i];
+ if (val != ~cnt) {
+ ulong new_bank0_end = cnt * sizeof(long) - 1;
+ ulong mear1 = mpc824x_mpc107_getreg(MEAR1);
+ ulong emear1 = mpc824x_mpc107_getreg(EMEAR1);
+ mear1 = (mear1 & 0xFFFFFF00) |
+ ((new_bank0_end & MICR_ADDR_MASK) >> MICR_ADDR_SHIFT);
+ emear1 = (emear1 & 0xFFFFFF00) |
+ ((new_bank0_end & MICR_ADDR_MASK) >> MICR_EADDR_SHIFT);
+ mpc824x_mpc107_setreg(MEAR1, mear1);
+ mpc824x_mpc107_setreg(EMEAR1, emear1);
+
+ ret = cnt * sizeof(long);
+ goto Done;
+ }
+ }
+
+ ret = CFG_MAX_RAM_SIZE;
+Done:
+ return ret;
+}
+
+/*
+ * Initialize PCI Devices
+ */
+#ifndef CONFIG_PCI_PNP
+static struct pci_config_table pci_sandpoint_config_table[] = {
+#if 0
+ { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
+ 0x0, 0x0, 0x0, /* unknown eth0 divice */
+ pci_cfgfunc_config_device, { PCI_ENET0_IOADDR,
+ PCI_ENET0_MEMADDR,
+ PCI_COMMAND_IO |
+ PCI_COMMAND_MEMORY |
+ PCI_COMMAND_MASTER }},
+ { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
+ 0x0, 0x0, 0x0, /* unknown eth1 device */
+ pci_cfgfunc_config_device, { PCI_ENET1_IOADDR,
+ PCI_ENET1_MEMADDR,
+ PCI_COMMAND_IO |
+ PCI_COMMAND_MEMORY |
+ PCI_COMMAND_MASTER }},
+#endif
+ { }
+};
+#endif
+
+struct pci_controller hose = {
+#ifndef CONFIG_PCI_PNP
+ config_table: pci_sandpoint_config_table,
+#endif
+};
+
+void pci_init(void)
+{
+ pci_mpc824x_init(&hose);
+}
--- /dev/null
+#
+# (C) Copyright 2000
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+include $(TOPDIR)/config.mk
+
+LIB = lib$(BOARD).a
+
+OBJS = $(BOARD).o flash.o
+
+$(LIB): .depend $(OBJS)
+ $(AR) crv $@ $^
+
+#########################################################################
+
+.depend: Makefile $(SOBJS:.o=.S) $(OBJS:.o=.c)
+ $(CC) -M $(CFLAGS) $(SOBJS:.o=.S) $(OBJS:.o=.c) > $@
+
+sinclude .depend
+
+#########################################################################
--- /dev/null
+#
+# (C) Copyright 2000
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+include $(TOPDIR)/config.mk
+
+LIB = lib$(BOARD).a
+
+OBJS = $(BOARD).o flash.o
+
+$(LIB): .depend $(OBJS)
+ $(AR) crv $@ $^
+
+#########################################################################
+
+.depend: Makefile $(SOBJS:.o=.S) $(OBJS:.o=.c)
+ $(CC) -M $(CFLAGS) $(SOBJS:.o=.S) $(OBJS:.o=.c) > $@
+
+sinclude .depend
+
+#########################################################################
--- /dev/null
+/*
+ * (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
+ */
+
+/*
+ * Pantelis Antoniou, Intracom S.A., panto@intracom.gr
+ * U-Boot port on NetVia board
+ */
+
+#include <common.h>
+#include "mpc8xx.h"
+
+/* 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 _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
+
+const uint sdram_table[0x40] = {
+ /* 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,
+ CS_1111 | BS_1111 | A10_0000 | RAS_1111 | CAS_1111 | WE_1111 | AMX_COL,
+ CS_0000 | BS_0001 | A10_0000 | RAS_1111 | CAS_0001 | WE_0000 | AMX_COL | UTA,
+ CS_0001 | BS_1111 | A10_1111 | RAS_0001 | CAS_1111 | WE_0001 | AMX_COL | UTA | TODT | LAST,
+ _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_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_,
+
+ /* UPT */
+ CS_1111 | BS_1111 | A10_1111 | RAS_1111 | CAS_1111 | WE_1111 | AMX_COL, /* NOP */
+ CS_0001 | BS_1111 | A10_1111 | RAS_0001 | CAS_0001 | WE_1111 | AMX_COL | LOOP,
+ CS_1111 | BS_1111 | A10_1111 | RAS_1111 | CAS_1111 | WE_1111 | AMX_COL,
+ CS_1111 | BS_1111 | A10_1111 | RAS_1111 | CAS_1111 | WE_1111 | AMX_COL,
+ CS_1111 | BS_1111 | A10_1111 | RAS_1111 | CAS_1111 | WE_1111 | AMX_COL | LOOP,
+ CS_1111 | BS_1111 | A10_1111 | RAS_1111 | CAS_1111 | WE_1111 | AMX_COL | LAST,
+ _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,
+ CS_1111 | BS_1111 | A10_1111 | RAS_1111 | CAS_1111 | WE_1111 | AMX_COL | TODT | LAST,
+
+ /* REG */
+ CS_1111 | BS_1111 | A10_1111 | RAS_1111 | CAS_1111 | WE_1110 | AMX_MAR,
+ CS_0001 | BS_1111 | A10_0001 | RAS_0001 | CAS_0001 | WE_0001 | AMX_MAR | TODT | LAST,
+};
+
+/* ------------------------------------------------------------------------- */
+
+
+/*
+ * Check Board Identity:
+ *
+ * Test ETX ID string (ETX_xxx...)
+ *
+ * Return 1 always.
+ */
+
+int checkboard(void)
+{
+ printf ("NETVIA\n");
+ return (0);
+}
+
+/* ------------------------------------------------------------------------- */
+
+/* 0xC8 = 0b11001000 , CAS3, >> 2 = 0b00 11 0 010 */
+#define MAR_SDRAM_INIT 0x000000C8LU
+
+#define MCR_OP(x) ((unsigned long)((x) & 3) << (31-1))
+#define MCR_OP_MASK MCR_OP(3)
+
+#define MCR_UM(x) ((unsigned long)((x) & 1) << (31 - 8))
+#define MCR_UM_MASK MCR_UM(1)
+#define MCR_UM_UPMA MCR_UM(0)
+#define MCR_UM_UPMB MCR_UM(1)
+
+#define MCR_MB(x) ((unsigned long)((x) & 7) << (31 - 18))
+#define MCR_MB_MASK MCR_MB(7)
+#define MCR_MB_CS(x) MCR_MB(x)
+
+#define MCR_MCLF(x) ((unsigned long)((x) & 15) << (31 - 23))
+#define MCR_MCLF_MASK MCR_MCLF(15)
+
+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(UPMA, (uint *) sdram_table, sizeof(sdram_table) / sizeof(uint));
+
+ /*
+ * Preliminary prescaler for refresh
+ */
+ memctl->memc_mptpr = CFG_MPTPR_1BK_8K;
+
+ 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_mamr = CFG_MAMR_9COL & ~MAMR_PTAE; /* no refresh yet */
+
+ udelay(200);
+
+ /* perform SDRAM initialisation sequence */
+ memctl->memc_mcr = MCR_OP_RUN | MCR_UM_UPMA | MCR_MB_CS3 | MCR_MCLF(1) | MCR_MAD(0x3C); /* precharge all */
+ udelay(1);
+ memctl->memc_mcr = MCR_OP_RUN | MCR_UM_UPMA | MCR_MB_CS3 | MCR_MCLF(0) | MCR_MAD(0x30); /* refresh 16 times(0) */
+ udelay(1);
+ memctl->memc_mcr = MCR_OP_RUN | MCR_UM_UPMA | MCR_MB_CS3 | MCR_MCLF(1) | MCR_MAD(0x3E); /* exception program (write mar) */
+ udelay(1);
+
+ memctl->memc_mamr |= MAMR_PTAE; /* enable refresh */
+
+ udelay(1000);
+
+ memctl->memc_mamr = CFG_MAMR_9COL;
+
+ size = SDRAM_MAX_SIZE;
+
+ udelay(10000);
+
+ /* do the ram test */
+ {
+ register unsigned long *rp;
+ register unsigned long v;
+
+ /* first fill */
+ for (rp = (unsigned long *)0; rp < (unsigned long *)SDRAM_MAX_SIZE; )
+ *rp++ = (unsigned long)rp;
+
+ /* now check */
+ for (rp = (unsigned long *)0; rp < (unsigned long *)SDRAM_MAX_SIZE; rp++) {
+ if ((v = *rp) != (unsigned long)rp) {
+ printf("ERROR at 0x%lx (0x%lx)\n", (unsigned long)rp, v);
+ return -1;
+ }
+ }
+
+ }
+
+ return (size);
+}
+
+/* ------------------------------------------------------------------------- */
+
+int misc_init_r(void)
+{
+ return(0);
+}
+
+/* ------------------------------------------------------------------------- */
+
+/* bits that can have a special purpose or can be configured as inputs/outputs */
+#define PA_MASK (_BWR(4, 9) | _BWR(12, 15))
+#define PA_ODR_MASK (_BW(9) | _BW(12) | _BW(14))
+#define PA_ODR_VAL 0
+#define PA_GP_INMASK 0
+#define PA_GP_OUTMASK (_BW(5) | _BW(14) | _BW(15))
+#define PA_SP_OUTMASK 0
+#define PA_GP_OUTVAL _BW(5)
+#define PA_SP_OUTVAL 0
+
+#define PB_MASK (_BR(16, 19) | _BR(22, 31))
+#define PB_ODR_MASK PB_MASK
+#define PB_ODR_VAL 0
+#define PB_GP_INMASK 0
+#define PB_GP_OUTMASK (_BR(16, 19) | _BR(26, 27) | _B(31))
+#define PB_SP_OUTMASK _BR(28, 30)
+#define PB_SP_OUTVAL _BR(28, 30)
+#define PB_GP_OUTVAL (_BR(16, 19) | _BR(26, 27) | _B(31))
+
+#define PC_MASK _BWR(4, 15)
+#define PC_SO_MASK (_BWR(6, 11) | _BWR(14, 15))
+#define PC_SO_VAL 0
+#define PC_INT_MASK PC_MASK
+#define PC_INT_VAL 0
+#define PC_GP_INMASK (_BWR(5, 7) | _BWR(9, 10) | _BW(13))
+#define PC_GP_OUTMASK _BW(12)
+#define PC_SP_OUTMASK 0
+#define PC_SP_OUTVAL _BW(12)
+#define PC_GP_OUTVAL 0
+
+#define PD_MASK _BWR(0, 15)
+#define PD_GP_INMASK 0
+#define PD_GP_OUTMASK _BWR(3, 15)
+#define PD_SP_OUTMASK 0
+#define PD_GP_OUTVAL (_BW(3) | _BW(5) | _BW(7) | _BWR(8, 15))
+#define PD_SP_OUTVAL 0
+
+int board_pre_init(void)
+{
+ register volatile immap_t *immap = (immap_t *) CFG_IMMR;
+ register volatile iop8xx_t *ioport = &immap->im_ioport;
+ register volatile cpm8xx_t *cpm = &immap->im_cpm;
+
+ ioport->iop_padat = (ioport->iop_padat & ~PA_MASK) | PA_SP_OUTVAL | PA_GP_OUTVAL;
+ ioport->iop_paodr = (ioport->iop_paodr & ~PA_ODR_MASK) | PA_ODR_VAL;
+ ioport->iop_padir = (ioport->iop_padir & ~PA_GP_INMASK)| PA_SP_OUTMASK | PA_GP_OUTMASK;
+ ioport->iop_papar = (ioport->iop_papar & ~(PA_GP_INMASK & PA_GP_OUTMASK));
+
+ cpm->cp_pbdat = (ioport->iop_padat & ~PB_MASK) | PB_SP_OUTVAL | PB_GP_OUTVAL;
+ cpm->cp_pbodr = (ioport->iop_paodr & ~PB_ODR_MASK) | PB_ODR_VAL;
+ cpm->cp_pbdir = (ioport->iop_padir & ~PB_GP_INMASK)| PB_SP_OUTMASK | PB_GP_OUTMASK;
+ cpm->cp_pbpar = (ioport->iop_papar & ~(PB_GP_INMASK & PB_GP_OUTMASK));
+
+ ioport->iop_pcdat = (ioport->iop_pcdat & ~PC_MASK) | PC_SP_OUTVAL | PC_GP_OUTVAL;
+ ioport->iop_pcdir = (ioport->iop_pcdir & ~PC_GP_INMASK)| PC_SP_OUTMASK | PC_GP_OUTMASK;
+ ioport->iop_pcso = (ioport->iop_pcso & ~PC_SO_MASK) | PC_SO_VAL;
+ ioport->iop_pcint = (ioport->iop_pcint & ~PC_INT_MASK) | PC_INT_VAL;
+ ioport->iop_pcpar = (ioport->iop_pcpar & ~(PC_GP_INMASK & PC_GP_OUTMASK));
+
+ ioport->iop_pddat = (ioport->iop_pddat & ~PD_MASK) | PD_SP_OUTVAL | PD_GP_OUTVAL;
+ ioport->iop_pddir = (ioport->iop_pddir & ~PD_GP_INMASK)| PD_SP_OUTMASK | PD_GP_OUTMASK;
+ ioport->iop_pdpar = (ioport->iop_pdpar & ~(PD_GP_INMASK & PD_GP_OUTMASK));
+
+ return 0;
+}
+
--- /dev/null
+/*
+ * (C) Copyright 2000
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+OUTPUT_ARCH(powerpc)
+SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/local/powerpc-any-elf/lib);
+/* Do we need any of these for elf?
+ __DYNAMIC = 0; */
+SECTIONS
+{
+ /* Read-only sections, merged into text segment: */
+ . = + SIZEOF_HEADERS;
+ .interp : { *(.interp) }
+ .hash : { *(.hash) }
+ .dynsym : { *(.dynsym) }
+ .dynstr : { *(.dynstr) }
+ .rel.text : { *(.rel.text) }
+ .rela.text : { *(.rela.text) }
+ .rel.data : { *(.rel.data) }
+ .rela.data : { *(.rela.data) }
+ .rel.rodata : { *(.rel.rodata) }
+ .rela.rodata : { *(.rela.rodata) }
+ .rel.got : { *(.rel.got) }
+ .rela.got : { *(.rela.got) }
+ .rel.ctors : { *(.rel.ctors) }
+ .rela.ctors : { *(.rela.ctors) }
+ .rel.dtors : { *(.rel.dtors) }
+ .rela.dtors : { *(.rela.dtors) }
+ .rel.bss : { *(.rel.bss) }
+ .rela.bss : { *(.rela.bss) }
+ .rel.plt : { *(.rel.plt) }
+ .rela.plt : { *(.rela.plt) }
+ .init : { *(.init) }
+ .plt : { *(.plt) }
+ .text :
+ {
+ cpu/mpc8xx/start.o (.text)
+ cpu/mpc8xx/traps.o (.text)
+ common/dlmalloc.o (.text)
+ lib_ppc/ppcstring.o (.text)
+ lib_generic/vsprintf.o (.text)
+ lib_generic/crc32.o (.text)
+ lib_generic/zlib.o (.text)
+ lib_ppc/cache.o (.text)
+ lib_ppc/time.o (.text)
+
+ . = env_offset;
+ common/environment.o (.ppcenv)
+
+ *(.text)
+ *(.fixup)
+ *(.got1)
+ }
+ _etext = .;
+ PROVIDE (etext = .);
+ .rodata :
+ {
+ *(.rodata)
+ *(.rodata1)
+ }
+ .fini : { *(.fini) } =0
+ .ctors : { *(.ctors) }
+ .dtors : { *(.dtors) }
+
+ /* Read-write section, merged into data segment: */
+ . = (. + 0x00FF) & 0xFFFFFF00;
+ _erotext = .;
+ PROVIDE (erotext = .);
+ .reloc :
+ {
+ *(.got)
+ _GOT2_TABLE_ = .;
+ *(.got2)
+ _FIXUP_TABLE_ = .;
+ *(.fixup)
+ }
+ __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2;
+ __fixup_entries = (. - _FIXUP_TABLE_)>>2;
+
+ .data :
+ {
+ *(.data)
+ *(.data1)
+ *(.sdata)
+ *(.sdata2)
+ *(.dynamic)
+ CONSTRUCTORS
+ }
+ _edata = .;
+ PROVIDE (edata = .);
+
+ __start___ex_table = .;
+ __ex_table : { *(__ex_table) }
+ __stop___ex_table = .;
+
+ . = ALIGN(256);
+ __init_begin = .;
+ .text.init : { *(.text.init) }
+ .data.init : { *(.data.init) }
+ . = ALIGN(256);
+ __init_end = .;
+
+ __bss_start = .;
+ .bss :
+ {
+ *(.sbss) *(.scommon)
+ *(.dynbss)
+ *(.bss)
+ *(COMMON)
+ }
+ _end = . ;
+ PROVIDE (end = .);
+}
--- /dev/null
+/*
+ * (C) Copyright 2000
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+OUTPUT_ARCH(powerpc)
+SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/local/powerpc-any-elf/lib);
+/* Do we need any of these for elf?
+ __DYNAMIC = 0; */
+SECTIONS
+{
+ /* Read-only sections, merged into text segment: */
+ . = + SIZEOF_HEADERS;
+ .interp : { *(.interp) }
+ .hash : { *(.hash) }
+ .dynsym : { *(.dynsym) }
+ .dynstr : { *(.dynstr) }
+ .rel.text : { *(.rel.text) }
+ .rela.text : { *(.rela.text) }
+ .rel.data : { *(.rel.data) }
+ .rela.data : { *(.rela.data) }
+ .rel.rodata : { *(.rel.rodata) }
+ .rela.rodata : { *(.rela.rodata) }
+ .rel.got : { *(.rel.got) }
+ .rela.got : { *(.rela.got) }
+ .rel.ctors : { *(.rel.ctors) }
+ .rela.ctors : { *(.rela.ctors) }
+ .rel.dtors : { *(.rel.dtors) }
+ .rela.dtors : { *(.rela.dtors) }
+ .rel.bss : { *(.rel.bss) }
+ .rela.bss : { *(.rela.bss) }
+ .rel.plt : { *(.rel.plt) }
+ .rela.plt : { *(.rela.plt) }
+ .init : { *(.init) }
+ .plt : { *(.plt) }
+ .text :
+ {
+ /* WARNING - the following is hand-optimized to fit within */
+ /* the sector layout of our flash chips! XXX FIXME XXX */
+
+ cpu/mpc8xx/start.o (.text)
+ common/dlmalloc.o (.text)
+ lib_generic/vsprintf.o (.text)
+ lib_generic/crc32.o (.text)
+
+ . = env_offset;
+ common/environment.o(.text)
+
+ *(.text)
+ *(.fixup)
+ *(.got1)
+ }
+ _etext = .;
+ PROVIDE (etext = .);
+ .rodata :
+ {
+ *(.rodata)
+ *(.rodata1)
+ }
+ .fini : { *(.fini) } =0
+ .ctors : { *(.ctors) }
+ .dtors : { *(.dtors) }
+
+ /* Read-write section, merged into data segment: */
+ . = (. + 0x0FFF) & 0xFFFFF000;
+ _erotext = .;
+ PROVIDE (erotext = .);
+ .reloc :
+ {
+ *(.got)
+ _GOT2_TABLE_ = .;
+ *(.got2)
+ _FIXUP_TABLE_ = .;
+ *(.fixup)
+ }
+ __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2;
+ __fixup_entries = (. - _FIXUP_TABLE_)>>2;
+
+ .data :
+ {
+ *(.data)
+ *(.data1)
+ *(.sdata)
+ *(.sdata2)
+ *(.dynamic)
+ CONSTRUCTORS
+ }
+ _edata = .;
+ PROVIDE (edata = .);
+
+ __start___ex_table = .;
+ __ex_table : { *(__ex_table) }
+ __stop___ex_table = .;
+
+ . = ALIGN(4096);
+ __init_begin = .;
+ .text.init : { *(.text.init) }
+ .data.init : { *(.data.init) }
+ . = ALIGN(4096);
+ __init_end = .;
+
+ __bss_start = .;
+ .bss :
+ {
+ *(.sbss) *(.scommon)
+ *(.dynbss)
+ *(.bss)
+ *(COMMON)
+ }
+ _end = . ;
+ PROVIDE (end = .);
+}
+
--- /dev/null
+/*
+ * (C) Copyright 2000
+ * Marius Groeger <mgroeger@sysgo.de>
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ *
+ * (C) Copyright 2000
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * Flash Routines for STM29W320DB/STM29W800D flash chips
+ *
+ *--------------------------------------------------------------------
+ * 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_char *addr, flash_info_t *info);
+static int write_byte (flash_info_t *info, ulong dest, uchar data);
+
+/*-----------------------------------------------------------------------
+ */
+
+unsigned long flash_init (void)
+{
+ 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;
+ }
+
+ /*
+ * We use the following trick here: since flash is cyclically
+ * mapped in the 0xFF800000-0xFFFFFFFF area, we detect the type
+ * and the size of flash using 0xFF800000 as the base address,
+ * and then call flash_get_size() again to fill flash_info.
+ */
+ size = flash_get_size((vu_char *)CFG_FLASH_PRELIMBASE, &flash_info[0]);
+ if (size)
+ {
+ flash_get_size((vu_char *)(-size), &flash_info[0]);
+ }
+
+#if (CFG_MONITOR_BASE >= CFG_FLASH_PRELIMBASE)
+ /* monitor protection ON by default */
+ flash_protect(FLAG_PROTECT_SET,
+ CFG_MONITOR_BASE,
+ CFG_MONITOR_BASE+CFG_MONITOR_LEN-1,
+ &flash_info[0]);
+#endif
+
+#if (CFG_ENV_IS_IN_FLASH == 1) && defined(CFG_ENV_ADDR)
+# ifndef CFG_ENV_SIZE
+# define CFG_ENV_SIZE CFG_ENV_SECT_SIZE
+# endif
+ flash_protect(FLAG_PROTECT_SET,
+ CFG_ENV_ADDR,
+ CFG_ENV_ADDR + CFG_ENV_SIZE - 1,
+ &flash_info[0]);
+#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_STM:
+ printf ("ST ");
+ break;
+ default:
+ printf ("Unknown Vendor ");
+ break;
+ }
+
+ switch (info->flash_id & FLASH_TYPEMASK) {
+ case FLASH_STM320DB:
+ printf ("M29W320DB (32 Mbit)\n");
+ break;
+ case FLASH_STM800DB:
+ printf ("M29W800DB (8 Mbit, bottom boot block)\n");
+ break;
+ case FLASH_STM800DT:
+ printf ("M29W800DT (8 Mbit, top boot block)\n");
+ break;
+ default:
+ printf ("Unknown Chip Type\n");
+ break;
+ }
+
+ printf (" Size: %ld KB in %d Sectors\n",
+ info->size >> 10, info->sector_count);
+
+ printf (" Sector Start Addresses:");
+ for (i=0; i<info->sector_count; ++i) {
+ if ((i % 5) == 0)
+ printf ("\n ");
+ printf (" %08lX%s",
+ info->start[i],
+ info->protect[i] ? " (RO)" : " "
+ );
+ }
+ printf ("\n");
+ return;
+}
+
+/*
+ * The following code cannot be run from FLASH!
+ */
+
+static ulong flash_get_size (vu_char *addr, flash_info_t *info)
+{
+ short i;
+ uchar vendor, devid;
+ ulong base = (ulong)addr;
+
+ /* Write auto select command: read Manufacturer ID */
+ addr[0x0AAA] = 0xAA;
+ addr[0x0555] = 0x55;
+ addr[0x0AAA] = 0x90;
+
+ udelay(1000);
+
+ vendor = addr[0];
+ devid = addr[2];
+
+ /* only support STM */
+ if ((vendor << 16) != FLASH_MAN_STM) {
+ return 0;
+ }
+
+ if (devid == FLASH_STM320DB) {
+ /* MPC8240 can address maximum 2Mb of flash, that is why the MSB
+ * lead is grounded and we can access only 2 first Mb */
+ info->flash_id = vendor << 16 | devid;
+ info->sector_count = 32;
+ info->size = info->sector_count * 0x10000;
+ for (i = 0; i < info->sector_count; i++) {
+ info->start[i] = base + i * 0x10000;
+ }
+ }
+ else if (devid == FLASH_STM800DB) {
+ info->flash_id = vendor << 16 | devid;
+ info->sector_count = 19;
+ info->size = 0x100000;
+ info->start[0] = 0x0000;
+ info->start[1] = 0x4000;
+ info->start[2] = 0x6000;
+ info->start[3] = 0x8000;
+ for (i = 4; i < info->sector_count; i++) {
+ info->start[i] = base + (i-3) * 0x10000;
+ }
+ }
+ else if (devid == FLASH_STM800DT) {
+ info->flash_id = vendor << 16 | devid;
+ info->sector_count = 19;
+ info->size = 0x100000;
+ for (i = 0; i < info->sector_count-4; i++) {
+ info->start[i] = base + i * 0x10000;
+ }
+ info->start[i] = base + i * 0x10000;
+ info->start[i+1] = base + i * 0x10000 + 0x8000;
+ info->start[i+2] = base + i * 0x10000 + 0xa000;
+ info->start[i+3] = base + i * 0x10000 + 0xc000;
+ }
+ else {
+ return 0;
+ }
+
+ /* mark all sectors as unprotected */
+ for (i = 0; i < info->sector_count; i++) {
+ info->protect[i] = 0;
+ }
+
+ /* Issue the reset command */
+ if (info->flash_id != FLASH_UNKNOWN) {
+ addr[0] = 0xF0; /* reset bank */
+ }
+
+ 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;
+ }
+
+ 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[0x0AAA] = 0xAA;
+ addr[0x0555] = 0x55;
+ addr[0x0AAA] = 0x80;
+ addr[0x0AAA] = 0xAA;
+ addr[0x0555] = 0x55;
+
+ /* wait at least 80us - let's wait 1 ms */
+ udelay (1000);
+
+ /* 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 */
+ serial_putc ('.');
+ last = now;
+ }
+ }
+
+ DONE:
+ /* reset to read mode */
+ addr = (volatile unsigned char *)info->start[0];
+ addr[0] = 0xF0; /* reset bank */
+
+ printf (" done\n");
+ return 0;
+}
+
+/*-----------------------------------------------------------------------
+ * Copy memory to flash, returns:
+ * 0 - OK
+ * 1 - write timeout
+ * 2 - Flash not erased
+ */
+
+int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
+{
+ int rc;
+
+ while (cnt > 0) {
+ if ((rc = write_byte(info, addr, *src)) != 0) {
+ return (rc);
+ }
+ addr++;
+ src++;
+ cnt--;
+ }
+
+ return (0);
+}
+
+/*-----------------------------------------------------------------------
+ * Write a byte to Flash, returns:
+ * 0 - OK
+ * 1 - write timeout
+ * 2 - Flash not erased
+ */
+static int write_byte (flash_info_t *info, ulong dest, uchar data)
+{
+ 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[0x0AAA] = 0xAA;
+ addr[0x0555] = 0x55;
+ addr[0x0AAA] = 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);
+}
+
+/*-----------------------------------------------------------------------
+ */
--- /dev/null
+/*
+ * (C) Copyright 2000
+ * Rob Taylor, Flying Pig Systems. robt@flyingpig.com.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <mpc824x.h>
+#include <pci.h>
+#include <i2c.h>
+
+int checkboard (void)
+{
+ puts ( "Board: OXC8240\n" );
+ return 0;
+}
+
+long int initdram (int board_type)
+{
+#ifndef CFG_RAMBOOT
+ int i, cnt;
+ volatile uchar * base= CFG_SDRAM_BASE;
+ volatile ulong * addr;
+ ulong save[32];
+ ulong val, ret = 0;
+
+ for (i=0, cnt=(CFG_MAX_RAM_SIZE / sizeof(long)) >> 1; cnt > 0; cnt >>= 1) {
+ addr = (volatile ulong *)base + cnt;
+ save[i++] = *addr;
+ *addr = ~cnt;
+ }
+
+ addr = (volatile ulong *)base;
+ save[i] = *addr;
+ *addr = 0;
+
+ if (*addr != 0) {
+ *addr = save[i];
+ goto Done;
+ }
+
+ for (cnt = 1; cnt <= CFG_MAX_RAM_SIZE / sizeof(long); cnt <<= 1) {
+ addr = (volatile ulong *)base + cnt;
+ val = *addr;
+ *addr = save[--i];
+ if (val != ~cnt) {
+ ulong new_bank0_end = cnt * sizeof(long) - 1;
+ ulong mear1 = mpc824x_mpc107_getreg(MEAR1);
+ ulong emear1 = mpc824x_mpc107_getreg(EMEAR1);
+ mear1 = (mear1 & 0xFFFFFF00) |
+ ((new_bank0_end & MICR_ADDR_MASK) >> MICR_ADDR_SHIFT);
+ emear1 = (emear1 & 0xFFFFFF00) |
+ ((new_bank0_end & MICR_ADDR_MASK) >> MICR_EADDR_SHIFT);
+ mpc824x_mpc107_setreg(MEAR1, mear1);
+ mpc824x_mpc107_setreg(EMEAR1, emear1);
+
+ ret = cnt * sizeof(long);
+ goto Done;
+ }
+ }
+
+ ret = CFG_MAX_RAM_SIZE;
+Done:
+ return ret;
+#else
+ /* if U-Boot starts from RAM, then suppose we have 16Mb of RAM */
+ return (16 << 20);
+#endif
+}
+
+/*
+ * Initialize PCI Devices, report devices found.
+ */
+#ifndef CONFIG_PCI_PNP
+static struct pci_config_table pci_oxc_config_table[] = {
+ { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, 0x14, PCI_ANY_ID,
+ pci_cfgfunc_config_device, { PCI_ENET0_IOADDR,
+ PCI_ENET0_MEMADDR,
+ PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER }},
+ { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, 0x15, PCI_ANY_ID,
+ pci_cfgfunc_config_device, { PCI_ENET1_IOADDR,
+ PCI_ENET1_MEMADDR,
+ PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER }},
+ { }
+};
+#endif
+
+static struct pci_controller hose = {
+#ifndef CONFIG_PCI_PNP
+ config_table: pci_oxc_config_table,
+#endif
+};
+
+void pci_init (void)
+{
+ pci_mpc824x_init(&hose);
+}
+
+int board_pre_init (void)
+{
+ *(volatile unsigned char *)(CFG_CPLD_RESET) = 0x89;
+ return 0;
+}
+
+#ifdef CONFIG_WATCHDOG
+void oxc_wdt_reset(void)
+{
+ *(volatile unsigned char *)(CFG_CPLD_WATCHDOG) = 0xff;
+}
+
+void watchdog_reset(void)
+{
+ int re_enable = disable_interrupts();
+
+ oxc_wdt_reset();
+ if (re_enable)
+ enable_interrupts();
+}
+#endif
+
+static int oxc_get_expander(unsigned char addr, unsigned char * val)
+{
+ return i2c_read(addr, 0, 0, val, 1);
+}
+
+static int oxc_set_expander(unsigned char addr, unsigned char val)
+{
+ return i2c_write(addr, 0, 0, &val, 1);
+}
+
+static int expander0alive = 0;
+
+#ifdef CONFIG_SHOW_ACTIVITY
+static int ledtoggle = 0;
+static int ledstatus = 1;
+
+void oxc_toggle_activeled(void)
+{
+ ledtoggle++;
+}
+
+void show_activity(int arg)
+{
+ static unsigned char led = 0;
+ unsigned char val;
+
+ if (!expander0alive) return;
+
+ if ((ledtoggle > (2 * arg)) && ledstatus) {
+ led ^= 0x80;
+ oxc_get_expander(CFG_I2C_EXPANDER0_ADDR, &val);
+ udelay(200);
+ oxc_set_expander(CFG_I2C_EXPANDER0_ADDR, (val & 0x7F) | led);
+ ledtoggle = 0;
+ }
+}
+#endif
+
+#ifdef CONFIG_SHOW_BOOT_PROGRESS
+void show_boot_progress(int arg)
+{
+ unsigned char val;
+
+ if (!expander0alive) return;
+
+ if (arg > 0 && ledstatus) {
+ ledstatus = 0;
+ oxc_get_expander(CFG_I2C_EXPANDER0_ADDR, &val);
+ udelay(200);
+ oxc_set_expander(CFG_I2C_EXPANDER0_ADDR, val | 0x80);
+ } else if (arg < 0) {
+ oxc_get_expander(CFG_I2C_EXPANDER0_ADDR, &val);
+ udelay(200);
+ oxc_set_expander(CFG_I2C_EXPANDER0_ADDR, val & 0x7F);
+ ledstatus = 1;
+ }
+}
+#endif
+
+int misc_init_r (void)
+{
+ /* check whether the i2c expander #0 is accessible */
+ if (!oxc_set_expander(CFG_I2C_EXPANDER0_ADDR, 0x7F)) {
+ udelay(200);
+ expander0alive = 1;
+ }
+
+#ifdef CFG_OXC_GENERATE_IP
+ {
+ DECLARE_GLOBAL_DATA_PTR;
+
+ char str[32];
+ unsigned long ip = CFG_OXC_IPMASK;
+ bd_t *bd = gd->bd;
+
+ if (expander0alive) {
+ unsigned char val;
+
+ if (!oxc_get_expander(CFG_I2C_EXPANDER0_ADDR, &val)) {
+ ip = (ip & 0xffffff00) | ((val & 0x7c) >> 2);
+ }
+ }
+
+ if ((ip & 0xff) < 3) {
+ /* if fail, set x.x.x.254 */
+ ip = (ip & 0xffffff00) | 0xfe;
+ }
+
+ bd->bi_ip_addr = ip;
+ sprintf(str, "%ld.%ld.%ld.%ld",
+ (bd->bi_ip_addr & 0xff000000) >> 24,
+ (bd->bi_ip_addr & 0x00ff0000) >> 16,
+ (bd->bi_ip_addr & 0x0000ff00) >> 8,
+ (bd->bi_ip_addr & 0x000000ff));
+ setenv("ipaddr", str);
+ printf("ip: %s\n", str);
+ }
+#endif
+ return (0);
+}
--- /dev/null
+/*
+ * (C) Copyright 2002
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <config.h>
+#include <common.h>
+#include <asm/io.h>
+
+#include "pcippc2.h"
+#include "i2c.h"
+
+typedef struct cpc710_mem_org_s
+{
+ u8 rows;
+ u8 cols;
+ u8 banks2;
+ u8 org;
+} cpc710_mem_org_t;
+
+static int cpc710_compute_mcer (u32 * mcer,
+ unsigned long *
+ size,
+ unsigned int sdram);
+static int cpc710_eeprom_checksum (unsigned int sdram);
+static u8 cpc710_eeprom_read (unsigned int sdram,
+ unsigned int offset);
+
+static u32 cpc710_mcer_mem [] =
+{
+ 0x000003f3, /* 18 lines, 4 Mb */
+ 0x000003e3, /* 19 lines, 8 Mb */
+ 0x000003c3, /* 20 lines, 16 Mb */
+ 0x00000383, /* 21 lines, 32 Mb */
+ 0x00000303, /* 22 lines, 64 Mb */
+ 0x00000203, /* 23 lines, 128 Mb */
+ 0x00000003, /* 24 lines, 256 Mb */
+ 0x00000002, /* 25 lines, 512 Mb */
+ 0x00000001 /* 26 lines, 1024 Mb */
+};
+static cpc710_mem_org_t cpc710_mem_org [] =
+{
+ { 0x0c, 0x09, 0x02, 0x00 }, /* 0000: 12/ 9/2 */
+ { 0x0d, 0x09, 0x02, 0x00 }, /* 0000: 13/ 9/2 */
+ { 0x0d, 0x0a, 0x02, 0x00 }, /* 0000: 13/10/2 */
+ { 0x0d, 0x0b, 0x02, 0x00 }, /* 0000: 13/11/2 */
+ { 0x0d, 0x0c, 0x02, 0x00 }, /* 0000: 13/12/2 */
+ { 0x0e, 0x0c, 0x02, 0x00 }, /* 0000: 14/12/2 */
+ { 0x0b, 0x08, 0x02, 0x01 }, /* 0001: 11/ 8/2 */
+ { 0x0b, 0x09, 0x01, 0x02 }, /* 0010: 11/ 9/1 */
+ { 0x0b, 0x0a, 0x01, 0x03 }, /* 0011: 11/10/1 */
+ { 0x0c, 0x08, 0x02, 0x04 }, /* 0100: 12/ 8/2 */
+ { 0x0c, 0x0a, 0x02, 0x05 }, /* 0101: 12/10/2 */
+ { 0x0d, 0x08, 0x01, 0x06 }, /* 0110: 13/ 8/1 */
+ { 0x0d, 0x08, 0x02, 0x07 }, /* 0111: 13/ 8/2 */
+ { 0x0d, 0x09, 0x01, 0x08 }, /* 1000: 13/ 9/1 */
+ { 0x0d, 0x0a, 0x01, 0x09 }, /* 1001: 13/10/1 */
+ { 0x0b, 0x08, 0x01, 0x0a }, /* 1010: 11/ 8/1 */
+ { 0x0c, 0x08, 0x01, 0x0b }, /* 1011: 12/ 8/1 */
+ { 0x0c, 0x09, 0x01, 0x0c }, /* 1100: 12/ 9/1 */
+ { 0x0e, 0x09, 0x02, 0x0d }, /* 1101: 14/ 9/2 */
+ { 0x0e, 0x0a, 0x02, 0x0e }, /* 1110: 14/10/2 */
+ { 0x0e, 0x0b, 0x02, 0x0f } /* 1111: 14/11/2 */
+};
+
+unsigned long cpc710_ram_init (void)
+{
+ unsigned long memsize = 0;
+ unsigned long bank_size;
+ u32 mcer;
+
+#ifndef CFG_RAMBOOT
+ /* Clear memory banks
+ */
+ out32(REG(SDRAM0, MCER0), 0);
+ out32(REG(SDRAM0, MCER1), 0);
+ out32(REG(SDRAM0, MCER2), 0);
+ out32(REG(SDRAM0, MCER3), 0);
+ out32(REG(SDRAM0, MCER4), 0);
+ out32(REG(SDRAM0, MCER5), 0);
+ out32(REG(SDRAM0, MCER6), 0);
+ out32(REG(SDRAM0, MCER7), 0);
+ iobarrier_rw();
+
+ /* Disable memory
+ */
+ out32(REG(SDRAM0,MCCR), 0x13b06000);
+ iobarrier_rw();
+#endif
+
+ /* Only the first memory bank is initialised now
+ */
+ if (! cpc710_compute_mcer(& mcer, & bank_size, 0))
+ {
+ puts("Unsupported SDRAM type !\n");
+ hang();
+ }
+ memsize += bank_size;
+#ifndef CFG_RAMBOOT
+ /* Enable bank, zero start
+ */
+ out32(REG(SDRAM0, MCER0), mcer | 0x80000000);
+ iobarrier_rw();
+#endif
+
+#ifndef CFG_RAMBOOT
+ /* Enable memory
+ */
+ out32(REG(SDRAM0, MCCR), in32(REG(SDRAM0, MCCR)) | 0x80000000);
+
+ /* Wait until initialisation finished
+ */
+ while (! (in32 (REG(SDRAM0, MCCR)) & 0x20000000))
+ {
+ iobarrier_rw();
+ }
+
+ /* Clear Memory Error Status and Address registers
+ */
+ out32(REG(SDRAM0, MESR), 0);
+ out32(REG(SDRAM0, MEAR), 0);
+ iobarrier_rw();
+
+ /* ECC is not configured now
+ */
+#endif
+
+ /* Memory size counter
+ */
+ out32(REG(CPC0, RGBAN1), memsize);
+
+ return memsize;
+}
+
+static int cpc710_compute_mcer (
+ u32 * mcer,
+ unsigned long * size,
+ unsigned int sdram)
+{
+ u8 rows;
+ u8 cols;
+ u8 banks2;
+ unsigned int lines;
+ u32 mc = 0;
+ unsigned int i;
+ cpc710_mem_org_t * org = 0;
+
+
+ if (! i2c_reset())
+ {
+ puts("Can't reset I2C!\n");
+ hang();
+ }
+
+ if (! cpc710_eeprom_checksum(sdram))
+ {
+ puts("Invalid EEPROM checksum !\n");
+ hang();
+ }
+
+ rows = cpc710_eeprom_read(sdram, 3);
+ cols = cpc710_eeprom_read(sdram, 4);
+ /* Can be 2 or 4 banks; divide by 2
+ */
+ banks2 = cpc710_eeprom_read(sdram, 17) / 2;
+
+ lines = rows + cols + banks2;
+
+ if (lines < 18 || lines > 26)
+ {
+ /* Unsupported configuration
+ */
+ return 0;
+ }
+
+
+ mc |= cpc710_mcer_mem [lines - 18] << 6;
+
+ for (i = 0; i < sizeof(cpc710_mem_org) / sizeof(cpc710_mem_org_t); i++)
+ {
+ cpc710_mem_org_t * corg = cpc710_mem_org + i;
+
+ if (corg->rows == rows && corg->cols == cols && corg->banks2 == banks2)
+ {
+ org = corg;
+
+ break;
+ }
+ }
+
+ if (! org)
+ {
+ /* Unsupported configuration
+ */
+ return 0;
+ }
+
+ mc |= (u32) org->org << 2;
+
+ /* Supported configuration
+ */
+ *mcer = mc;
+ *size = 1l << (lines + 4);
+
+ return 1;
+}
+
+static int cpc710_eeprom_checksum (
+ unsigned int sdram)
+{
+ u8 sum = 0;
+ unsigned int i;
+
+ for (i = 0; i < 63; i++)
+ {
+ sum += cpc710_eeprom_read(sdram, i);
+ }
+
+ return sum == cpc710_eeprom_read(sdram, 63);
+}
+
+static u8 cpc710_eeprom_read (
+ unsigned int sdram,
+ unsigned int offset)
+{
+ u8 dev = (sdram << 1) | 0xa0;
+ u8 data;
+
+ if (! i2c_read_byte(& data, dev,offset))
+ {
+ puts("I2C error !\n");
+ hang();
+ }
+
+ return data;
+}
--- /dev/null
+/*
+ * (C) Copyright 2002
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <config.h>
+#include <common.h>
+#include <asm/io.h>
+#include <pci.h>
+
+#include "hardware.h"
+#include "pcippc2.h"
+
+struct pci_controller local_hose, cpci_hose;
+
+static u32 cpc710_mapped_ram;
+
+ /* Enable PCI retry timeouts
+ */
+void cpc710_pci_enable_timeout (void)
+{
+ out32(BRIDGE(LOCAL, CFGADDR), 0x50000080);
+ iobarrier_rw();
+ out32(BRIDGE(LOCAL, CFGDATA), 0x32000000);
+ iobarrier_rw();
+
+ out32(BRIDGE(CPCI, CFGADDR), 0x50000180);
+ iobarrier_rw();
+ out32(BRIDGE(CPCI, CFGDATA), 0x32000000);
+ iobarrier_rw();
+}
+
+void cpc710_pci_init (void)
+{
+ u32 sdram_size = pcippc2_sdram_size();
+
+ cpc710_mapped_ram = sdram_size < PCI_MEMORY_MAXSIZE ?
+ sdram_size : PCI_MEMORY_MAXSIZE;
+
+ /* Select the local PCI
+ */
+ out32(REG(CPC0, PCICNFR), 0x80000002);
+ iobarrier_rw();
+
+ out32(REG(CPC0, PCIBAR), BRIDGE_LOCAL_PHYS);
+ iobarrier_rw();
+
+ /* Enable PCI bridge address decoding
+ */
+ out32(REG(CPC0, PCIENB), 0x80000000);
+ iobarrier_rw();
+
+ /* Select the CPCI bridge
+ */
+ out32(REG(CPC0, PCICNFR), 0x80000003);
+ iobarrier_rw();
+
+ out32(REG(CPC0, PCIBAR), BRIDGE_CPCI_PHYS);
+ iobarrier_rw();
+
+ /* Enable PCI bridge address decoding
+ */
+ out32(REG(CPC0, PCIENB), 0x80000000);
+ iobarrier_rw();
+
+ /* Disable configuration accesses
+ */
+ out32(REG(CPC0, PCICNFR), 0x80000000);
+ iobarrier_rw();
+
+ /* Initialise the local PCI
+ */
+ out32(BRIDGE(LOCAL, CRR), 0x7c000000);
+ iobarrier_rw();
+ out32(BRIDGE(LOCAL, PCIDG), 0x40000000);
+ iobarrier_rw();
+ out32(BRIDGE(LOCAL, PIBAR), BRIDGE_LOCAL_IO_BUS);
+ out32(BRIDGE(LOCAL, SIBAR), BRIDGE_LOCAL_IO_PHYS);
+ out32(BRIDGE(LOCAL, IOSIZE), -BRIDGE_LOCAL_IO_SIZE);
+ iobarrier_rw();
+ out32(BRIDGE(LOCAL, PMBAR), BRIDGE_LOCAL_MEM_BUS);
+ out32(BRIDGE(LOCAL, SMBAR), BRIDGE_LOCAL_MEM_PHYS);
+ out32(BRIDGE(LOCAL, MSIZE), -BRIDGE_LOCAL_MEM_SIZE);
+ iobarrier_rw();
+ out32(BRIDGE(LOCAL, PR), 0x00ffe000);
+ iobarrier_rw();
+ out32(BRIDGE(LOCAL, ACR), 0xfe000000);
+ iobarrier_rw();
+ out32(BRIDGE(LOCAL, PSBAR), PCI_MEMORY_BUS >> 24);
+ out32(BRIDGE(LOCAL, BARPS), PCI_MEMORY_PHYS >> 24);
+ out32(BRIDGE(LOCAL, PSSIZE), 256 - (cpc710_mapped_ram >> 24));
+ iobarrier_rw();
+
+ /* Initialise the CPCI bridge
+ */
+ out32(BRIDGE(CPCI, CRR), 0x7c000000);
+ iobarrier_rw();
+ out32(BRIDGE(CPCI, PCIDG), 0xC0000000);
+ iobarrier_rw();
+ out32(BRIDGE(CPCI, PIBAR), BRIDGE_CPCI_IO_BUS);
+ out32(BRIDGE(CPCI, SIBAR), BRIDGE_CPCI_IO_PHYS);
+ out32(BRIDGE(CPCI, IOSIZE), -BRIDGE_CPCI_IO_SIZE);
+ iobarrier_rw();
+ out32(BRIDGE(CPCI, PMBAR), BRIDGE_CPCI_MEM_BUS);
+ out32(BRIDGE(CPCI, SMBAR), BRIDGE_CPCI_MEM_PHYS);
+ out32(BRIDGE(CPCI, MSIZE), -BRIDGE_CPCI_MEM_SIZE);
+ iobarrier_rw();
+ out32(BRIDGE(CPCI, PR), 0x80ffe000);
+ iobarrier_rw();
+ out32(BRIDGE(CPCI, ACR), 0xdf000000);
+ iobarrier_rw();
+ out32(BRIDGE(CPCI, PSBAR), PCI_MEMORY_BUS >> 24);
+ out32(BRIDGE(CPCI, BARPS), PCI_MEMORY_PHYS >> 24);
+ out32(BRIDGE(CPCI, PSSIZE), 256 - (cpc710_mapped_ram >> 24));
+ iobarrier_rw();
+
+ /* Local PCI
+ */
+
+ out32(BRIDGE(LOCAL, CFGADDR), 0x04000080);
+ iobarrier_rw();
+ out32(BRIDGE(LOCAL, CFGDATA), 0x56010000);
+ iobarrier_rw();
+
+ out32(BRIDGE(LOCAL, CFGADDR), 0x0c000080);
+ iobarrier_rw();
+ out32(BRIDGE(LOCAL, CFGDATA), PCI_LATENCY_TIMER_VAL << 16);
+ iobarrier_rw();
+
+ /* Set bus and subbus numbers
+ */
+ out32(BRIDGE(LOCAL, CFGADDR), 0x40000080);
+ iobarrier_rw();
+ out32(BRIDGE(LOCAL, CFGDATA), 0x00000000);
+ iobarrier_rw();
+
+ out32(BRIDGE(LOCAL, CFGADDR), 0x50000080);
+ iobarrier_rw();
+ /* PCI retry timeouts will be enabled later
+ */
+ out32(BRIDGE(LOCAL, CFGDATA), 0x00000000);
+ iobarrier_rw();
+
+ /* CPCI
+ */
+
+ /* Set bus and subbus numbers
+ */
+ out32(BRIDGE(CPCI, CFGADDR), 0x40000080);
+ iobarrier_rw();
+ out32(BRIDGE(CPCI, CFGDATA), 0x01010000);
+ iobarrier_rw();
+
+ out32(BRIDGE(CPCI, CFGADDR), 0x04000180);
+ iobarrier_rw();
+ out32(BRIDGE(CPCI, CFGDATA), 0x56010000);
+ iobarrier_rw();
+
+ out32(BRIDGE(CPCI, CFGADDR), 0x0c000180);
+ iobarrier_rw();
+ out32(BRIDGE(CPCI, CFGDATA), PCI_LATENCY_TIMER_VAL << 16);
+ iobarrier_rw();
+
+ /* Write to the PSBAR */
+ out32(BRIDGE(CPCI, CFGADDR), 0x10000180);
+ iobarrier_rw();
+ out32(BRIDGE(CPCI, CFGDATA), cpu_to_le32(PCI_MEMORY_BUS));
+ iobarrier_rw();
+
+ /* Set bus and subbus numbers
+ */
+ out32(BRIDGE(CPCI, CFGADDR), 0x40000180);
+ iobarrier_rw();
+ out32(BRIDGE(CPCI, CFGDATA), 0x01ff0000);
+ iobarrier_rw();
+
+ out32(BRIDGE(CPCI, CFGADDR), 0x50000180);
+ iobarrier_rw();
+ out32(BRIDGE(CPCI, CFGDATA), 0x32000000);
+ /* PCI retry timeouts will be enabled later
+ */
+ out32(BRIDGE(CPCI, CFGDATA), 0x00000000);
+ iobarrier_rw();
+
+ /* Remove reset on the PCI buses
+ */
+ out32(BRIDGE(LOCAL, CRR), 0xfc000000);
+ iobarrier_rw();
+ out32(BRIDGE(CPCI, CRR), 0xfc000000);
+ iobarrier_rw();
+
+ local_hose.first_busno = 0;
+ local_hose.last_busno = 0xff;
+
+ /* System memory space */
+ pci_set_region(local_hose.regions + 0,
+ PCI_MEMORY_BUS,
+ PCI_MEMORY_PHYS,
+ PCI_MEMORY_MAXSIZE,
+ PCI_REGION_MEM | PCI_REGION_MEMORY);
+
+ /* PCI memory space */
+ pci_set_region(local_hose.regions + 1,
+ BRIDGE_LOCAL_MEM_BUS,
+ BRIDGE_LOCAL_MEM_PHYS,
+ BRIDGE_LOCAL_MEM_SIZE,
+ PCI_REGION_MEM);
+
+ /* PCI I/O space */
+ pci_set_region(local_hose.regions + 2,
+ BRIDGE_LOCAL_IO_BUS,
+ BRIDGE_LOCAL_IO_PHYS,
+ BRIDGE_LOCAL_IO_SIZE,
+ PCI_REGION_IO);
+
+ local_hose.region_count = 3;
+
+ pci_setup_indirect(&local_hose,
+ BRIDGE_LOCAL_PHYS + HW_BRIDGE_CFGADDR,
+ BRIDGE_LOCAL_PHYS + HW_BRIDGE_CFGDATA);
+
+ pci_register_hose(&local_hose);
+
+ /* Initialize PCI32 bus registers */
+ pci_hose_write_config_byte(&local_hose,
+ PCI_BDF(local_hose.first_busno,0,0),
+ CPC710_BUS_NUMBER,
+ local_hose.first_busno);
+ pci_hose_write_config_byte(&local_hose,
+ PCI_BDF(local_hose.first_busno,0,0),
+ CPC710_SUB_BUS_NUMBER,
+ local_hose.last_busno);
+
+ local_hose.last_busno = pci_hose_scan(&local_hose);
+
+ /* Write out correct max subordinate bus number for local hose */
+ pci_hose_write_config_byte(&local_hose,
+ PCI_BDF(local_hose.first_busno,0,0),
+ CPC710_SUB_BUS_NUMBER,
+ local_hose.last_busno);
+
+ cpci_hose.first_busno = local_hose.last_busno + 1;
+ cpci_hose.last_busno = 0xff;
+
+ /* System memory space */
+ pci_set_region(cpci_hose.regions + 0,
+ PCI_MEMORY_BUS,
+ PCI_MEMORY_PHYS,
+ PCI_MEMORY_MAXSIZE,
+ PCI_REGION_MEMORY);
+
+ /* PCI memory space */
+ pci_set_region(cpci_hose.regions + 1,
+ BRIDGE_CPCI_MEM_BUS,
+ BRIDGE_CPCI_MEM_PHYS,
+ BRIDGE_CPCI_MEM_SIZE,
+ PCI_REGION_MEM);
+
+ /* PCI I/O space */
+ pci_set_region(cpci_hose.regions + 2,
+ BRIDGE_CPCI_IO_BUS,
+ BRIDGE_CPCI_IO_PHYS,
+ BRIDGE_CPCI_IO_SIZE,
+ PCI_REGION_IO);
+
+ cpci_hose.region_count = 3;
+
+ pci_setup_indirect(&cpci_hose,
+ BRIDGE_CPCI_PHYS + HW_BRIDGE_CFGADDR,
+ BRIDGE_CPCI_PHYS + HW_BRIDGE_CFGDATA);
+
+ pci_register_hose(&cpci_hose);
+
+ /* Initialize PCI64 bus registers */
+ pci_hose_write_config_byte(&cpci_hose,
+ PCI_BDF(cpci_hose.first_busno,0,0),
+ CPC710_BUS_NUMBER,
+ cpci_hose.first_busno);
+ pci_hose_write_config_byte(&cpci_hose,
+ PCI_BDF(cpci_hose.first_busno,0,0),
+ CPC710_SUB_BUS_NUMBER,
+ cpci_hose.last_busno);
+
+ cpci_hose.last_busno = pci_hose_scan(&cpci_hose);
+
+ /* Write out correct max subordinate bus number for cpci hose */
+ pci_hose_write_config_byte(&cpci_hose,
+ PCI_BDF(cpci_hose.first_busno,0,0),
+ CPC710_SUB_BUS_NUMBER,
+ cpci_hose.last_busno);
+}
--- /dev/null
+/*
+ * (C) Copyright 2002
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <config.h>
+#include <common.h>
+#include <asm/io.h>
+
+#include "hardware.h"
+#include "i2c.h"
+
+static void i2c_start (void);
+static void i2c_stop (void);
+static int i2c_write (u8 data);
+static void i2c_read (u8 * data);
+
+static inline void i2c_port_start (void);
+static inline void i2c_clock (unsigned int val);
+static inline void i2c_data (unsigned int val);
+static inline unsigned int
+ i2c_in (void);
+static inline void i2c_write_bit (unsigned int val);
+static inline unsigned int
+ i2c_read_bit (void);
+
+static inline void i2c_udelay (unsigned int time);
+
+int i2c_read_byte (
+ u8 * data,
+ u8 dev,
+ u8 offset)
+{
+ int err = 0;
+
+ i2c_start();
+
+ err = ! i2c_write(dev);
+
+ if (! err)
+ {
+ err = ! i2c_write(offset);
+ }
+
+ if (! err)
+ {
+ i2c_start();
+ }
+
+ if (! err)
+ {
+ err = ! i2c_write(dev | 0x01);
+ }
+
+ if (! err)
+ {
+ i2c_read(data);
+ }
+
+ i2c_stop();
+
+ return ! err;
+}
+
+static inline void i2c_udelay (
+ unsigned int time)
+{
+ int v;
+
+ asm volatile("mtdec %0" : : "r" (time * ((CFG_BUS_CLK / 4) / 1000000)));
+
+ do
+ {
+ asm volatile("isync; mfdec %0" : "=r" (v));
+ } while (v >= 0);
+}
+
+ /* Low-level hardware access
+ */
+
+#define BIT_GPDATA 0x80000000
+#define BIT_GPCLK 0x40000000
+
+static inline void i2c_port_start (void)
+{
+ out32(REG(CPC0, GPDIR), in32(REG(CPC0, GPDIR)) & ~(BIT_GPCLK | BIT_GPDATA));
+ out32(REG(CPC0, GPOUT), in32(REG(CPC0, GPOUT)) & ~(BIT_GPCLK | BIT_GPDATA));
+ iobarrier_rw();
+
+ i2c_udelay(1);
+}
+
+static inline void i2c_clock (
+ unsigned int val)
+{
+ if (val)
+ {
+ out32(REG(CPC0, GPDIR), in32(REG(CPC0, GPDIR)) & ~BIT_GPCLK);
+ }
+ else
+ {
+ out32(REG(CPC0, GPDIR), in32(REG(CPC0, GPDIR)) | BIT_GPCLK);
+ }
+
+ iobarrier_rw();
+
+ i2c_udelay(1);
+}
+
+static inline void i2c_data (
+ unsigned int val)
+{
+ if (val)
+ {
+ out32(REG(CPC0, GPDIR), in32(REG(CPC0, GPDIR)) & ~BIT_GPDATA);
+ }
+ else
+ {
+ out32(REG(CPC0, GPDIR), in32(REG(CPC0, GPDIR)) | BIT_GPDATA);
+ }
+
+ iobarrier_rw();
+
+ i2c_udelay(1);
+}
+
+static inline unsigned int i2c_in (void)
+{
+ unsigned int val = ((in32(REG(CPC0, GPIN)) & BIT_GPDATA) != 0)?1:0;
+
+ iobarrier_rw();
+
+ return val;
+}
+
+
+ /* Protocol implementation
+ */
+
+static inline void i2c_write_bit (
+ unsigned int val)
+{
+ i2c_data(val);
+ i2c_udelay(10);
+ i2c_clock(1);
+ i2c_udelay(10);
+ i2c_clock(0);
+ i2c_udelay(10);
+}
+
+static inline unsigned int i2c_read_bit (void)
+{
+ unsigned int val;
+
+ i2c_data(1);
+ i2c_udelay(10);
+
+ i2c_clock(1);
+ i2c_udelay(10);
+
+ val = i2c_in();
+
+ i2c_clock(0);
+ i2c_udelay(10);
+
+ return val;
+}
+
+unsigned int i2c_reset (void)
+{
+ unsigned int val;
+ int i;
+
+ i2c_port_start();
+
+ i=0;
+ do {
+ i2c_udelay(10);
+ i2c_clock(0);
+ i2c_udelay(10);
+ i2c_clock(1);
+ i2c_udelay(10);
+ val = i2c_in();
+ i++;
+ } while ((i<9)&&(val==0));
+ return (val);
+}
+
+
+static void i2c_start (void)
+{
+ i2c_data(1);
+ i2c_clock(1);
+ i2c_udelay(10);
+ i2c_data(0);
+ i2c_udelay(10);
+ i2c_clock(0);
+ i2c_udelay(10);
+}
+
+static void i2c_stop (void)
+{
+ i2c_data(0);
+ i2c_udelay(10);
+ i2c_clock(1);
+ i2c_udelay(10);
+ i2c_data(1);
+ i2c_udelay(10);
+}
+
+static int i2c_write (
+ u8 data)
+{
+ unsigned int i;
+
+ for (i = 0; i < 8; i++)
+ {
+ i2c_write_bit(data >> 7);
+ data <<= 1;
+ }
+
+ return i2c_read_bit() == 0;
+}
+
+static void i2c_read (
+ u8 * data)
+{
+ unsigned int i;
+ u8 val = 0;
+
+ for (i = 0; i < 8; i++)
+ {
+ val <<= 1;
+ val |= i2c_read_bit();
+ }
+
+ *data = val;
+ i2c_write_bit(1); /* NoAck */
+}
--- /dev/null
+/*
+ * (C) Copyright 2002
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <config.h>
+#include <common.h>
+#include <command.h>
+#include <asm/io.h>
+#include <linux/mtd/doc2000.h>
+#include <watchdog.h>
+#include <pci.h>
+
+#include "hardware.h"
+#include "pcippc2.h"
+#include "sconsole.h"
+#include "fpga_serial.h"
+
+#if defined(CONFIG_WATCHDOG)
+
+static int pcippc2_wdt_init_done = 0;
+
+void pcippc2_wdt_init (void);
+
+#endif
+
+ /* Check board identity
+ */
+int checkboard (void)
+{
+#ifdef CONFIG_PCIPPC2
+ puts ("Board: Gespac PCIPPC-2\n");
+#else
+ puts ("Board: Gespac PCIPPC-6\n");
+#endif
+ return 0;
+}
+
+ /* RAM size is stored in CPC0_RGBAN1
+ */
+u32 pcippc2_sdram_size (void)
+{
+ return in32 (REG (CPC0, RGBAN1));
+}
+
+long initdram (int board_type)
+{
+ return cpc710_ram_init ();
+}
+
+void do_reset (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[])
+{
+ out32 (REG (CPC0, SPOR), 0);
+ iobarrier_rw ();
+ while (1);
+}
+
+int board_pre_init (void)
+{
+ out32 (REG (CPC0, RSTR), 0xC0000000);
+ iobarrier_rw ();
+
+ out32 (REG (CPC0, RSTR), 0xF0000000);
+ iobarrier_rw ();
+
+ out32 (REG (CPC0, UCTL), 0x00F80000);
+
+ out32 (REG (CPC0, SIOC0), 0x30000000);
+
+ out32 (REG (CPC0, ABCNTL), 0x00000000);
+
+ out32 (REG (CPC0, SESR), 0x00000000);
+ out32 (REG (CPC0, SEAR), 0x00000000);
+
+ /* Detect IBM Avignon CPC710 Revision */
+ if ((in32 (REG (CPC0, UCTL)) & 0x000000F0) == CPC710_TYPE_100P)
+ out32 (REG (CPC0, PGCHP), 0xA0000040);
+ else
+ out32 (REG (CPC0, PGCHP), 0x80800040);
+
+
+ out32 (REG (CPC0, ATAS), 0x709C2508);
+
+ iobarrier_rw ();
+
+ return 0;
+}
+
+void after_reloc (ulong dest_addr)
+{
+ DECLARE_GLOBAL_DATA_PTR;
+
+ /* Jump to the main U-Boot board init code
+ */
+ board_init_r (gd, dest_addr);
+}
+
+int misc_init_r (void)
+{
+ pcippc2_fpga_init ();
+
+#if defined(CONFIG_WATCHDOG)
+ pcippc2_wdt_init ();
+#endif
+
+ fpga_serial_init (sconsole_get_baudrate ());
+
+ sconsole_putc = fpga_serial_putc;
+ sconsole_puts = fpga_serial_puts;
+ sconsole_getc = fpga_serial_getc;
+ sconsole_tstc = fpga_serial_tstc;
+ sconsole_setbrg = fpga_serial_setbrg;
+
+ sconsole_flush ();
+ return (0);
+}
+
+void pci_init (void)
+{
+ cpc710_pci_init ();
+
+ /* FPGA requires no retry timeouts to be enabled
+ */
+ cpc710_pci_enable_timeout ();
+}
+
+void doc_init (void)
+{
+ doc_probe (pcippc2_fpga1_phys + HW_FPGA1_DOC);
+}
+
+#if defined(CONFIG_WATCHDOG)
+
+void pcippc2_wdt_init (void)
+{
+ out16r (FPGA (WDT, PROG), 0xffff);
+ out8 (FPGA (WDT, CTRL), 0x1);
+
+ pcippc2_wdt_init_done = 1;
+}
+
+void pcippc2_wdt_done (void)
+{
+ out8 (FPGA (WDT, CTRL), 0x0);
+
+ pcippc2_wdt_init_done = 0;
+}
+
+void pcippc2_wdt_reset (void)
+{
+ if (pcippc2_wdt_init_done == 1)
+ out8 (FPGA (WDT, REFRESH), 0x56);
+}
+
+void watchdog_reset (void)
+{
+ int re_enable = disable_interrupts ();
+
+ pcippc2_wdt_reset ();
+ if (re_enable)
+ enable_interrupts ();
+}
+
+#if (CONFIG_COMMANDS & CFG_CMD_BSP)
+int do_wd (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[])
+{
+ switch (argc) {
+ case 1:
+ printf ("Watchdog timer status is %s\n",
+ pcippc2_wdt_init_done == 1 ? "on" : "off");
+
+ return 0;
+ case 2:
+ if (!strcmp(argv[1],"on")) {
+ pcippc2_wdt_init();
+ printf("Watchdog timer now is on\n");
+
+ return 0;
+
+ } else if (!strcmp(argv[1],"off")) {
+ pcippc2_wdt_done();
+ printf("Watchdog timer now is off\n");
+
+ return 0;
+
+ } else
+ break;
+ default:
+ break;
+ }
+ printf ("Usage:\n%s\n", cmdtp->usage);
+ return 1;
+}
+
+#endif /* CFG_CMD_BSP */
+#endif /* CONFIG_WATCHDOG */
--- /dev/null
+/*
+ * (C) Copyright 2002
+ * Wolfgang Grandegger, DENX Software Engineering, wg@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 <malloc.h>
+#include <net.h>
+#include <asm/io.h>
+#include <pci.h>
+#include <cmd_autoscript.h>
+#include <cmd_bsp.h>
+
+#include "pn62.h"
+
+#if (CONFIG_COMMANDS & CFG_CMD_BSP)
+
+extern int do_bootm (cmd_tbl_t *, int, int, char *[]);
+
+/*
+ * Command led: controls the various LEDs 0..11 on the PN62 card.
+ */
+int do_led (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+ unsigned int number, function;
+
+ if (argc != 3) {
+ printf ("Usage:\n%s\n", cmdtp->usage);
+ return 1;
+ }
+ number = simple_strtoul(argv[1], NULL, 10);
+ if (number > PN62_LED_MAX)
+ return 1;
+ function = simple_strtoul(argv[2], NULL, 16);
+ set_led (number, function);
+ return 0;
+}
+
+/*
+ * Command loadpci: loads a image over PCI.
+ */
+#define CMD_MOVE_WINDOW 0x1
+#define CMD_BOOT_IMAGE 0x2
+
+int do_loadpci (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+ char *s;
+ ulong addr = 0, count = 0;
+ u32 off;
+ int cmd, rcode = 0;
+
+ /* pre-set load_addr */
+ if ((s = getenv("loadaddr")) != NULL) {
+ addr = simple_strtoul(s, NULL, 16);
+ }
+
+ switch (argc) {
+ case 1:
+ break;
+ case 2:
+ addr = simple_strtoul(argv[1], NULL, 16);
+ break;
+ default:
+ printf ("Usage:\n%s\n", cmdtp->usage);
+ return 1;
+ }
+
+ printf ("## Ready for image download ...\n");
+
+ show_startup_phase(12);
+
+ while (1) {
+ /* Alive indicator */
+ i2155x_write_scrapad(BOOT_PROTO, BOOT_PROTO_READY);
+
+ /* Toggle status LEDs */
+ cmd = (count / 200) % 4; /* downscale */
+ set_led(4, cmd == 0 ? LED_1 : LED_0);
+ set_led(5, cmd == 1 ? LED_1 : LED_0);
+ set_led(6, cmd == 2 ? LED_1 : LED_0);
+ set_led(7, cmd == 3 ? LED_1 : LED_0);
+ udelay(1000);
+ count++;
+
+ cmd = i2155x_read_scrapad(BOOT_CMD);
+
+ if (cmd == BOOT_CMD_MOVE) {
+ off = i2155x_read_scrapad(BOOT_DATA);
+ off += addr;
+ i2155x_set_bar_base(3, off);
+ printf ("## BAR3 Addr moved = 0x%08x\n", off);
+ i2155x_write_scrapad(BOOT_CMD, ~cmd);
+ show_startup_phase(13);
+ }
+ else if (cmd == BOOT_CMD_BOOT) {
+ set_led(4, LED_1);
+ set_led(5, LED_1);
+ set_led(6, LED_1);
+ set_led(7, LED_1);
+
+ i2155x_write_scrapad(BOOT_CMD, ~cmd);
+ show_startup_phase(14);
+ break;
+ }
+
+ /* Abort if ctrl-c was pressed */
+ if (ctrlc()) {
+ printf("\nAbort\n");
+ return 0;
+ }
+
+ }
+
+ /* Repoint to the default shared memory */
+ i2155x_set_bar_base(3, PN62_SMEM_DEFAULT);
+
+ load_addr = addr;
+ printf ("## Start Addr = 0x%08lx\n", addr);
+
+ show_startup_phase(15);
+
+ /* Loading ok, check if we should attempt an auto-start */
+ if (((s = getenv("autostart")) != NULL) && (strcmp(s,"yes") == 0)) {
+ char *local_args[2];
+ local_args[0] = argv[0];
+ local_args[1] = NULL;
+
+ printf ("Automatic boot of image at addr 0x%08lX ...\n",
+ load_addr);
+ rcode = do_bootm (cmdtp, 0, 1, local_args);
+ }
+
+#ifdef CONFIG_AUTOSCRIPT
+ if (load_addr) {
+ char *s;
+
+ if (((s = getenv("autoscript")) != NULL) && (strcmp(s,"yes") == 0)) {
+ printf("Running autoscript at addr 0x%08lX ...\n", load_addr);
+ rcode = autoscript (bd, load_addr);
+ }
+ }
+#endif
+ return rcode;
+}
+
+#endif
--- /dev/null
+/*
+ * (C) Copyright 2002 Wolfgang Grandegger <wg@denx.de>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <mpc824x.h>
+#include <asm/io.h>
+#include <pci.h>
+
+#include "pn62.h"
+
+typedef struct {
+ pci_dev_t devno;
+ volatile u32 *csr;
+
+} i2155x_t;
+
+static i2155x_t i2155x = { 0, NULL };
+
+static struct pci_device_id i2155x_ids[] = {
+ { 0x1011, 0x0046 }, /* i21554 */
+ { 0x8086, 0xb555 } /* i21555 */
+};
+
+int i2155x_init(void)
+{
+ pci_dev_t devno;
+ u32 val;
+ int i;
+
+ /*
+ * Find the Intel bridge.
+ */
+ if ((devno = pci_find_devices(i2155x_ids, 0)) < 0) {
+ printf("Error: Intel bridge 2155x not found!\n");
+ return -1;
+ }
+ i2155x.devno = devno;
+
+ /*
+ * Get auto-configured base address for CSR access.
+ */
+ pci_read_config_dword(devno, PCI_BASE_ADDRESS_1, &val);
+ if (val & PCI_BASE_ADDRESS_SPACE_IO) {
+ val &= PCI_BASE_ADDRESS_IO_MASK;
+ i2155x.csr = (volatile u32 *)(_IO_BASE + val);
+ } else {
+ val &= PCI_BASE_ADDRESS_MEM_MASK;
+ i2155x.csr = (volatile u32 *)val;
+ }
+
+ /*
+ * Translate downstream memory 2 (bar3) to base of shared memory.
+ */
+ i2155x_set_bar_base(3, PN62_SMEM_DEFAULT);
+
+ /*
+ * Enable memory space, I/O space and bus master bits
+ * in both Primary and Secondary command registers.
+ */
+ val = PCI_COMMAND_MEMORY|PCI_COMMAND_MASTER|PCI_COMMAND_IO;
+ pci_write_config_word(devno, 0x44, val);
+ pci_write_config_word(devno, 0x04, val);
+
+ /*
+ * Clear scratchpad registers.
+ */
+ for (i = 0; i < (I2155X_SCRAPAD_MAX - 1); i++) {
+ i2155x_write_scrapad(i, 0x0);
+ }
+
+ /*
+ * Set interrupt line for Linux.
+ */
+ pci_write_config_byte(devno, PCI_INTERRUPT_LINE, 3);
+
+ return 0;
+}
+
+/*
+ * Access the Scratchpad registers 0..7 of the Intel bridge.
+ */
+void i2155x_write_scrapad(int idx, u32 val)
+{
+ if (idx >= 0 && idx < I2155X_SCRAPAD_MAX)
+ out_le32(i2155x.csr + (I2155X_SCRAPAD_ADDR/4) + idx, val);
+ else
+ printf("i2155x_write_scrapad: invalid index\n");
+}
+
+u32 i2155x_read_scrapad(int idx)
+{
+ if (idx >= 0 && idx < I2155X_SCRAPAD_MAX)
+ return in_le32(i2155x.csr + (I2155X_SCRAPAD_ADDR/4) + idx);
+ else
+ printf("i2155x_read_scrapad: invalid index\n");
+ return -1;
+}
+
+void i2155x_set_bar_base(int bar, u32 base)
+{
+ if (bar >= 2 && bar <= 4) {
+ pci_write_config_dword(i2155x.devno,
+ I2155X_BAR2_BASE + (bar - 2) * 4,
+ base);
+ }
+}
+
+/*
+ * Read Vital Product Data (VPD) from the Serial EPROM attached
+ * to the Intel bridge.
+ */
+int i2155x_read_vpd(int offset, int size, unsigned char *data)
+{
+ int i, n;
+ u16 val16;
+
+ for (i = 0; i < size; i++) {
+ pci_write_config_word(i2155x.devno, I2155X_VPD_ADDR,
+ offset + i - I2155X_VPD_START);
+ for (n = 10000; n > 0; n--) {
+ pci_read_config_word(i2155x.devno, I2155X_VPD_ADDR, &val16);
+ if ((val16 & 0x8000) != 0) /* wait for completion */
+ break;
+ udelay(100);
+ }
+ if (n == 0) {
+ printf("i2155x_read_vpd: TIMEOUT\n");
+ return -1;
+ }
+
+ pci_read_config_byte(i2155x.devno, I2155X_VPD_DATA, &data[i]);
+ }
+
+ return i;
+}
+
+static struct pci_device_id am79c95x_ids [] = {
+ { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_LANCE },
+ { }
+};
+
+
+/*
+ * Initialize the AMD ethernet controllers.
+ */
+int am79c95x_init(void)
+{
+ pci_dev_t devno;
+ int i;
+
+ /*
+ * Set interrupt line for Linux.
+ */
+ for (i = 0; i < 2; i++) {
+ if ((devno = pci_find_devices(am79c95x_ids, i)) < 0)
+ break;
+ pci_write_config_byte(devno, PCI_INTERRUPT_LINE, 2+i);
+ }
+ if (i < 2)
+ printf("Error: Only %d AMD Ethernet Controller found!\n", i);
+
+ return 0;
+}
+
+
+void set_led(unsigned int number, unsigned int function)
+{
+ volatile u8 *addr;
+
+ if ((number >= 0) && (number < PN62_LED_MAX) &&
+ (function >= 0) && (function <= LED_LAST_FUNCTION)) {
+ addr = (volatile u8 *)(PN62_LED_BASE + number * 8);
+ out_8(addr, function&0xff);
+ }
+}
+
+/*
+ * Show fatal error indicated by Kinght Rider(tm) effect
+ * in LEDS 0-7. LEDS 8-11 contain 4 bit error code.
+ * Note: this function will not terminate.
+ */
+void fatal_error(unsigned int error_code)
+{
+ int i, d;
+
+ for (i = 0; i < 12; i++) {
+ set_led(i, LED_0);
+ }
+
+ /*
+ * Write error code.
+ */
+ set_led(8, (error_code & 0x01) ? LED_1 : LED_0);
+ set_led(9, (error_code & 0x02) ? LED_1 : LED_0);
+ set_led(10, (error_code & 0x04) ? LED_1 : LED_0);
+ set_led(11, (error_code & 0x08) ? LED_1 : LED_0);
+
+ /*
+ * Yay - Knight Rider effect!
+ */
+ while(1) {
+ unsigned int delay = 2000;
+
+ for (i = 0; i < 8; i++) {
+ set_led(i, LED_1);
+ for (d = 0; d < delay; d++);
+ set_led(i, LED_0);
+ }
+
+ for (i = 7; i > 0; i--) {
+ set_led(i, LED_1);
+ for (d = 0; d < delay; d++);
+ set_led(i, LED_0);
+ }
+ }
+}
--- /dev/null
+/*
+ * (C) Copyright 2002 Wolfgang Grandegger <wg@denx.de>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <mpc824x.h>
+#include <pci.h>
+
+#include "pn62.h"
+
+
+static int get_serial_number (char *string, int size);
+static int get_mac_address (int id, u8 * mac, char *string, int size);
+
+#ifdef CONFIG_SHOW_BOOT_PROGRESS
+void show_boot_progress (int phase)
+{
+ /*
+ * Show phases of the bootm command on the front panel
+ * LEDs and the scratchpad register #3 as well. We use
+ * blinking LEDs for logical "1".
+ */
+ if (phase > 0) {
+ set_led (8, (phase & 0x1) ? LED_SLOW_CLOCK : LED_0);
+ set_led (9, (phase & 0x2) ? LED_SLOW_CLOCK : LED_0);
+ set_led (10, (phase & 0x4) ? LED_SLOW_CLOCK : LED_0);
+ set_led (11, (phase & 0x8) ? LED_SLOW_CLOCK : LED_0);
+ }
+ i2155x_write_scrapad (BOOT_STATUS, phase);
+ if (phase < 0)
+ i2155x_write_scrapad (BOOT_DONE, BOOT_DONE_ERROR);
+}
+#endif
+
+void show_startup_phase (int phase)
+{
+ /*
+ * Show the phase of U-Boot startup on the front panel
+ * LEDs and the scratchpad register #3 as well.
+ */
+ if (phase > 0) {
+ set_led (8, (phase & 0x1) ? LED_1 : LED_0);
+ set_led (9, (phase & 0x2) ? LED_1 : LED_0);
+ set_led (10, (phase & 0x4) ? LED_1 : LED_0);
+ set_led (11, (phase & 0x8) ? LED_1 : LED_0);
+ }
+ i2155x_write_scrapad (BOOT_STATUS, phase);
+ if (phase < 0)
+ i2155x_write_scrapad (BOOT_DONE, BOOT_DONE_ERROR);
+}
+
+int checkboard (void)
+{
+ show_startup_phase (1);
+ puts ("Board: PN62\n");
+ return 0;
+}
+
+long int initdram (int board_type)
+{
+ int i, cnt;
+ volatile uchar *base = CFG_SDRAM_BASE;
+ volatile ulong *addr;
+ ulong save[32];
+ ulong val, ret = 0;
+
+ show_startup_phase (2);
+
+ for (i = 0, cnt = (CFG_MAX_RAM_SIZE / sizeof (long)) >> 1; cnt > 0;
+ cnt >>= 1) {
+ addr = (volatile ulong *) base + cnt;
+ save[i++] = *addr;
+ *addr = ~cnt;
+ }
+
+ addr = (volatile ulong *) base;
+ save[i] = *addr;
+ *addr = 0;
+
+ if (*addr != 0) {
+ *addr = save[i];
+ goto Done;
+ }
+
+ for (cnt = 1; cnt <= CFG_MAX_RAM_SIZE / sizeof (long); cnt <<= 1) {
+ addr = (volatile ulong *) base + cnt;
+ val = *addr;
+ *addr = save[--i];
+ if (val != ~cnt) {
+ ulong new_bank0_end = cnt * sizeof (long) - 1;
+ ulong mear1 = mpc824x_mpc107_getreg (MEAR1);
+ ulong emear1 = mpc824x_mpc107_getreg (EMEAR1);
+
+ mear1 = (mear1 & 0xFFFFFF00) |
+ ((new_bank0_end & MICR_ADDR_MASK) >> MICR_ADDR_SHIFT);
+ emear1 = (emear1 & 0xFFFFFF00) |
+ ((new_bank0_end & MICR_ADDR_MASK) >> MICR_EADDR_SHIFT);
+ mpc824x_mpc107_setreg (MEAR1, mear1);
+ mpc824x_mpc107_setreg (EMEAR1, emear1);
+
+ ret = cnt * sizeof (long);
+ goto Done;
+ }
+ }
+
+ ret = CFG_MAX_RAM_SIZE;
+ Done:
+ show_startup_phase (3);
+ return ret;
+}
+
+/*
+ * Initialize PCI Devices. We rely on auto-configuration.
+ */
+#ifndef CONFIG_PCI_PNP
+#error "CONFIG_PCI_PNP is not defined, please correct!"
+#endif
+
+struct pci_controller hose = {
+};
+
+void pci_init (void)
+{
+ show_startup_phase (4);
+ pci_mpc824x_init (&hose);
+
+ show_startup_phase (5);
+ i2155x_init ();
+ show_startup_phase (6);
+ am79c95x_init ();
+ show_startup_phase (7);
+}
+
+int misc_init_r (void)
+{
+ DECLARE_GLOBAL_DATA_PTR;
+
+ char str[20];
+ u8 mac[6];
+
+ show_startup_phase (8);
+ /*
+ * Get serial number and ethernet addresses if not already defined
+ * and update the board info structure and the environment.
+ */
+ if (getenv ("serial#") == NULL &&
+ get_serial_number (str, strlen (str)) > 0) {
+ setenv ("serial#", str);
+ }
+ show_startup_phase (9);
+
+ if (getenv ("ethaddr") == NULL &&
+ get_mac_address (0, mac, str, sizeof (str)) > 0) {
+ setenv ("ethaddr", str);
+ memcpy (gd->bd->bi_enetaddr, mac, 6);
+ }
+ show_startup_phase (10);
+
+ if (getenv ("eth1addr") == NULL &&
+ get_mac_address (1, mac, str, sizeof (str)) > 0) {
+ setenv ("eth1addr", str);
+ memcpy (gd->bd->bi_enet1addr, mac, 6);
+ }
+ show_startup_phase (11);
+
+ /* Tell everybody that U-Boot is up and runnig */
+ i2155x_write_scrapad (0, 0x12345678);
+ return (0);
+}
+
+static int get_serial_number (char *string, int size)
+{
+ int i;
+ char c;
+
+ if (size < I2155X_VPD_SN_SIZE)
+ size = I2155X_VPD_SN_SIZE;
+ for (i = 0; i < (size - 1); i++) {
+ i2155x_read_vpd (I2155X_VPD_SN_START + i, 1, &c);
+ if (c == '\0')
+ break;
+ string[i] = c;
+ }
+ string[i] = '\0'; /* make sure it's terminated */
+
+ return i;
+}
+
+static int get_mac_address (int id, u8 * mac, char *string, int size)
+{
+ if (size < 6 * 3)
+ return -1;
+
+ i2155x_read_vpd (I2155X_VPD_MAC0_START + 6 * id, 6, mac);
+ return sprintf (string, "%02x:%02x:%02x:%02x:%02x:%02x",
+ mac[0], mac[1], mac[2],
+ mac[3], mac[4], mac[5]);
+}
--- /dev/null
+/*
+ * (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 <common.h>
+#include <config.h>
+#include <mpc8xx.h>
+#include <i2c.h>
+
+#include <commproc.h>
+#include <command.h>
+#include <cmd_bsp.h>
+#include <malloc.h>
+
+#include <linux/types.h>
+#include <linux/string.h> /* for strdup */
+
+
+/*
+ * Memory Controller Using
+ *
+ * CS0 - Flash memory (0x40000000)
+ * CS1 - SDRAM (0x00000000}
+ * CS2 -
+ * CS3 -
+ * CS4 -
+ * CS5 -
+ * CS6 - PCMCIA device
+ * CS7 - PCMCIA device
+ */
+
+/* ------------------------------------------------------------------------- */
+
+#define _not_used_ 0xffffffff
+
+const uint sdram_table[]=
+{
+ /* single read. (offset 0 in upm RAM) */
+ 0x1f07fc04, 0xeeaefc04, 0x11adfc04, 0xefbbbc00,
+ 0x1ff77c47,
+
+ /* MRS initialization (offset 5) */
+
+ 0x1ff77c34, 0xefeabc34, 0x1fb57c35,
+
+ /* burst read. (offset 8 in upm RAM) */
+ 0x1f07fc04, 0xeeaefc04, 0x10adfc04, 0xf0affc00,
+ 0xf0affc00, 0xf1affc00, 0xefbbbc00, 0x1ff77c47,
+ _not_used_, _not_used_, _not_used_, _not_used_,
+ _not_used_, _not_used_, _not_used_, _not_used_,
+
+ /* single write. (offset 18 in upm RAM) */
+ 0x1f27fc04, 0xeeaebc00, 0x01b93c04, 0x1ff77c47,
+ _not_used_, _not_used_, _not_used_, _not_used_,
+
+ /* burst write. (offset 20 in upm RAM) */
+ 0x1f07fc04, 0xeeaebc00, 0x10ad7c00, 0xf0affc00,
+ 0xf0affc00, 0xe1bbbc04, 0x1ff77c47, _not_used_,
+ _not_used_, _not_used_, _not_used_, _not_used_,
+ _not_used_, _not_used_, _not_used_, _not_used_,
+
+ /* refresh. (offset 30 in upm RAM) */
+ 0x1ff5fc84, 0xfffffc04, 0xfffffc04, 0xfffffc04,
+ 0xfffffc84, 0xfffffc07, _not_used_, _not_used_,
+ _not_used_, _not_used_, _not_used_, _not_used_,
+
+ /* exception. (offset 3c in upm RAM) */
+ 0x7ffffc07, _not_used_, _not_used_, _not_used_ };
+
+/* ------------------------------------------------------------------------- */
+
+/*
+ * Check Board Identity:
+ */
+
+int checkboard (void)
+{
+ puts ("Board: R360 MPI Board\n");
+ return 0;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static long int dram_size (long int, long int *, long int);
+
+/* ------------------------------------------------------------------------- */
+
+long int initdram (int board_type)
+{
+ volatile immap_t *immap = (immap_t *) CFG_IMMR;
+ volatile memctl8xx_t *memctl = &immap->im_memctl;
+ long int size8, size9;
+ long int size_b0 = 0;
+ unsigned long reg;
+
+ upmconfig (UPMA, (uint *) sdram_table,
+ sizeof (sdram_table) / sizeof (uint));
+
+ /*
+ * Preliminary prescaler for refresh (depends on number of
+ * banks): This value is selected for four cycles every 62.4 us
+ * with two SDRAM banks or four cycles every 31.2 us with one
+ * bank. It will be adjusted after memory sizing.
+ */
+ memctl->memc_mptpr = CFG_MPTPR_2BK_8K;
+
+ memctl->memc_mar = 0x00000088;
+
+ /*
+ * Map controller bank 1 to the SDRAM bank at
+ * preliminary address - these have to be modified after the
+ * SDRAM size has been determined.
+ */
+ memctl->memc_or1 = CFG_OR1_PRELIM;
+ memctl->memc_br1 = CFG_BR1_PRELIM;
+
+ memctl->memc_mamr = CFG_MAMR_8COL & (~(MAMR_PTAE)); /* no refresh yet */
+
+ udelay (200);
+
+ /* perform SDRAM initializsation sequence */
+
+ memctl->memc_mcr = 0x80002105; /* SDRAM bank 0 */
+ udelay (200);
+ memctl->memc_mcr = 0x80002230; /* SDRAM bank 0 - execute twice */
+ udelay (200);
+
+ memctl->memc_mamr |= MAMR_PTAE; /* enable refresh */
+
+ udelay (1000);
+
+ /*
+ * Check Bank 0 Memory Size for re-configuration
+ *
+ * try 8 column mode
+ */
+ size8 = dram_size (CFG_MAMR_8COL, (ulong *) SDRAM_BASE1_PRELIM,
+ SDRAM_MAX_SIZE);
+
+ udelay (1000);
+
+ /*
+ * try 9 column mode
+ */
+ size9 = dram_size (CFG_MAMR_9COL, (ulong *) SDRAM_BASE1_PRELIM,
+ SDRAM_MAX_SIZE);
+
+ if (size8 < size9) { /* leave configuration at 9 columns */
+ size_b0 = size9;
+/* debug ("SDRAM Bank 0 in 9 column mode: %ld MB\n", size >> 20); */
+ } else { /* back to 8 columns */
+ size_b0 = size8;
+ memctl->memc_mamr = CFG_MAMR_8COL;
+ udelay (500);
+/* debug ("SDRAM Bank 0 in 8 column mode: %ld MB\n", size >> 20); */
+ }
+
+ udelay (1000);
+
+ /*
+ * Adjust refresh rate depending on SDRAM type, both banks
+ * For types > 128 MBit leave it at the current (fast) rate
+ */
+ if ((size_b0 < 0x02000000)) {
+ /* reduce to 15.6 us (62.4 us / quad) */
+ memctl->memc_mptpr = CFG_MPTPR_2BK_4K;
+ udelay (1000);
+ }
+
+ /*
+ * Final mapping
+ */
+
+ memctl->memc_or1 = ((-size_b0) & 0xFFFF0000) | CFG_OR_TIMING_SDRAM;
+ memctl->memc_br1 = (CFG_SDRAM_BASE & BR_BA_MSK) | BR_MS_UPMA | BR_V;
+
+ /* adjust refresh rate depending on SDRAM type, one bank */
+ reg = memctl->memc_mptpr;
+ reg >>= 1; /* reduce to CFG_MPTPR_1BK_8K / _4K */
+ memctl->memc_mptpr = reg;
+
+ udelay (10000);
+
+ return (size_b0);
+}
+
+/* ------------------------------------------------------------------------- */
+
+/*
+ * Check memory range for valid RAM. A simple memory test determines
+ * the actually available RAM size between addresses `base' and
+ * `base + maxsize'. Some (not all) hardware errors are detected:
+ * - short between address lines
+ * - short between data lines
+ */
+
+static long int dram_size (long int mamr_value, long int *base,
+ long int maxsize)
+{
+ volatile immap_t *immap = (immap_t *) CFG_IMMR;
+ volatile memctl8xx_t *memctl = &immap->im_memctl;
+ volatile long int *addr;
+ ulong cnt, val;
+ ulong save[32]; /* to make test non-destructive */
+ unsigned char i = 0;
+
+ memctl->memc_mamr = mamr_value;
+
+ for (cnt = maxsize / sizeof (long); cnt > 0; cnt >>= 1) {
+ addr = base + cnt; /* pointer arith! */
+
+ save[i++] = *addr;
+ *addr = ~cnt;
+ }
+
+ /* write 0 to base address */
+ addr = base;
+ save[i] = *addr;
+ *addr = 0;
+
+ /* check at base address */
+ if ((val = *addr) != 0) {
+ *addr = save[i];
+ return (0);
+ }
+
+ for (cnt = 1; cnt <= maxsize / sizeof (long); cnt <<= 1) {
+ addr = base + cnt; /* pointer arith! */
+ val = *addr;
+ *addr = save[--i];
+
+ if (val != (~cnt)) {
+ return (cnt * sizeof (long));
+ }
+ }
+ return (maxsize);
+}
+
+/* ------------------------------------------------------------------------- */
+
+void r360_pwm_write (uchar reg, uchar val)
+{
+ if (i2c_write (CFG_I2C_PWM_ADDR, reg, 1, &val, 1)) {
+ printf ("Can't write PWM register 0x%02X.\n", reg);
+ }
+}
+
+/* ------------------------------------------------------------------------- */
+
+/*-----------------------------------------------------------------------
+ * Keyboard Controller
+ */
+
+/* Number of bytes returned from Keyboard Controller */
+#define KEYBD_KEY_MAX 20 /* maximum key number */
+#define KEYBD_DATALEN ((KEYBD_KEY_MAX + 7) / 8) /* normal key scan data */
+
+static uchar kbd_addr = CFG_I2C_KBD_ADDR;
+
+static uchar *key_match (uchar *);
+
+int misc_init_r (void)
+{
+ uchar kbd_data[KEYBD_DATALEN];
+ uchar keybd_env[2 * KEYBD_DATALEN + 1];
+ uchar *str;
+ int i;
+
+ i2c_init (CFG_I2C_SPEED, CFG_I2C_SLAVE);
+
+ i2c_read (kbd_addr, 0, 0, kbd_data, KEYBD_DATALEN);
+
+ for (i = 0; i < KEYBD_DATALEN; ++i) {
+ sprintf (keybd_env + i + i, "%02X", kbd_data[i]);
+ }
+ setenv ("keybd", keybd_env);
+
+ str = strdup (key_match (kbd_data)); /* decode keys */
+
+#ifdef CONFIG_PREBOOT /* automatically configure "preboot" command on key match */
+ setenv ("preboot", str); /* set or delete definition */
+#endif /* CONFIG_PREBOOT */
+ if (str != NULL) {
+ free (str);
+ }
+
+ return (0);
+}
+
+/*-----------------------------------------------------------------------
+ * Check if pressed key(s) match magic sequence,
+ * and return the command string associated with that key(s).
+ *
+ * If no key press was decoded, NULL is returned.
+ *
+ * Note: the first character of the argument will be overwritten with
+ * the "magic charcter code" of the decoded key(s), or '\0'.
+ *
+ *
+ * Note: the string points to static environment data and must be
+ * saved before you call any function that modifies the environment.
+ */
+#ifdef CONFIG_PREBOOT
+
+static uchar kbd_magic_prefix[] = "key_magic";
+static uchar kbd_command_prefix[] = "key_cmd";
+
+static uchar *key_match (uchar * kbd_data)
+{
+ uchar compare[KEYBD_DATALEN];
+ uchar magic[sizeof (kbd_magic_prefix) + 1];
+ uchar cmd_name[sizeof (kbd_command_prefix) + 1];
+ uchar key_mask;
+ uchar *str, *nxt, *suffix;
+ uchar *kbd_magic_keys;
+ char *cmd;
+ int i;
+
+ /*
+ * The following string defines the characters that can pe appended
+ * to "key_magic" to form the names of environment variables that
+ * hold "magic" key codes, i. e. such key codes that can cause
+ * pre-boot actions. If the string is empty (""), then only
+ * "key_magic" is checked (old behaviour); the string "125" causes
+ * checks for "key_magic1", "key_magic2" and "key_magic5", etc.
+ */
+ if ((kbd_magic_keys = getenv ("magic_keys")) == NULL)
+ kbd_magic_keys = "";
+
+ /* loop over all magic keys;
+ * use '\0' suffix in case of empty string
+ */
+ for (suffix=kbd_magic_keys; *suffix || suffix==kbd_magic_keys; ++suffix) {
+ sprintf (magic, "%s%c", kbd_magic_prefix, *suffix);
+#if 0
+ printf ("### Check magic \"%s\"\n", magic);
+#endif
+
+ memcpy(compare, kbd_data, KEYBD_DATALEN);
+
+ for (str = getenv(magic); str != NULL; str = (*nxt) ? nxt+1 : nxt) {
+ uchar c;
+
+ c = (uchar) simple_strtoul (str, (char **) (&nxt), 16);
+
+ if (str == nxt) /* invalid character */
+ break;
+
+ if (c >= KEYBD_KEY_MAX) /* bad key number */
+ goto next_magic;
+
+ key_mask = 0x80 >> (c % 8);
+
+ if (!(compare[c / 8] & key_mask)) /* key not pressed */
+ goto next_magic;
+
+ compare[c / 8] &= ~key_mask;
+ }
+
+ for (i=0; i<KEYBD_DATALEN; i++)
+ if (compare[i]) /* key(s) not released */
+ goto next_magic;
+
+ sprintf (cmd_name, "%s%c", kbd_command_prefix, *suffix);
+
+ cmd = getenv (cmd_name);
+#if 0
+ printf ("### Set PREBOOT to $(%s): \"%s\"\n",
+ cmd_name, cmd ? cmd : "<<NULL>>");
+#endif
+ *kbd_data = *suffix;
+ return (cmd);
+
+ next_magic:;
+ }
+#if 0
+ printf ("### Delete PREBOOT\n");
+#endif
+ *kbd_data = '\0';
+ return (NULL);
+}
+#endif /* CONFIG_PREBOOT */
+
+/* Read Keyboard status */
+int do_kbd (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
+{
+ uchar kbd_data[KEYBD_DATALEN];
+ uchar keybd_env[2 * KEYBD_DATALEN + 1];
+ int i;
+
+ i2c_init (CFG_I2C_SPEED, CFG_I2C_SLAVE);
+
+ /* Read keys */
+ i2c_read (kbd_addr, 0, 0, kbd_data, KEYBD_DATALEN);
+
+ puts ("Keys:");
+ for (i = 0; i < KEYBD_DATALEN; ++i) {
+ sprintf (keybd_env + i + i, "%02X", kbd_data[i]);
+ printf (" %02x", kbd_data[i]);
+ }
+ putc ('\n');
+ setenv ("keybd", keybd_env);
+ return 0;
+}
--- /dev/null
+/*
+ * (C) Copyright 2002
+ * Custom IDEAS, Inc. <www.cideas.com>
+ * Jon Diekema <diekema@cideas.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <ioports.h>
+#include <mpc8260.h>
+#include <asm/cpm_8260.h>
+#include <configs/sacsng.h>
+
+#include "clkinit.h"
+
+int Daq64xSampling = 0;
+
+
+void Daq_BRG_Reset(uint brg)
+{
+ volatile immap_t *immr = (immap_t *)CFG_IMMR;
+ volatile uint *brg_ptr;
+
+ brg_ptr = (uint *)&immr->im_brgc1;
+
+ if (brg >= 5) {
+ brg_ptr = (uint *)&immr->im_brgc5;
+ brg -= 4;
+ }
+ brg_ptr += brg;
+ *brg_ptr |= CPM_BRG_RST;
+ *brg_ptr &= ~CPM_BRG_RST;
+}
+
+void Daq_BRG_Disable(uint brg)
+{
+ volatile immap_t *immr = (immap_t *)CFG_IMMR;
+ volatile uint *brg_ptr;
+
+ brg_ptr = (uint *)&immr->im_brgc1;
+
+ if (brg >= 5) {
+ brg_ptr = (uint *)&immr->im_brgc5;
+ brg -= 4;
+ }
+ brg_ptr += brg;
+ *brg_ptr &= ~CPM_BRG_EN;
+}
+
+void Daq_BRG_Enable(uint brg)
+{
+ volatile immap_t *immr = (immap_t *)CFG_IMMR;
+ volatile uint *brg_ptr;
+
+ brg_ptr = (uint *)&immr->im_brgc1;
+ if (brg >= 5) {
+ brg_ptr = (uint *)&immr->im_brgc5;
+ brg -= 4;
+ }
+ brg_ptr += brg;
+ *brg_ptr |= CPM_BRG_EN;
+}
+
+uint Daq_BRG_Get_Div16(uint brg)
+{
+ volatile immap_t *immr = (immap_t *)CFG_IMMR;
+ uint *brg_ptr;
+
+ brg_ptr = (uint *)&immr->im_brgc1;
+ if (brg >= 5) {
+ brg_ptr = (uint *)&immr->im_brgc5;
+ brg -= 4;
+ }
+ brg_ptr += brg;
+
+ if (*brg_ptr & CPM_BRG_DIV16) {
+ /* DIV16 active */
+ return (TRUE);
+ }
+ else {
+ /* DIV16 inactive */
+ return (FALSE);
+ }
+}
+
+void Daq_BRG_Set_Div16(uint brg, uint div16)
+{
+ volatile immap_t *immr = (immap_t *)CFG_IMMR;
+ uint *brg_ptr;
+
+ brg_ptr = (uint *)&immr->im_brgc1;
+ if (brg >= 5) {
+ brg_ptr = (uint *)&immr->im_brgc5;
+ brg -= 4;
+ }
+ brg_ptr += brg;
+
+ if (div16) {
+ /* DIV16 active */
+ *brg_ptr |= CPM_BRG_DIV16;
+ }
+ else {
+ /* DIV16 inactive */
+ *brg_ptr &= ~CPM_BRG_DIV16;
+ }
+}
+
+uint Daq_BRG_Get_Count(uint brg)
+{
+ volatile immap_t *immr = (immap_t *)CFG_IMMR;
+ uint *brg_ptr;
+ uint brg_cnt;
+
+ brg_ptr = (uint *)&immr->im_brgc1;
+ if (brg >= 5) {
+ brg_ptr = (uint *)&immr->im_brgc5;
+ brg -= 4;
+ }
+ brg_ptr += brg;
+
+ /* Get the clock divider
+ *
+ * Note: A clock divider of 0 means divide by 1,
+ * therefore we need to add 1 to the count.
+ */
+ brg_cnt = (*brg_ptr & CPM_BRG_CD_MASK) >> CPM_BRG_DIV16_SHIFT;
+ brg_cnt++;
+ if (*brg_ptr & CPM_BRG_DIV16) {
+ brg_cnt *= 16;
+ }
+
+ return (brg_cnt);
+}
+
+void Daq_BRG_Set_Count(uint brg, uint brg_cnt)
+{
+ volatile immap_t *immr = (immap_t *)CFG_IMMR;
+ uint *brg_ptr;
+
+ brg_ptr = (uint *)&immr->im_brgc1;
+ if (brg >= 5) {
+ brg_ptr = (uint *)&immr->im_brgc5;
+ brg -= 4;
+ }
+ brg_ptr += brg;
+
+ /*
+ * Note: A clock divider of 0 means divide by 1,
+ * therefore we need to subtract 1 from the count.
+ */
+ if (brg_cnt > 4096) {
+ /* Prescale = Divide by 16 */
+ *brg_ptr = (*brg_ptr & ~CPM_BRG_CD_MASK) |
+ (((brg_cnt / 16) - 1) << CPM_BRG_DIV16_SHIFT);
+ *brg_ptr |= CPM_BRG_DIV16;
+ }
+ else {
+ /* Prescale = Divide by 1 */
+ *brg_ptr = (*brg_ptr & ~CPM_BRG_CD_MASK) |
+ ((brg_cnt - 1) << CPM_BRG_DIV16_SHIFT);
+ *brg_ptr &= ~CPM_BRG_DIV16;
+ }
+}
+
+uint Daq_BRG_Get_ExtClk(uint brg)
+{
+ volatile immap_t *immr = (immap_t *)CFG_IMMR;
+ uint *brg_ptr;
+
+ brg_ptr = (uint *)&immr->im_brgc1;
+ if (brg >= 5) {
+ brg_ptr = (uint *)&immr->im_brgc5;
+ brg -= 4;
+ }
+ brg_ptr += brg;
+
+ return ((*brg_ptr & CPM_BRG_EXTC_MASK) >> CPM_BRG_EXTC_SHIFT);
+}
+
+char* Daq_BRG_Get_ExtClk_Description(uint brg)
+{
+ uint extc;
+
+ extc = Daq_BRG_Get_ExtClk(brg);
+
+ switch (brg + 1) {
+ case 1:
+ case 2:
+ case 5:
+ case 6: {
+ switch (extc) {
+ case 0: {
+ return ("BRG_INT");
+ }
+ case 1: {
+ return ("CLK3");
+ }
+ case 2: {
+ return ("CLK5");
+ }
+ }
+ return ("??1245??");
+ }
+ case 3:
+ case 4:
+ case 7:
+ case 8: {
+ switch (extc) {
+ case 0: {
+ return ("BRG_INT");
+ }
+ case 1: {
+ return ("CLK9");
+ }
+ case 2: {
+ return ("CLK15");
+ }
+ }
+ return ("??3478??");
+ }
+ }
+ return ("??9876??");
+}
+
+void Daq_BRG_Set_ExtClk(uint brg, uint extc)
+{
+ volatile immap_t *immr = (immap_t *)CFG_IMMR;
+ uint *brg_ptr;
+
+ brg_ptr = (uint *)&immr->im_brgc1;
+ if (brg >= 5) {
+ brg_ptr = (uint *)&immr->im_brgc5;
+ brg -= 4;
+ }
+ brg_ptr += brg;
+
+ *brg_ptr = (*brg_ptr & ~CPM_BRG_EXTC_MASK) |
+ ((extc << CPM_BRG_EXTC_SHIFT) & CPM_BRG_EXTC_MASK);
+}
+
+uint Daq_BRG_Rate(uint brg)
+{
+ DECLARE_GLOBAL_DATA_PTR;
+ volatile immap_t *immr = (immap_t *)CFG_IMMR;
+ uint *brg_ptr;
+ uint brg_cnt;
+ uint brg_freq = 0;
+
+ brg_ptr = (uint *)&immr->im_brgc1;
+ brg_ptr += brg;
+ if (brg >= 5) {
+ brg_ptr = (uint *)&immr->im_brgc5;
+ brg_ptr += (brg - 4);
+ }
+
+ brg_cnt = Daq_BRG_Get_Count(brg);
+
+ switch (Daq_BRG_Get_ExtClk(brg)) {
+ case CPM_BRG_EXTC_CLK3:
+ case CPM_BRG_EXTC_CLK5: {
+ brg_freq = brg_cnt;
+ break;
+ }
+ default: {
+ brg_freq = (uint)BRG_INT_CLK / brg_cnt;
+ }
+ }
+ return (brg_freq);
+}
+
+uint Daq_Get_SampleRate(void)
+
+{
+ /*
+ * Read the BRG's to return the actual sample rate.
+ */
+ return (Daq_BRG_Rate(MCLK_BRG) / (MCLK_DIVISOR * SCLK_DIVISOR));
+}
+
+uint Daq_Set_SampleRate(uint rate, uint force)
+
+{
+ DECLARE_GLOBAL_DATA_PTR;
+ uint mclk_divisor; /* MCLK divisor */
+ uint rate_curr; /* Current sample rate */
+
+ /*
+ * Limit the sample rate to some sensible values.
+ */
+ if (Daq64xSampling) {
+ if (rate > MAX_64x_SAMPLE_RATE) {
+ rate = MAX_64x_SAMPLE_RATE;
+ }
+ }
+ else {
+ if (rate > MAX_128x_SAMPLE_RATE) {
+ rate = MAX_128x_SAMPLE_RATE;
+ }
+ }
+ if (rate < MIN_SAMPLE_RATE) {
+ rate = MIN_SAMPLE_RATE;
+ }
+
+ /* Check to see if we are really changing rates */
+ rate_curr = Daq_Get_SampleRate();
+ if ((rate != rate_curr) || force) {
+ /*
+ * Dynamically adjust MCLK based on the new sample rate.
+ */
+
+ /* Compute the divisors */
+ mclk_divisor = BRG_INT_CLK / (rate * MCLK_DIVISOR * SCLK_DIVISOR);
+
+ /* Setup MCLK */
+ Daq_BRG_Set_Count(MCLK_BRG, mclk_divisor);
+
+ /* Setup SCLK */
+# ifdef RUN_SCLK_ON_BRG_INT
+ Daq_BRG_Set_Count(SCLK_BRG, mclk_divisor * MCLK_DIVISOR);
+# else
+ Daq_BRG_Set_Count(SCLK_BRG, MCLK_DIVISOR);
+# endif
+
+# ifdef RUN_LRCLK_ON_BRG_INT
+ Daq_BRG_Set_Count(LRCLK_BRG,
+ mclk_divisor * MCLK_DIVISOR * SCLK_DIVISOR);
+# else
+ Daq_BRG_Set_Count(LRCLK_BRG, SCLK_DIVISOR);
+# endif
+
+ /* Read the BRG's to return the actual sample rate. */
+ rate_curr = Daq_Get_SampleRate();
+ }
+
+ return (rate_curr);
+}
+
+void Daq_Init_Clocks(int sample_rate, int sample_64x)
+
+{
+ volatile ioport_t *iopa = ioport_addr((immap_t *)CFG_IMMR, 0 /* port A */);
+
+ /* Save off the clocking data */
+ Daq64xSampling = sample_64x;
+
+ /*
+ * Limit the sample rate to some sensible values.
+ */
+ if (Daq64xSampling) {
+ if (sample_rate > MAX_64x_SAMPLE_RATE) {
+ sample_rate = MAX_64x_SAMPLE_RATE;
+ }
+ }
+ else {
+ if (sample_rate > MAX_128x_SAMPLE_RATE) {
+ sample_rate = MAX_128x_SAMPLE_RATE;
+ }
+ }
+ if (sample_rate < MIN_SAMPLE_RATE) {
+ sample_rate = MIN_SAMPLE_RATE;
+ }
+
+ /*
+ * Initialize the MCLK/SCLK/LRCLK baud rate generators.
+ */
+
+ /* Setup MCLK */
+ Daq_BRG_Set_ExtClk(MCLK_BRG, CPM_BRG_EXTC_BRGCLK);
+
+ /* Setup SCLK */
+# ifdef RUN_SCLK_ON_BRG_INT
+ Daq_BRG_Set_ExtClk(SCLK_BRG, CPM_BRG_EXTC_BRGCLK);
+# else
+ Daq_BRG_Set_ExtClk(SCLK_BRG, CPM_BRG_EXTC_CLK9);
+# endif
+
+ /* Setup LRCLK */
+# ifdef RUN_LRCLK_ON_BRG_INT
+ Daq_BRG_Set_ExtClk(LRCLK_BRG, CPM_BRG_EXTC_BRGCLK);
+# else
+ Daq_BRG_Set_ExtClk(LRCLK_BRG, CPM_BRG_EXTC_CLK5);
+# endif
+
+ /* Setup the BRG rates */
+ Daq_Set_SampleRate(sample_rate, TRUE);
+
+ /* Enable the clock drivers */
+ iopa->pdat &= ~SLRCLK_EN_MASK;
+}
+
+void Daq_Stop_Clocks(void)
+
+{
+#ifdef TIGHTEN_UP_BRG_TIMING
+ volatile immap_t *immr = (immap_t *)CFG_IMMR;
+#endif
+
+# ifdef TIGHTEN_UP_BRG_TIMING
+ /*
+ * Reset MCLK BRG
+ */
+# if (MCLK_BRG == 0)
+ immr->im_brgc1 |= CPM_BRG_RST;
+ immr->im_brgc1 &= ~CPM_BRG_RST;
+# endif
+# if (MCLK_BRG == 1)
+ immr->im_brgc2 |= CPM_BRG_RST;
+ immr->im_brgc2 &= ~CPM_BRG_RST;
+# endif
+# if (MCLK_BRG == 2)
+ immr->im_brgc3 |= CPM_BRG_RST;
+ immr->im_brgc3 &= ~CPM_BRG_RST;
+# endif
+# if (MCLK_BRG == 3)
+ immr->im_brgc4 |= CPM_BRG_RST;
+ immr->im_brgc4 &= ~CPM_BRG_RST;
+# endif
+# if (MCLK_BRG == 4)
+ immr->im_brgc5 |= CPM_BRG_RST;
+ immr->im_brgc5 &= ~CPM_BRG_RST;
+# endif
+# if (MCLK_BRG == 5)
+ immr->im_brgc6 |= CPM_BRG_RST;
+ immr->im_brgc6 &= ~CPM_BRG_RST;
+# endif
+# if (MCLK_BRG == 6)
+ immr->im_brgc7 |= CPM_BRG_RST;
+ immr->im_brgc7 &= ~CPM_BRG_RST;
+# endif
+# if (MCLK_BRG == 7)
+ immr->im_brgc8 |= CPM_BRG_RST;
+ immr->im_brgc8 &= ~CPM_BRG_RST;
+# endif
+
+ /*
+ * Reset SCLK BRG
+ */
+# if (SCLK_BRG == 0)
+ immr->im_brgc1 |= CPM_BRG_RST;
+ immr->im_brgc1 &= ~CPM_BRG_RST;
+# endif
+# if (SCLK_BRG == 1)
+ immr->im_brgc2 |= CPM_BRG_RST;
+ immr->im_brgc2 &= ~CPM_BRG_RST;
+# endif
+# if (SCLK_BRG == 2)
+ immr->im_brgc3 |= CPM_BRG_RST;
+ immr->im_brgc3 &= ~CPM_BRG_RST;
+# endif
+# if (SCLK_BRG == 3)
+ immr->im_brgc4 |= CPM_BRG_RST;
+ immr->im_brgc4 &= ~CPM_BRG_RST;
+# endif
+# if (SCLK_BRG == 4)
+ immr->im_brgc5 |= CPM_BRG_RST;
+ immr->im_brgc5 &= ~CPM_BRG_RST;
+# endif
+# if (SCLK_BRG == 5)
+ immr->im_brgc6 |= CPM_BRG_RST;
+ immr->im_brgc6 &= ~CPM_BRG_RST;
+# endif
+# if (SCLK_BRG == 6)
+ immr->im_brgc7 |= CPM_BRG_RST;
+ immr->im_brgc7 &= ~CPM_BRG_RST;
+# endif
+# if (SCLK_BRG == 7)
+ immr->im_brgc8 |= CPM_BRG_RST;
+ immr->im_brgc8 &= ~CPM_BRG_RST;
+# endif
+
+ /*
+ * Reset LRCLK BRG
+ */
+# if (LRCLK_BRG == 0)
+ immr->im_brgc1 |= CPM_BRG_RST;
+ immr->im_brgc1 &= ~CPM_BRG_RST;
+# endif
+# if (LRCLK_BRG == 1)
+ immr->im_brgc2 |= CPM_BRG_RST;
+ immr->im_brgc2 &= ~CPM_BRG_RST;
+# endif
+# if (LRCLK_BRG == 2)
+ immr->im_brgc3 |= CPM_BRG_RST;
+ immr->im_brgc3 &= ~CPM_BRG_RST;
+# endif
+# if (LRCLK_BRG == 3)
+ immr->im_brgc4 |= CPM_BRG_RST;
+ immr->im_brgc4 &= ~CPM_BRG_RST;
+# endif
+# if (LRCLK_BRG == 4)
+ immr->im_brgc5 |= CPM_BRG_RST;
+ immr->im_brgc5 &= ~CPM_BRG_RST;
+# endif
+# if (LRCLK_BRG == 5)
+ immr->im_brgc6 |= CPM_BRG_RST;
+ immr->im_brgc6 &= ~CPM_BRG_RST;
+# endif
+# if (LRCLK_BRG == 6)
+ immr->im_brgc7 |= CPM_BRG_RST;
+ immr->im_brgc7 &= ~CPM_BRG_RST;
+# endif
+# if (LRCLK_BRG == 7)
+ immr->im_brgc8 |= CPM_BRG_RST;
+ immr->im_brgc8 &= ~CPM_BRG_RST;
+# endif
+# else
+ /*
+ * Reset the clocks
+ */
+ Daq_BRG_Reset(MCLK_BRG);
+ Daq_BRG_Reset(SCLK_BRG);
+ Daq_BRG_Reset(LRCLK_BRG);
+# endif
+}
+
+void Daq_Start_Clocks(int sample_rate)
+
+{
+#ifdef TIGHTEN_UP_BRG_TIMING
+ volatile immap_t *immr = (immap_t *)CFG_IMMR;
+
+ uint mclk_brg; /* MCLK BRG value */
+ uint sclk_brg; /* SCLK BRG value */
+ uint lrclk_brg; /* LRCLK BRG value */
+ uint temp_lrclk_brg; /* Temporary LRCLK BRG value */
+ uint real_lrclk_brg; /* Permanent LRCLK BRG value */
+ unsigned long flags; /* Interrupt flags */
+ uint sclk_cnt; /* SCLK count */
+ uint delay_cnt; /* Delay count */
+#endif
+
+# ifdef TIGHTEN_UP_BRG_TIMING
+ /*
+ * Obtain the enabled MCLK BRG value
+ */
+# if (MCLK_BRG == 0)
+ mclk_brg = (immr->im_brgc1 & ~CPM_BRG_RST) | CPM_BRG_EN;
+# endif
+# if (MCLK_BRG == 1)
+ mclk_brg = (immr->im_brgc2 & ~CPM_BRG_RST) | CPM_BRG_EN;
+# endif
+# if (MCLK_BRG == 2)
+ mclk_brg = (immr->im_brgc3 & ~CPM_BRG_RST) | CPM_BRG_EN;
+# endif
+# if (MCLK_BRG == 3)
+ mclk_brg = (immr->im_brgc4 & ~CPM_BRG_RST) | CPM_BRG_EN;
+# endif
+# if (MCLK_BRG == 4)
+ mclk_brg = (immr->im_brgc5 & ~CPM_BRG_RST) | CPM_BRG_EN;
+# endif
+# if (MCLK_BRG == 5)
+ mclk_brg = (immr->im_brgc6 & ~CPM_BRG_RST) | CPM_BRG_EN;
+# endif
+# if (MCLK_BRG == 6)
+ mclk_brg = (immr->im_brgc7 & ~CPM_BRG_RST) | CPM_BRG_EN;
+# endif
+# if (MCLK_BRG == 7)
+ mclk_brg = (immr->im_brgc8 & ~CPM_BRG_RST) | CPM_BRG_EN;
+# endif
+
+ /*
+ * Obtain the enabled SCLK BRG value
+ */
+# if (SCLK_BRG == 0)
+ sclk_brg = (immr->im_brgc1 & ~CPM_BRG_RST) | CPM_BRG_EN;
+# endif
+# if (SCLK_BRG == 1)
+ sclk_brg = (immr->im_brgc2 & ~CPM_BRG_RST) | CPM_BRG_EN;
+# endif
+# if (SCLK_BRG == 2)
+ sclk_brg = (immr->im_brgc3 & ~CPM_BRG_RST) | CPM_BRG_EN;
+# endif
+# if (SCLK_BRG == 3)
+ sclk_brg = (immr->im_brgc4 & ~CPM_BRG_RST) | CPM_BRG_EN;
+# endif
+# if (SCLK_BRG == 4)
+ sclk_brg = (immr->im_brgc5 & ~CPM_BRG_RST) | CPM_BRG_EN;
+# endif
+# if (SCLK_BRG == 5)
+ sclk_brg = (immr->im_brgc6 & ~CPM_BRG_RST) | CPM_BRG_EN;
+# endif
+# if (SCLK_BRG == 6)
+ sclk_brg = (immr->im_brgc7 & ~CPM_BRG_RST) | CPM_BRG_EN;
+# endif
+# if (SCLK_BRG == 7)
+ sclk_brg = (immr->im_brgc8 & ~CPM_BRG_RST) | CPM_BRG_EN;
+# endif
+
+ /*
+ * Obtain the enabled LRCLK BRG value
+ */
+# if (LRCLK_BRG == 0)
+ lrclk_brg = (immr->im_brgc1 & ~CPM_BRG_RST) | CPM_BRG_EN;
+# endif
+# if (LRCLK_BRG == 1)
+ lrclk_brg = (immr->im_brgc2 & ~CPM_BRG_RST) | CPM_BRG_EN;
+# endif
+# if (LRCLK_BRG == 2)
+ lrclk_brg = (immr->im_brgc3 & ~CPM_BRG_RST) | CPM_BRG_EN;
+# endif
+# if (LRCLK_BRG == 3)
+ lrclk_brg = (immr->im_brgc4 & ~CPM_BRG_RST) | CPM_BRG_EN;
+# endif
+# if (LRCLK_BRG == 4)
+ lrclk_brg = (immr->im_brgc5 & ~CPM_BRG_RST) | CPM_BRG_EN;
+# endif
+# if (LRCLK_BRG == 5)
+ lrclk_brg = (immr->im_brgc6 & ~CPM_BRG_RST) | CPM_BRG_EN;
+# endif
+# if (LRCLK_BRG == 6)
+ lrclk_brg = (immr->im_brgc7 & ~CPM_BRG_RST) | CPM_BRG_EN;
+# endif
+# if (LRCLK_BRG == 7)
+ lrclk_brg = (immr->im_brgc8 & ~CPM_BRG_RST) | CPM_BRG_EN;
+# endif
+
+ /* Save off the real LRCLK value */
+ real_lrclk_brg = lrclk_brg;
+
+ /* Obtain the current SCLK count */
+ sclk_cnt = ((sclk_brg & 0x00001FFE) >> 1) + 1;
+
+ /* Compute the delay as a function of SCLK count */
+ delay_cnt = ((sclk_cnt / 4) - 2) * 10 + 6;
+ if (sample_rate == 43402) {
+ delay_cnt++;
+ }
+
+ /* Clear out the count */
+ temp_lrclk_brg = sclk_brg & ~0x00001FFE;
+
+ /* Insert the count */
+ temp_lrclk_brg |= ((delay_cnt + (sclk_cnt / 2) - 1) << 1) & 0x00001FFE;
+
+ /*
+ * Enable MCLK BRG
+ */
+# if (MCLK_BRG == 0)
+ immr->im_brgc1 = mclk_brg;
+# endif
+# if (MCLK_BRG == 1)
+ immr->im_brgc2 = mclk_brg;
+# endif
+# if (MCLK_BRG == 2)
+ immr->im_brgc3 = mclk_brg;
+# endif
+# if (MCLK_BRG == 3)
+ immr->im_brgc4 = mclk_brg;
+# endif
+# if (MCLK_BRG == 4)
+ immr->im_brgc5 = mclk_brg;
+# endif
+# if (MCLK_BRG == 5)
+ immr->im_brgc6 = mclk_brg;
+# endif
+# if (MCLK_BRG == 6)
+ immr->im_brgc7 = mclk_brg;
+# endif
+# if (MCLK_BRG == 7)
+ immr->im_brgc8 = mclk_brg;
+# endif
+
+ /*
+ * Enable SCLK BRG
+ */
+# if (SCLK_BRG == 0)
+ immr->im_brgc1 = sclk_brg;
+# endif
+# if (SCLK_BRG == 1)
+ immr->im_brgc2 = sclk_brg;
+# endif
+# if (SCLK_BRG == 2)
+ immr->im_brgc3 = sclk_brg;
+# endif
+# if (SCLK_BRG == 3)
+ immr->im_brgc4 = sclk_brg;
+# endif
+# if (SCLK_BRG == 4)
+ immr->im_brgc5 = sclk_brg;
+# endif
+# if (SCLK_BRG == 5)
+ immr->im_brgc6 = sclk_brg;
+# endif
+# if (SCLK_BRG == 6)
+ immr->im_brgc7 = sclk_brg;
+# endif
+# if (SCLK_BRG == 7)
+ immr->im_brgc8 = sclk_brg;
+# endif
+
+ /*
+ * Enable LRCLK BRG (1st time - temporary)
+ */
+# if (LRCLK_BRG == 0)
+ immr->im_brgc1 = temp_lrclk_brg;
+# endif
+# if (LRCLK_BRG == 1)
+ immr->im_brgc2 = temp_lrclk_brg;
+# endif
+# if (LRCLK_BRG == 2)
+ immr->im_brgc3 = temp_lrclk_brg;
+# endif
+# if (LRCLK_BRG == 3)
+ immr->im_brgc4 = temp_lrclk_brg;
+# endif
+# if (LRCLK_BRG == 4)
+ immr->im_brgc5 = temp_lrclk_brg;
+# endif
+# if (LRCLK_BRG == 5)
+ immr->im_brgc6 = temp_lrclk_brg;
+# endif
+# if (LRCLK_BRG == 6)
+ immr->im_brgc7 = temp_lrclk_brg;
+# endif
+# if (LRCLK_BRG == 7)
+ immr->im_brgc8 = temp_lrclk_brg;
+# endif
+
+ /*
+ * Enable LRCLK BRG (2nd time - permanent)
+ */
+# if (LRCLK_BRG == 0)
+ immr->im_brgc1 = real_lrclk_brg;
+# endif
+# if (LRCLK_BRG == 1)
+ immr->im_brgc2 = real_lrclk_brg;
+# endif
+# if (LRCLK_BRG == 2)
+ immr->im_brgc3 = real_lrclk_brg;
+# endif
+# if (LRCLK_BRG == 3)
+ immr->im_brgc4 = real_lrclk_brg;
+# endif
+# if (LRCLK_BRG == 4)
+ immr->im_brgc5 = real_lrclk_brg;
+# endif
+# if (LRCLK_BRG == 5)
+ immr->im_brgc6 = real_lrclk_brg;
+# endif
+# if (LRCLK_BRG == 6)
+ immr->im_brgc7 = real_lrclk_brg;
+# endif
+# if (LRCLK_BRG == 7)
+ immr->im_brgc8 = real_lrclk_brg;
+# endif
+# else
+ /*
+ * Enable the clocks
+ */
+ Daq_BRG_Enable(LRCLK_BRG);
+ Daq_BRG_Enable(SCLK_BRG);
+ Daq_BRG_Enable(MCLK_BRG);
+# endif
+}
+
+void Daq_Display_Clocks(void)
+
+{
+ volatile immap_t *immr = (immap_t *)CFG_IMMR;
+ uint mclk_divisor; /* Detected MCLK divisor */
+ uint sclk_divisor; /* Detected SCLK divisor */
+
+ printf("\nBRG:\n");
+ if (immr->im_brgc4 != 0) {
+ printf("\tbrgc4\t0x%08x @ 0x%08x, %5d count, %d extc, %8s, MCLK\n",
+ immr->im_brgc4,
+ (uint)&(immr->im_brgc4),
+ Daq_BRG_Get_Count(3),
+ Daq_BRG_Get_ExtClk(3),
+ Daq_BRG_Get_ExtClk_Description(3));
+ }
+ if (immr->im_brgc8 != 0) {
+ printf("\tbrgc8\t0x%08x @ 0x%08x, %5d count, %d extc, %8s, SCLK\n",
+ immr->im_brgc8,
+ (uint)&(immr->im_brgc8),
+ Daq_BRG_Get_Count(7),
+ Daq_BRG_Get_ExtClk(7),
+ Daq_BRG_Get_ExtClk_Description(7));
+ }
+ if (immr->im_brgc6 != 0) {
+ printf("\tbrgc6\t0x%08x @ 0x%08x, %5d count, %d extc, %8s, LRCLK\n",
+ immr->im_brgc6,
+ (uint)&(immr->im_brgc6),
+ Daq_BRG_Get_Count(5),
+ Daq_BRG_Get_ExtClk(5),
+ Daq_BRG_Get_ExtClk_Description(5));
+ }
+ if (immr->im_brgc1 != 0) {
+ printf("\tbrgc1\t0x%08x @ 0x%08x, %5d count, %d extc, %8s, SMC1\n",
+ immr->im_brgc1,
+ (uint)&(immr->im_brgc1),
+ Daq_BRG_Get_Count(0),
+ Daq_BRG_Get_ExtClk(0),
+ Daq_BRG_Get_ExtClk_Description(0));
+ }
+ if (immr->im_brgc2 != 0) {
+ printf("\tbrgc2\t0x%08x @ 0x%08x, %5d count, %d extc, %8s, SMC2\n",
+ immr->im_brgc2,
+ (uint)&(immr->im_brgc2),
+ Daq_BRG_Get_Count(1),
+ Daq_BRG_Get_ExtClk(1),
+ Daq_BRG_Get_ExtClk_Description(1));
+ }
+ if (immr->im_brgc3 != 0) {
+ printf("\tbrgc3\t0x%08x @ 0x%08x, %5d count, %d extc, %8s, SCC1\n",
+ immr->im_brgc3,
+ (uint)&(immr->im_brgc3),
+ Daq_BRG_Get_Count(2),
+ Daq_BRG_Get_ExtClk(2),
+ Daq_BRG_Get_ExtClk_Description(2));
+ }
+ if (immr->im_brgc5 != 0) {
+ printf("\tbrgc5\t0x%08x @ 0x%08x, %5d count, %d extc, %8s\n",
+ immr->im_brgc5,
+ (uint)&(immr->im_brgc5),
+ Daq_BRG_Get_Count(4),
+ Daq_BRG_Get_ExtClk(4),
+ Daq_BRG_Get_ExtClk_Description(4));
+ }
+ if (immr->im_brgc7 != 0) {
+ printf("\tbrgc7\t0x%08x @ 0x%08x, %5d count, %d extc, %8s\n",
+ immr->im_brgc7,
+ (uint)&(immr->im_brgc7),
+ Daq_BRG_Get_Count(6),
+ Daq_BRG_Get_ExtClk(6),
+ Daq_BRG_Get_ExtClk_Description(6));
+ }
+
+# ifdef RUN_SCLK_ON_BRG_INT
+ mclk_divisor = Daq_BRG_Rate(MCLK_BRG) / Daq_BRG_Rate(SCLK_BRG);
+# else
+ mclk_divisor = Daq_BRG_Get_Count(SCLK_BRG);
+# endif
+# ifdef RUN_LRCLK_ON_BRG_INT
+ sclk_divisor = Daq_BRG_Rate(SCLK_BRG) / Daq_BRG_Rate(LRCLK_BRG);
+# else
+ sclk_divisor = Daq_BRG_Get_Count(LRCLK_BRG);
+# endif
+
+ printf("\nADC/DAC Clocking (%d/%d):\n", sclk_divisor, mclk_divisor);
+ printf("\tMCLK %8d Hz, or %3dx SCLK, or %3dx LRCLK\n",
+ Daq_BRG_Rate(MCLK_BRG),
+ mclk_divisor,
+ mclk_divisor * sclk_divisor);
+# ifdef RUN_SCLK_ON_BRG_INT
+ printf("\tSCLK %8d Hz, or %3dx LRCLK\n",
+ Daq_BRG_Rate(SCLK_BRG),
+ sclk_divisor);
+# else
+ printf("\tSCLK %8d Hz, or %3dx LRCLK\n",
+ Daq_BRG_Rate(MCLK_BRG) / mclk_divisor,
+ sclk_divisor);
+# endif
+# ifdef RUN_LRCLK_ON_BRG_INT
+ printf("\tLRCLK %8d Hz\n",
+ Daq_BRG_Rate(LRCLK_BRG));
+# else
+# ifdef RUN_SCLK_ON_BRG_INT
+ printf("\tLRCLK %8d Hz\n",
+ Daq_BRG_Rate(SCLK_BRG) / sclk_divisor);
+# else
+ printf("\tLRCLK %8d Hz\n",
+ Daq_BRG_Rate(MCLK_BRG) / (mclk_divisor * sclk_divisor));
+# endif
+# endif
+ printf("\n");
+}
--- /dev/null
+/*
+ * 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
+ */
+
+#ifdef SKIP
+#undef SKIP
+#endif
+
+#ifdef CONF
+#undef CONF
+#endif
+
+#ifdef DIN
+#undef DIN
+#endif
+
+#ifdef DOUT
+#undef DOUT
+#endif
+
+#ifdef GPIO
+#undef GPIO
+#endif
+
+#ifdef SPEC
+#undef SPEC
+#endif
+
+#ifdef ACTV
+#undef ACTV
+#endif
+
+#ifdef OPEN
+#undef OPEN
+#endif
+
+#define SKIP 0 /* SKIP over this port */
+#define CONF 1 /* CONFiguration the port */
+
+#define DIN 0 /* PDIRx 0: Direction IN */
+#define DOUT 1 /* PDIRx 1: Direction OUT */
+
+#define GPIO 0 /* PPARx 0: General Purpose I/O */
+#define SPEC 1 /* PPARx 1: dedicated to a peripheral function, */
+ /* i.e. the port has a SPECial use. */
+
+#define ACTV 0 /* PODRx 0: ACTiVely driven as an output */
+#define OPEN 1 /* PODRx 1: OPEN-drain driver */
+
+const iop_conf_t iop_conf_tab[4][32] = {
+
+ /* Port A configuration */
+ { /* conf ppar psor pdir podr pdat */
+ /* PA31 */ { CONF, GPIO, 0, DOUT, ACTV, 1 }, /* RODIS8* */
+ /* PA30 */ { CONF, GPIO, 0, DOUT, ACTV, 1 }, /* RODIS7* */
+ /* PA29 */ { CONF, GPIO, 0, DOUT, ACTV, 1 }, /* RODIS6* */
+ /* PA28 */ { CONF, GPIO, 0, DOUT, ACTV, 1 }, /* RODIS5* */
+ /* PA27 */ { CONF, GPIO, 0, DOUT, ACTV, 1 }, /* RODIS4* */
+ /* PA26 */ { CONF, GPIO, 0, DOUT, ACTV, 1 }, /* RODIS3* */
+ /* PA25 */ { CONF, GPIO, 0, DOUT, ACTV, 1 }, /* RODIS2* */
+ /* PA24 */ { CONF, GPIO, 0, DOUT, ACTV, 1 }, /* RODIS1* */
+ /* PA23 */ { CONF, GPIO, 0, DOUT, ACTV, 1 }, /* ODIS_EN* */
+ /* PA22 */ { CONF, GPIO, 0, DOUT, ACTV, 1 }, /* STLED2_EN* */
+ /* PA21 */ { CONF, GPIO, 0, DOUT, ACTV, 1 }, /* STLED1_EN* */
+ /* PA20 */ { CONF, GPIO, 0, DOUT, ACTV, 1 }, /* PLED3_EN* */
+ /* PA19 */ { CONF, GPIO, 0, DOUT, ACTV, 1 }, /* PLED2_EN* */
+ /* PA18 */ { CONF, GPIO, 0, DOUT, ACTV, 0 }, /* PLED1_EN* */
+ /* PA17 */ { CONF, GPIO, 0, DOUT, ACTV, 0 }, /* N/C */
+ /* PA16 */ { CONF, GPIO, 0, DOUT, ACTV, 0 }, /* DAC_RST* */
+ /* PA15 */ { CONF, GPIO, 0, DOUT, ACTV, 1 }, /* CH34SDATA_PU */
+ /* PA14 */ { CONF, GPIO, 0, DOUT, ACTV, 1 }, /* CH12SDATA_PU */
+ /* PA13 */ { CONF, GPIO, 0, DOUT, ACTV, 1 }, /* SLRCLK_EN* */
+ /* PA12 */ { CONF, GPIO, 0, DOUT, ACTV, 1 }, /* MTRX_4ACDC* */
+ /* PA11 */ { CONF, GPIO, 0, DOUT, ACTV, 1 }, /* MTRX_4TEDS* */
+ /* PA10 */ { CONF, GPIO, 0, DOUT, ACTV, 1 }, /* MTRX_4XTDS* */
+ /* PA9 */ { CONF, GPIO, 0, DOUT, ACTV, 1 }, /* MTRX_3ACDC* */
+ /* PA8 */ { CONF, GPIO, 0, DOUT, ACTV, 1 }, /* MTRX_3TEDS* */
+ /* PA7 */ { CONF, GPIO, 0, DOUT, ACTV, 1 }, /* MTRX_3XTDS* */
+ /* PA6 */ { CONF, GPIO, 0, DOUT, ACTV, 1 }, /* MTRX_2ACDC* */
+ /* PA5 */ { CONF, GPIO, 0, DOUT, ACTV, 1 }, /* MTRX_2TEDS* */
+ /* PA4 */ { CONF, GPIO, 0, DOUT, ACTV, 1 }, /* MTRX_2XTDS* */
+ /* PA3 */ { CONF, GPIO, 0, DOUT, ACTV, 0 }, /* N/C */
+ /* PA2 */ { CONF, GPIO, 0, DOUT, ACTV, 1 }, /* MTRX_1ACDC* */
+ /* PA1 */ { CONF, GPIO, 0, DOUT, ACTV, 1 }, /* MTRX_1TEDS* */
+ /* PA0 */ { CONF, GPIO, 0, DOUT, ACTV, 1 } /* MTRX_1XTDS* */
+ },
+
+ /* Port B configuration */
+ { /* conf ppar psor pdir podr pdat */
+ /* PB31 */ { CONF, SPEC, 0, DOUT, ACTV, 0 }, /* FCC2 MII_TX_ER */
+ /* PB30 */ { CONF, SPEC, 0, DIN, ACTV, 0 }, /* FCC2 MII_RX_DV */
+ /* PB29 */ { CONF, SPEC, 1, DOUT, ACTV, 0 }, /* FCC2 MII_TX_EN */
+ /* PB28 */ { CONF, SPEC, 0, DIN, ACTV, 0 }, /* FCC2 MII_RX_ER */
+ /* PB27 */ { CONF, SPEC, 0, DIN, ACTV, 0 }, /* FCC2 MII_COL */
+ /* PB26 */ { CONF, SPEC, 0, DIN, ACTV, 0 }, /* FCC2 MII_CRS */
+ /* PB25 */ { CONF, SPEC, 0, DOUT, ACTV, 0 }, /* FCC2 MII_TXD3 */
+ /* PB24 */ { CONF, SPEC, 0, DOUT, ACTV, 0 }, /* FCC2 MII_TXD2 */
+ /* PB23 */ { CONF, SPEC, 0, DOUT, ACTV, 0 }, /* FCC2 MII_TXD1 */
+ /* PB22 */ { CONF, SPEC, 0, DOUT, ACTV, 0 }, /* FCC2 MII_TXD0 */
+ /* PB21 */ { CONF, SPEC, 0, DIN, ACTV, 0 }, /* FCC2 MII_RXD0 */
+ /* PB20 */ { CONF, SPEC, 0, DIN, ACTV, 0 }, /* FCC2 MII_RXD1 */
+ /* PB19 */ { CONF, SPEC, 0, DIN, ACTV, 0 }, /* FCC2 MII_RXD2 */
+ /* PB18 */ { CONF, SPEC, 0, DIN, ACTV, 0 }, /* FCC2 MII_RXD3 */
+ /* PB17 */ { CONF, GPIO, 0, DOUT, ACTV, 0 }, /* N/C */
+ /* PB16 */ { CONF, GPIO, 0, DOUT, ACTV, 0 }, /* N/C */
+ /* PB15 */ { CONF, GPIO, 0, DOUT, ACTV, 0 }, /* N/C */
+ /* PB14 */ { CONF, SPEC, 1, DIN, ACTV, 0 }, /* L1RXDC1, BSDATA_ADC12 */
+ /* PB13 */ { CONF, GPIO, 0, DOUT, ACTV, 0 }, /* N/C */
+ /* PB12 */ { CONF, SPEC, 1, DIN, ACTV, 0 }, /* L1RSYNCC1, LRCLK */
+ /* PB11 */ { CONF, SPEC, 1, DIN, ACTV, 0 }, /* L1TXDD1, RSDATA_DAC12 */
+ /* PB10 */ { CONF, SPEC, 1, DIN, ACTV, 0 }, /* L1RXDD1, BSDATA_ADC34 */
+ /* PB9 */ { CONF, GPIO, 0, DOUT, ACTV, 0 }, /* N/C */
+ /* PB8 */ { CONF, SPEC, 1, DIN, ACTV, 0 }, /* L1RSYNCD1, LRCLK */
+ /* PB7 */ { CONF, GPIO, 0, DOUT, ACTV, 0 }, /* N/C */
+ /* PB6 */ { CONF, GPIO, 0, DOUT, ACTV, 1 }, /* XCITE_SHDN */
+ /* PB5 */ { CONF, GPIO, 0, DOUT, ACTV, 1 }, /* TRIGGER */
+ /* PB4 */ { CONF, GPIO, 0, DOUT, ACTV, 0 }, /* ARM */
+ /* PB3 */ { SKIP, GPIO, 0, DIN, ACTV, 0 }, /* pin doesn't exist */
+ /* PB2 */ { SKIP, GPIO, 0, DIN, ACTV, 0 }, /* pin doesn't exist */
+ /* PB1 */ { SKIP, GPIO, 0, DIN, ACTV, 0 }, /* pin doesn't exist */
+ /* PB0 */ { SKIP, GPIO, 0, DIN, ACTV, 0 } /* pin doesn't exist */
+ },
+
+ /* Port C */
+ { /* conf ppar psor pdir podr pdat */
+ /* PC31 */ { CONF, GPIO, 0, DOUT, ACTV, 0 }, /* N/C */
+ /* PC30 */ { CONF, GPIO, 0, DOUT, ACTV, 0 }, /* N/C */
+ /* PC29 */ { CONF, SPEC, 0, DIN, ACTV, 0 }, /* CLK3, MCLK */
+ /* PC28 */ { CONF, GPIO, 0, DOUT, ACTV, 0 }, /* TOUT2* */
+#ifdef QQQ
+ /* PC28 */ { CONF, SPEC, 0, DOUT, ACTV, 0 }, /* TOUT2* */
+#endif
+ /* PC27 */ { CONF, SPEC, 0, DIN, ACTV, 0 }, /* CLK5, SCLK */
+ /* PC26 */ { CONF, GPIO, 0, DOUT, ACTV, 0 }, /* N/C */
+ /* PC25 */ { CONF, SPEC, 0, DIN, ACTV, 0 }, /* CLK7, SCLK */
+ /* PC24 */ { CONF, GPIO, 0, DOUT, ACTV, 0 }, /* N/C */
+ /* PC23 */ { CONF, SPEC, 0, DIN, ACTV, 0 }, /* CLK9, MCLK */
+ /* PC22 */ { CONF, GPIO, 0, DOUT, ACTV, 0 }, /* N/C */
+ /* PC21 */ { CONF, SPEC, 0, DOUT, ACTV, 0 }, /* BRGO6 (LRCLK) */
+ /* PC20 */ { CONF, GPIO, 0, DOUT, ACTV, 0 }, /* N/C */
+ /* PC19 */ { CONF, SPEC, 0, DIN, ACTV, 0 }, /* CLK13, MII_RXCLK */
+ /* PC18 */ { CONF, SPEC, 0, DIN, ACTV, 0 }, /* CLK14, MII_TXCLK */
+ /* PC17 */ { CONF, SPEC, 0, DOUT, ACTV, 0 }, /* BRGO8 (SCLK) */
+ /* PC16 */ { CONF, GPIO, 0, DOUT, ACTV, 0 }, /* N/C */
+ /* PC15 */ { CONF, SPEC, 0, DOUT, ACTV, 0 }, /* SMC2_TX */
+ /* PC14 */ { CONF, GPIO, 0, DOUT, ACTV, 0 }, /* N/C */
+ /* PC13 */ { CONF, GPIO, 0, DOUT, ACTV, 0 }, /* N/C */
+ /* PC12 */ { CONF, SPEC, 0, DOUT, ACTV, 0 }, /* TDM_STRB3 */
+ /* PC11 */ { CONF, GPIO, 0, DOUT, ACTV, 0 }, /* N/C */
+ /* PC10 */ { CONF, SPEC, 1, DOUT, ACTV, 0 }, /* TDM_STRB4 */
+ /* PC9 */ { CONF, GPIO, 0, DIN, ACTV, 0 }, /* BPDIS_IN3 */
+ /* PC8 */ { CONF, GPIO, 0, DIN, ACTV, 0 }, /* BPDIS_IN2 */
+ /* PC7 */ { CONF, GPIO, 0, DIN, ACTV, 0 }, /* BPDIS_IN1 */
+ /* PC6 */ { CONF, GPIO, 0, DOUT, ACTV, 0 }, /* N/C */
+ /* PC5 */ { CONF, GPIO, 0, DIN, ACTV, 0 }, /* BTST_IN2* */
+ /* PC4 */ { CONF, GPIO, 0, DIN, ACTV, 0 }, /* BTST_IN1* */
+ /* PC3 */ { CONF, GPIO, 0, DIN, ACTV, 0 }, /* MUSH_STAT */
+ /* PC2 */ { CONF, GPIO, 0, DIN, ACTV, 0 }, /* OUTDRV_STAT */
+ /* PC1 */ { CONF, GPIO, 0, DOUT, OPEN, 1 }, /* PHY_MDIO */
+ /* PC0 */ { CONF, GPIO, 0, DOUT, ACTV, 1 }, /* PHY_MDC */
+ },
+
+ /* Port D */
+ { /* conf ppar psor pdir podr pdat */
+ /* PD31 */ { CONF, SPEC, 0, DIN, ACTV, 0 }, /* SCC1_RX */
+ /* PD30 */ { CONF, SPEC, 1, DOUT, ACTV, 0 }, /* SCC1_TX */
+ /* PD29 */ { CONF, GPIO, 0, DOUT, ACTV, 0 }, /* N/C */
+ /* PD28 */ { CONF, GPIO, 0, DOUT, ACTV, 0 }, /* N/C */
+ /* PD27 */ { CONF, GPIO, 0, DOUT, ACTV, 0 }, /* N/C */
+ /* PD26 */ { CONF, GPIO, 0, DOUT, ACTV, 0 }, /* N/C */
+ /* PD25 */ { CONF, GPIO, 0, DOUT, ACTV, 0 }, /* N/C */
+ /* PD24 */ { CONF, GPIO, 0, DOUT, ACTV, 0 }, /* N/C */
+ /* PD23 */ { CONF, GPIO, 0, DOUT, ACTV, 0 }, /* N/C */
+ /* PD22 */ { CONF, GPIO, 0, DOUT, ACTV, 0 }, /* N/C */
+ /* PD21 */ { CONF, GPIO, 0, DOUT, ACTV, 0 }, /* N/C */
+ /* PD20 */ { CONF, GPIO, 0, DOUT, ACTV, 1 }, /* SPI_ADC_CS* */
+ /* PD19 */ { CONF, GPIO, 0, DOUT, ACTV, 1 }, /* SPI_DAC_CS* */
+#if defined(CONFIG_SOFT_SPI)
+ /* PD18 */ { CONF, GPIO, 0, DOUT, ACTV, 0 }, /* SPI_CLK */
+ /* PD17 */ { CONF, GPIO, 0, DOUT, ACTV, 0 }, /* SPI_MOSI */
+ /* PD16 */ { CONF, GPIO, 0, DIN, ACTV, 0 }, /* SPI_MISO */
+#else
+ /* PD18 */ { CONF, SPEC, 1, DOUT, ACTV, 0 }, /* SPI_CLK */
+ /* PD17 */ { CONF, SPEC, 1, DOUT, ACTV, 0 }, /* SPI_MOSI */
+ /* PD16 */ { CONF, SPEC, 1, DIN, ACTV, 0 }, /* SPI_MISO */
+#endif
+#if defined(CONFIG_SOFT_I2C)
+ /* PD15 */ { CONF, GPIO, 0, DOUT, OPEN, 1 }, /* I2C_SDA */
+ /* PD14 */ { CONF, GPIO, 0, DOUT, ACTV, 1 }, /* I2C_SCL */
+#else
+#if defined(CONFIG_HARD_I2C)
+ /* PD15 */ { CONF, SPEC, 1, DIN, OPEN, 0 }, /* I2C_SDA */
+ /* PD14 */ { CONF, SPEC, 1, DIN, OPEN, 0 }, /* I2C_SCL */
+#else /* normal I/O port pins */
+ /* PD15 */ { CONF, GPIO, 0, DOUT, ACTV, 0 }, /* I2C_SDA */
+ /* PD14 */ { CONF, GPIO, 0, DOUT, ACTV, 0 }, /* I2C_SCL */
+#endif
+#endif
+ /* PD13 */ { CONF, SPEC, 0, DOUT, ACTV, 0 }, /* TDM_STRB1 */
+ /* PD12 */ { CONF, SPEC, 0, DOUT, ACTV, 0 }, /* TDM_STRB2 */
+ /* PD11 */ { CONF, GPIO, 0, DOUT, ACTV, 0 }, /* N/C */
+ /* PD10 */ { CONF, SPEC, 1, DOUT, ACTV, 0 }, /* BRGO4 (MCLK) */
+ /* PD9 */ { CONF, SPEC, 0, DOUT, ACTV, 0 }, /* SMC1_TX */
+ /* PD8 */ { CONF, SPEC, 0, DIN, ACTV, 0 }, /* SMC1_RX */
+ /* PD7 */ { CONF, GPIO, 0, DOUT, ACTV, 1 }, /* N/C */
+ /* PD6 */ { CONF, GPIO, 0, DOUT, ACTV, 1 }, /* N/C */
+ /* PD5 */ { CONF, GPIO, 0, DOUT, ACTV, 1 }, /* N/C */
+ /* PD4 */ { CONF, SPEC, 1, DOUT, ACTV, 1 }, /* SMC2_RX */
+ /* PD3 */ { SKIP, GPIO, 0, DIN, ACTV, 0 }, /* pin doesn't exist */
+ /* PD2 */ { SKIP, GPIO, 0, DIN, ACTV, 0 }, /* pin doesn't exist */
+ /* PD1 */ { SKIP, GPIO, 0, DIN, ACTV, 0 }, /* pin doesn't exist */
+ /* PD0 */ { SKIP, GPIO, 0, DIN, ACTV, 0 } /* pin doesn't exist */
+ }
+};
+
--- /dev/null
+/*
+ * (C) Copyright 2000
+ * Rob Taylor, Flying Pig Systems. robt@flyingpig.com.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <mpc824x.h>
+#include <pci.h>
+
+int checkboard (void)
+{
+ /*TODO: Check processor type */
+
+ puts ( "Board: Sandpoint "
+#ifdef CONFIG_MPC8240
+ "8240"
+#endif
+#ifdef CONFIG_MPC8245
+ "8245"
+#endif
+ " Unity ##Test not implemented yet##\n");
+ return 0;
+}
+
+#if 0 /* NOT USED */
+int checkflash (void)
+{
+ /* TODO: XXX XXX XXX */
+ printf ("## Test not implemented yet ##\n");
+
+ return (0);
+}
+#endif
+
+long int initdram (int board_type)
+{
+ int i, cnt;
+ volatile uchar * base= CFG_SDRAM_BASE;
+ volatile ulong * addr;
+ ulong save[32];
+ ulong val, ret = 0;
+
+ for (i=0, cnt=(CFG_MAX_RAM_SIZE / sizeof(long)) >> 1; cnt > 0; cnt >>= 1) {
+ addr = (volatile ulong *)base + cnt;
+ save[i++] = *addr;
+ *addr = ~cnt;
+ }
+
+ addr = (volatile ulong *)base;
+ save[i] = *addr;
+ *addr = 0;
+
+ if (*addr != 0) {
+ *addr = save[i];
+ goto Done;
+ }
+
+ for (cnt = 1; cnt <= CFG_MAX_RAM_SIZE / sizeof(long); cnt <<= 1) {
+ addr = (volatile ulong *)base + cnt;
+ val = *addr;
+ *addr = save[--i];
+ if (val != ~cnt) {
+ ulong new_bank0_end = cnt * sizeof(long) - 1;
+ ulong mear1 = mpc824x_mpc107_getreg(MEAR1);
+ ulong emear1 = mpc824x_mpc107_getreg(EMEAR1);
+ mear1 = (mear1 & 0xFFFFFF00) |
+ ((new_bank0_end & MICR_ADDR_MASK) >> MICR_ADDR_SHIFT);
+ emear1 = (emear1 & 0xFFFFFF00) |
+ ((new_bank0_end & MICR_ADDR_MASK) >> MICR_EADDR_SHIFT);
+ mpc824x_mpc107_setreg(MEAR1, mear1);
+ mpc824x_mpc107_setreg(EMEAR1, emear1);
+
+ ret = cnt * sizeof(long);
+ goto Done;
+ }
+ }
+
+ ret = CFG_MAX_RAM_SIZE;
+Done:
+ return ret;
+}
+
+/*
+ * Initialize PCI Devices, report devices found.
+ */
+#ifndef CONFIG_PCI_PNP
+static struct pci_config_table pci_sandpoint_config_table[] = {
+ { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, 0x0f, PCI_ANY_ID,
+ pci_cfgfunc_config_device, { PCI_ENET0_IOADDR,
+ PCI_ENET0_MEMADDR,
+ PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER }},
+ { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, 0x10, PCI_ANY_ID,
+ pci_cfgfunc_config_device, { PCI_ENET1_IOADDR,
+ PCI_ENET1_MEMADDR,
+ PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER }},
+ { }
+};
+#endif
+
+struct pci_controller hose = {
+#ifndef CONFIG_PCI_PNP
+ config_table: pci_sandpoint_config_table,
+#endif
+};
+
+void pci_init(void)
+{
+ pci_mpc824x_init(&hose);
+}
--- /dev/null
+/*
+ * (C) Copyright 2000
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
+OUTPUT_ARCH(arm)
+ENTRY(_start)
+SECTIONS
+{
+ . = 0x00000000;
+
+ . = ALIGN(4);
+ .text :
+ {
+ cpu/sa1100/start.o (.text)
+ *(.text)
+ }
+
+ . = ALIGN(4);
+ .rodata : { *(.rodata) }
+
+ . = ALIGN(4);
+ .data : { *(.data) }
+
+ . = ALIGN(4);
+ .got : { *(.got) }
+
+ armboot_end_data = .;
+
+ . = ALIGN(4);
+ .bss : { *(.bss) }
+
+ armboot_end = .;
+}
--- /dev/null
+/*
+ * (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 <common.h>
+#include <mpc8xx.h>
+#include <commproc.h>
+#include <command.h>
+
+/* ------------------------------------------------------------------------- */
+
+static long int dram_size (long int, long int *, long int);
+void can_driver_enable (void);
+void can_driver_disable (void);
+
+int fpga_init(void);
+
+/* ------------------------------------------------------------------------- */
+
+#define _NOT_USED_ 0xFFFFFFFF
+
+const uint sdram_table[] =
+{
+ /*
+ * Single Read. (Offset 0 in UPMA RAM)
+ */
+ 0x1F0DFC04, 0xEEAFBC04, 0x11AF7C04, 0xEFBAFC00,
+ 0x1FF5FC47, /* last */
+ /*
+ * SDRAM Initialization (offset 5 in UPMA RAM)
+ *
+ * This is no UPM entry point. The following definition uses
+ * the remaining space to establish an initialization
+ * sequence, which is executed by a RUN command.
+ *
+ */
+ 0x1FF5FC34, 0xEFEABC34, 0x1FB57C35, /* last */
+ /*
+ * Burst Read. (Offset 8 in UPMA RAM)
+ */
+ 0x1F0DFC04, 0xEEAFBC04, 0x10AF7C04, 0xF0AFFC00,
+ 0xF0AFFC00, 0xF1AFFC00, 0xEFBAFC00, 0x1FF5FC47, /* last */
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ /*
+ * Single Write. (Offset 18 in UPMA RAM)
+ */
+ 0x1F0DFC04, 0xEEABBC00, 0x01B27C04, 0x1FF5FC47, /* last */
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ /*
+ * Burst Write. (Offset 20 in UPMA RAM)
+ */
+ 0x1F0DFC04, 0xEEABBC00, 0x10A77C00, 0xF0AFFC00,
+ 0xF0AFFC00, 0xE1BAFC04, 0x1FF5FC47, /* last */
+ _NOT_USED_,
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ /*
+ * Refresh (Offset 30 in UPMA RAM)
+ */
+ 0x1FFD7C84, 0xFFFFFC04, 0xFFFFFC04, 0xFFFFFC04,
+ 0xFFFFFC84, 0xFFFFFC07, /* last */
+ _NOT_USED_, _NOT_USED_,
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ /*
+ * Exception. (Offset 3c in UPMA RAM)
+ */
+ 0x7FFFFC07, /* last */
+ _NOT_USED_, _NOT_USED_, _NOT_USED_,
+};
+
+/* ------------------------------------------------------------------------- */
+
+
+/*
+ * Check Board Identity:
+ *
+ * Always return 1 (no second DRAM bank since based on TQM8xxL module)
+ */
+
+int checkboard (void)
+{
+ unsigned char *s;
+ unsigned char buf[64];
+
+ s = (getenv_r ("serial#", buf, sizeof(buf)) > 0) ? buf : NULL;
+
+ puts ("Board: Siemens CCM");
+
+ if (s) {
+ puts (" (");
+
+ for (; *s; ++s) {
+ if (*s == ' ')
+ break;
+ putc (*s);
+ }
+ putc (')');
+ }
+
+ putc ('\n');
+
+ return (0);
+}
+
+/* ------------------------------------------------------------------------- */
+
+/*
+ * If Power-On-Reset switch off the Red and Green LED: At reset, the
+ * data direction registers are cleared and must therefore be restored.
+ */
+#define RSR_CSRS 0x08000000
+
+int power_on_reset(void)
+{
+ /* Test Reset Status Register */
+ return ((volatile immap_t *)CFG_IMMR)->im_clkrst.car_rsr & RSR_CSRS ? 0:1;
+}
+
+#define PB_LED_GREEN 0x10000 /* red LED is on PB.15 */
+#define PB_LED_RED 0x20000 /* red LED is on PB.14 */
+#define PB_LEDS (PB_LED_GREEN | PB_LED_RED);
+
+static void init_leds (void)
+{
+ volatile immap_t *immap = (immap_t *)CFG_IMMR;
+
+ immap->im_cpm.cp_pbpar &= ~PB_LEDS;
+ immap->im_cpm.cp_pbodr &= ~PB_LEDS;
+ immap->im_cpm.cp_pbdir |= PB_LEDS;
+ /* Check stop reset status */
+ if (power_on_reset()) {
+ immap->im_cpm.cp_pbdat &= ~PB_LEDS;
+ }
+}
+
+/* ------------------------------------------------------------------------- */
+
+long int initdram (int board_type)
+{
+ volatile immap_t *immap = (immap_t *)CFG_IMMR;
+ volatile memctl8xx_t *memctl = &immap->im_memctl;
+ long int size8, size9;
+ long int size = 0;
+ unsigned long reg;
+
+ upmconfig(UPMA, (uint *)sdram_table, sizeof(sdram_table)/sizeof(uint));
+
+ /*
+ * Preliminary prescaler for refresh (depends on number of
+ * banks): This value is selected for four cycles every 62.4 us
+ * with two SDRAM banks or four cycles every 31.2 us with one
+ * bank. It will be adjusted after memory sizing.
+ */
+ memctl->memc_mptpr = CFG_MPTPR_2BK_8K;
+
+ memctl->memc_mar = 0x00000088;
+
+ /*
+ * Map controller banks 2 and 3 to the SDRAM banks 2 and 3 at
+ * preliminary addresses - these have to be modified after the
+ * SDRAM size has been determined.
+ */
+ memctl->memc_or2 = CFG_OR2_PRELIM;
+ memctl->memc_br2 = CFG_BR2_PRELIM;
+
+ memctl->memc_mamr = CFG_MAMR_8COL & (~(MAMR_PTAE)); /* no refresh yet */
+
+ udelay(200);
+
+ /* perform SDRAM initializsation sequence */
+
+ memctl->memc_mcr = 0x80004105; /* SDRAM bank 0 */
+ udelay(1);
+ memctl->memc_mcr = 0x80004230; /* SDRAM bank 0 - execute twice */
+ udelay(1);
+
+ memctl->memc_mamr |= MAMR_PTAE; /* enable refresh */
+
+ udelay (1000);
+
+ /*
+ * Check Bank 0 Memory Size for re-configuration
+ *
+ * try 8 column mode
+ */
+ size8 = dram_size (CFG_MAMR_8COL, (ulong *)SDRAM_BASE2_PRELIM, SDRAM_MAX_SIZE);
+
+ udelay (1000);
+
+ /*
+ * try 9 column mode
+ */
+ size9 = dram_size (CFG_MAMR_9COL, (ulong *)SDRAM_BASE2_PRELIM, SDRAM_MAX_SIZE);
+
+ if (size8 < size9) { /* leave configuration at 9 columns */
+ size = size9;
+/* debug ("SDRAM in 9 column mode: %ld MB\n", size >> 20); */
+ } else { /* back to 8 columns */
+ size = size8;
+ memctl->memc_mamr = CFG_MAMR_8COL;
+ udelay(500);
+/* debug ("SDRAM in 8 column mode: %ld MB\n", size >> 20); */
+ }
+
+ udelay (1000);
+
+ /*
+ * Adjust refresh rate depending on SDRAM type
+ * For types > 128 MBit leave it at the current (fast) rate
+ */
+ if (size < 0x02000000) {
+ /* reduce to 15.6 us (62.4 us / quad) */
+ memctl->memc_mptpr = CFG_MPTPR_2BK_4K;
+ udelay(1000);
+ }
+
+ /*
+ * Final mapping
+ */
+
+ memctl->memc_or2 = ((-size) & 0xFFFF0000) | CFG_OR_TIMING_SDRAM;
+ memctl->memc_br2 = (CFG_SDRAM_BASE & BR_BA_MSK) | BR_MS_UPMA | BR_V;
+
+
+ /* adjust refresh rate depending on SDRAM type, one bank */
+ reg = memctl->memc_mptpr;
+ reg >>= 1; /* reduce to CFG_MPTPR_1BK_8K / _4K */
+ memctl->memc_mptpr = reg;
+
+ can_driver_enable ();
+ init_leds ();
+
+ udelay(10000);
+
+ return (size);
+}
+
+/* ------------------------------------------------------------------------- */
+
+/*
+ * Warning - both the PUMA load mode and the CAN driver use UPM B,
+ * so make sure only one of both is active.
+ */
+void can_driver_enable (void)
+{
+ volatile immap_t *immap = (immap_t *)CFG_IMMR;
+ volatile memctl8xx_t *memctl = &immap->im_memctl;
+
+ /* Initialize MBMR */
+ memctl->memc_mbmr = MAMR_GPL_B4DIS; /* GPL_B4 ouput line Disable */
+
+ /* Initialize UPMB for CAN: single read */
+ memctl->memc_mdr = 0xFFFFC004;
+ memctl->memc_mcr = 0x0100 | UPMB;
+
+ memctl->memc_mdr = 0x0FFFD004;
+ memctl->memc_mcr = 0x0101 | UPMB;
+
+ memctl->memc_mdr = 0x0FFFC000;
+ memctl->memc_mcr = 0x0102 | UPMB;
+
+ memctl->memc_mdr = 0x3FFFC004;
+ memctl->memc_mcr = 0x0103 | UPMB;
+
+ memctl->memc_mdr = 0xFFFFDC05;
+ memctl->memc_mcr = 0x0104 | UPMB;
+
+ /* Initialize UPMB for CAN: single write */
+ memctl->memc_mdr = 0xFFFCC004;
+ memctl->memc_mcr = 0x0118 | UPMB;
+
+ memctl->memc_mdr = 0xCFFCD004;
+ memctl->memc_mcr = 0x0119 | UPMB;
+
+ memctl->memc_mdr = 0x0FFCC000;
+ memctl->memc_mcr = 0x011A | UPMB;
+
+ memctl->memc_mdr = 0x7FFCC004;
+ memctl->memc_mcr = 0x011B | UPMB;
+
+ memctl->memc_mdr = 0xFFFDCC05;
+ memctl->memc_mcr = 0x011C | UPMB;
+
+ /* Initialize OR3 / BR3 for CAN Bus Controller */
+ memctl->memc_or3 = CFG_OR3_CAN;
+ memctl->memc_br3 = CFG_BR3_CAN;
+}
+
+void can_driver_disable (void)
+{
+ volatile immap_t *immap = (immap_t *)CFG_IMMR;
+ volatile memctl8xx_t *memctl = &immap->im_memctl;
+
+ /* Reset OR3 / BR3 to disable CAN Bus Controller */
+ memctl->memc_br3 = 0;
+ memctl->memc_or3 = 0;
+
+ memctl->memc_mbmr = 0;
+}
+
+
+/* ------------------------------------------------------------------------- */
+
+/*
+ * Check memory range for valid RAM. A simple memory test determines
+ * the actually available RAM size between addresses `base' and
+ * `base + maxsize'. Some (not all) hardware errors are detected:
+ * - short between address lines
+ * - short between data lines
+ */
+
+static long int dram_size (long int mamr_value, long int *base, long int maxsize)
+{
+ volatile immap_t *immap = (immap_t *)CFG_IMMR;
+ volatile memctl8xx_t *memctl = &immap->im_memctl;
+ volatile long int *addr;
+ ulong cnt, val;
+ ulong save[32]; /* to make test non-destructive */
+ unsigned char i = 0;
+
+ memctl->memc_mamr = mamr_value;
+
+ for (cnt = maxsize/sizeof(long); cnt > 0; cnt >>= 1) {
+ addr = base + cnt; /* pointer arith! */
+
+ save[i++] = *addr;
+ *addr = ~cnt;
+ }
+
+ /* write 0 to base address */
+ addr = base;
+ save[i] = *addr;
+ *addr = 0;
+
+ /* check at base address */
+ if ((val = *addr) != 0) {
+ *addr = save[i];
+ return (0);
+ }
+
+ for (cnt = 1; cnt <= maxsize/sizeof(long); cnt <<= 1) {
+ addr = base + cnt; /* pointer arith! */
+
+ val = *addr;
+ *addr = save[--i];
+
+ if (val != (~cnt)) {
+ return (cnt * sizeof(long));
+ }
+ }
+ return (maxsize);
+}
+
+/* ------------------------------------------------------------------------- */
+
+#define ETH_CFG_BITS (CFG_PB_ETH_CFG1 | CFG_PB_ETH_CFG2 | CFG_PB_ETH_CFG3 )
+
+#define ETH_ALL_BITS (ETH_CFG_BITS | CFG_PB_ETH_POWERDOWN)
+
+void reset_phy(void)
+{
+ immap_t *immr = (immap_t *)CFG_IMMR;
+ ulong value;
+
+ /* Configure all needed port pins for GPIO */
+#if CFG_ETH_MDDIS_VALUE
+ immr->im_ioport.iop_padat |= CFG_PA_ETH_MDDIS;
+#else
+ immr->im_ioport.iop_padat &= ~(CFG_PA_ETH_MDDIS | CFG_PA_ETH_RESET); /* Set low */
+#endif
+ immr->im_ioport.iop_papar &= ~(CFG_PA_ETH_MDDIS | CFG_PA_ETH_RESET); /* GPIO */
+ immr->im_ioport.iop_paodr &= ~(CFG_PA_ETH_MDDIS | CFG_PA_ETH_RESET); /* active output */
+ immr->im_ioport.iop_padir |= CFG_PA_ETH_MDDIS | CFG_PA_ETH_RESET; /* output */
+
+ immr->im_cpm.cp_pbpar &= ~(ETH_ALL_BITS); /* GPIO */
+ immr->im_cpm.cp_pbodr &= ~(ETH_ALL_BITS); /* active output */
+
+ value = immr->im_cpm.cp_pbdat;
+
+ /* Assert Powerdown and Reset signals */
+ value |= CFG_PB_ETH_POWERDOWN;
+
+ /* PHY configuration includes MDDIS and CFG1 ... CFG3 */
+#if CFG_ETH_CFG1_VALUE
+ value |= CFG_PB_ETH_CFG1;
+#else
+ value &= ~(CFG_PB_ETH_CFG1);
+#endif
+#if CFG_ETH_CFG2_VALUE
+ value |= CFG_PB_ETH_CFG2;
+#else
+ value &= ~(CFG_PB_ETH_CFG2);
+#endif
+#if CFG_ETH_CFG3_VALUE
+ value |= CFG_PB_ETH_CFG3;
+#else
+ value &= ~(CFG_PB_ETH_CFG3);
+#endif
+
+ /* Drive output signals to initial state */
+ immr->im_cpm.cp_pbdat = value;
+ immr->im_cpm.cp_pbdir |= ETH_ALL_BITS;
+ udelay (10000);
+
+ /* De-assert Ethernet Powerdown */
+ immr->im_cpm.cp_pbdat &= ~(CFG_PB_ETH_POWERDOWN); /* Enable PHY power */
+ udelay (10000);
+
+ /* de-assert RESET signal of PHY */
+ immr->im_ioport.iop_padat |= CFG_PA_ETH_RESET;
+ udelay (1000);
+}
+
+
+int misc_init_r (void)
+{
+ fpga_init();
+ return (0);
+}
+/* ------------------------------------------------------------------------- */
--- /dev/null
+/*
+ * (C) Copyright 2002
+ * Wolfgang Grandegger, DENX Software Engineering, wg@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>
+#include <commproc.h>
+#include <common.h>
+
+#include "../common/fpga.h"
+
+fpga_t fpga_list[] = {
+ { "PUMA" , PUMA_CONF_BASE ,
+ CFG_PC_PUMA_INIT , CFG_PC_PUMA_PROG , CFG_PC_PUMA_DONE }
+};
+int fpga_count = sizeof(fpga_list) / sizeof(fpga_t);
+
+void can_driver_enable (void);
+void can_driver_disable (void);
+
+#define _NOT_USED_ 0xFFFFFFFF
+
+/*
+ * PUMA access using UPM B
+ */
+const uint puma_table[] =
+{
+ /*
+ * Single Read. (Offset 0 in UPM RAM)
+ */
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ _NOT_USED_,
+ /*
+ * Precharge and MRS
+ */
+ _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ /*
+ * Burst Read. (Offset 8 in UPM RAM)
+ */
+ _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_,
+ /*
+ * Single Write. (Offset 18 in UPM RAM)
+ */
+ 0x0FFCF804, 0x0FFCF400, 0x3FFDFC47, /* last */
+ _NOT_USED_,
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ /*
+ * Burst Write. (Offset 20 in UPM RAM)
+ */
+ _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_,
+ /*
+ * Refresh (Offset 30 in UPM RAM)
+ */
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ /*
+ * Exception. (Offset 3c in UPM RAM)
+ */
+ 0x7FFFFC07, /* last */
+ _NOT_USED_, _NOT_USED_, _NOT_USED_,
+};
+
+
+ulong fpga_control (fpga_t* fpga, int cmd)
+{
+ volatile immap_t *immr = (immap_t *)CFG_IMMR;
+ volatile memctl8xx_t *memctl = &immr->im_memctl;
+
+ switch (cmd) {
+ case FPGA_INIT_IS_HIGH:
+ immr->im_ioport.iop_pcdir &= ~fpga->init_mask; /* input */
+ return (immr->im_ioport.iop_pcdat & fpga->init_mask) ? 1:0;
+
+ case FPGA_INIT_SET_LOW:
+ immr->im_ioport.iop_pcdir |= fpga->init_mask; /* output */
+ immr->im_ioport.iop_pcdat &= ~fpga->init_mask;
+ break;
+
+ case FPGA_INIT_SET_HIGH:
+ immr->im_ioport.iop_pcdir |= fpga->init_mask; /* output */
+ immr->im_ioport.iop_pcdat |= fpga->init_mask;
+ break;
+
+ case FPGA_PROG_SET_LOW:
+ immr->im_ioport.iop_pcdat &= ~fpga->prog_mask;
+ break;
+
+ case FPGA_PROG_SET_HIGH:
+ immr->im_ioport.iop_pcdat |= fpga->prog_mask;
+ break;
+
+ case FPGA_DONE_IS_HIGH:
+ return (immr->im_ioport.iop_pcdat & fpga->done_mask) ? 1:0;
+
+ case FPGA_READ_MODE:
+ /* disable FPGA in memory controller */
+ memctl->memc_br4 = 0;
+ memctl->memc_or4 = PUMA_CONF_OR_READ;
+ memctl->memc_br4 = PUMA_CONF_BR_READ;
+
+ /* (re-) enable CAN drivers */
+ can_driver_enable ();
+
+ break;
+
+ case FPGA_LOAD_MODE:
+ /* disable FPGA in memory controller */
+ memctl->memc_br4 = 0;
+ /*
+ * We must disable the CAN drivers first because
+ * they use UPM B, too.
+ */
+ can_driver_disable ();
+ /*
+ * Configure UPMB for FPGA
+ */
+ upmconfig(UPMB,(uint *)puma_table,sizeof(puma_table)/sizeof(uint));
+ memctl->memc_or4 = PUMA_CONF_OR_LOAD;
+ memctl->memc_br4 = PUMA_CONF_BR_LOAD;
+ break;
+
+ case FPGA_GET_ID:
+ return *(volatile ulong *)fpga->conf_base;
+
+ case FPGA_INIT_PORTS:
+ immr->im_ioport.iop_pcpar &= ~fpga->init_mask; /* INIT I/O */
+ immr->im_ioport.iop_pcso &= ~fpga->init_mask;
+ immr->im_ioport.iop_pcdir &= ~fpga->init_mask;
+
+ immr->im_ioport.iop_pcpar &= ~fpga->prog_mask; /* PROG Output */
+ immr->im_ioport.iop_pcso &= ~fpga->prog_mask;
+ immr->im_ioport.iop_pcdir |= fpga->prog_mask;
+
+ immr->im_ioport.iop_pcpar &= ~fpga->done_mask; /* DONE Input */
+ immr->im_ioport.iop_pcso &= ~fpga->done_mask;
+ immr->im_ioport.iop_pcdir &= ~fpga->done_mask;
+
+ break;
+
+ }
+ return 0;
+}
+
--- /dev/null
+/*
+ * (C) Copyright 2002
+ * Wolfgang Grandegger, DENX Software Engineering, wg@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 <mpc8260.h>
+#include <common.h>
+#include "../common/fpga.h"
+
+fpga_t fpga_list[] = {
+ { "FIOX" , CFG_FIOX_BASE ,
+ CFG_PD_FIOX_INIT , CFG_PD_FIOX_PROG , CFG_PD_FIOX_DONE },
+ { "FDOHM", CFG_FDOHM_BASE,
+ CFG_PD_FDOHM_INIT, CFG_PD_FDOHM_PROG, CFG_PD_FDOHM_DONE }
+};
+int fpga_count = sizeof(fpga_list) / sizeof(fpga_t);
+
+
+ulong fpga_control (fpga_t* fpga, int cmd)
+{
+ volatile immap_t *immr = (immap_t *)CFG_IMMR;
+
+ switch (cmd) {
+ case FPGA_INIT_IS_HIGH:
+ immr->im_ioport.iop_pdird &= ~fpga->init_mask; /* input */
+ return (immr->im_ioport.iop_pdatd & fpga->init_mask) ? 1:0;
+
+ case FPGA_INIT_SET_LOW:
+ immr->im_ioport.iop_pdird |= fpga->init_mask; /* output */
+ immr->im_ioport.iop_pdatd &= ~fpga->init_mask;
+ break;
+
+ case FPGA_INIT_SET_HIGH:
+ immr->im_ioport.iop_pdird |= fpga->init_mask; /* output */
+ immr->im_ioport.iop_pdatd |= fpga->init_mask;
+ break;
+
+ case FPGA_PROG_SET_LOW:
+ immr->im_ioport.iop_pdatd &= ~fpga->prog_mask;
+ break;
+
+ case FPGA_PROG_SET_HIGH:
+ immr->im_ioport.iop_pdatd |= fpga->prog_mask;
+ break;
+
+ case FPGA_DONE_IS_HIGH:
+ return (immr->im_ioport.iop_pdatd & fpga->done_mask) ? 1:0;
+
+ case FPGA_READ_MODE:
+ break;
+
+ case FPGA_LOAD_MODE:
+ break;
+
+ case FPGA_GET_ID:
+ if (fpga->conf_base == CFG_FIOX_BASE) {
+ ulong ver = *(volatile ulong *)(fpga->conf_base + 0x10);
+ return ((ver >> 10) & 0xf) + ((ver >> 2) & 0xf0);
+ }
+ else if (fpga->conf_base == CFG_FDOHM_BASE) {
+ return (*(volatile ushort *)fpga->conf_base) & 0xff;
+ }
+ else {
+ return *(volatile ulong *)fpga->conf_base;
+ }
+
+ case FPGA_INIT_PORTS:
+ immr->im_ioport.iop_ppard &= ~fpga->init_mask; /* INIT I/O */
+ immr->im_ioport.iop_psord &= ~fpga->init_mask;
+ immr->im_ioport.iop_pdird &= ~fpga->init_mask;
+
+ immr->im_ioport.iop_ppard &= ~fpga->prog_mask; /* PROG Output */
+ immr->im_ioport.iop_psord &= ~fpga->prog_mask;
+ immr->im_ioport.iop_pdird |= fpga->prog_mask;
+
+ immr->im_ioport.iop_ppard &= ~fpga->done_mask; /* DONE Input */
+ immr->im_ioport.iop_psord &= ~fpga->done_mask;
+ immr->im_ioport.iop_pdird &= ~fpga->done_mask;
+
+ break;
+
+ }
+ return 0;
+}
--- /dev/null
+CCM/SCM-Ergaenzungen fuer U-Boot und Linux:
+-------------------------------------------
+
+Es gibt nun ein gemeinsames Kommando zum Laden der FPGAs:
+
+ => help fpga
+ fpga fpga status [name] - print FPGA status
+ fpga reset [name] - reset FPGA
+ fpga load [name] addr - load FPGA configuration data
+
+Der Name kann beim CCM-Module auch weggelassen werden.
+Die Laengenangabe und damit "puma_len" ist nicht mehr
+noetig:
+
+ => fpga load puma 40600000
+ FPGA load PUMA: addr 40600000: (00000005)... done
+
+Die MTD-Partitionierung kann nun mittels "bootargs" ueber-
+geben werden:
+
+ => printenv addmtd
+ addmtd=setenv bootargs $(bootargs)
+ mtdparts=0:256k(U-Boot)ro,768k(Kernel),-(Rest)\;1:-(myJFFS2)
+
+Die Portierung auf SMC ist natuerlich noch nicht getestet.
+
+Wolfgang Grandegger (04.06.2002)
--- /dev/null
+/*
+ * (C) Copyright 2002
+ * Wolfgang Grandegger, DENX Software Engineering, wg@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+
+#include <common.h>
+#include <command.h>
+#include <linux/ctype.h>
+#include <common.h>
+#include <cmd_boot.h>
+#include <cmd_bsp.h>
+
+#include "fpga.h"
+
+int power_on_reset(void);
+
+/* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
+
+
+static int fpga_get_version(fpga_t* fpga, char* name)
+{
+ char vname[12];
+ /*
+ * Net-list string format:
+ * "vvvvvvvvddddddddn...".
+ * Version Date Name
+ * "0000000322042002PUMA" = PUMA version 3 from 22.04.2002.
+ */
+ if (strlen(name) < (16 + strlen(fpga->name)))
+ goto failure;
+ /* Check FPGA name */
+ if (strcmp(&name[16], fpga->name) != 0)
+ goto failure;
+ /* Get version number */
+ memcpy(vname, name, 8);
+ vname[8] = '\0';
+ return simple_strtoul(vname, NULL, 16);
+
+ failure:
+ printf("Image name %s is invalid\n", name);
+ return -1;
+}
+
+/* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
+
+static fpga_t* fpga_get(char* fpga_name)
+{
+ char name[FPGA_NAME_LEN];
+ int i;
+
+ if (strlen(fpga_name) >= FPGA_NAME_LEN)
+ goto failure;
+ for (i = 0; i < strlen(fpga_name); i++)
+ name[i] = toupper(fpga_name[i]);
+ name[i] = '\0';
+ for (i = 0; i < fpga_count; i++) {
+ if (strcmp(name, fpga_list[i].name) == 0)
+ return &fpga_list[i];
+ }
+ failure:
+ printf("FPGA: name %s is invalid\n", fpga_name);
+ return NULL;
+}
+
+/* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
+
+static void fpga_status (fpga_t* fpga)
+{
+ /* Check state */
+ if (fpga_control(fpga, FPGA_DONE_IS_HIGH))
+ printf ("%s is loaded (%08lx)\n",
+ fpga->name, fpga_control(fpga, FPGA_GET_ID));
+ else
+ printf ("%s is NOT loaded\n", fpga->name);
+}
+
+/* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
+
+#define FPGA_RESET_TIMEOUT 100 /* = 10 ms */
+
+static int fpga_reset (fpga_t* fpga)
+{
+ int i;
+
+ /* Set PROG to low and wait til INIT goes low */
+ fpga_control(fpga, FPGA_PROG_SET_LOW);
+ for (i = 0; i < FPGA_RESET_TIMEOUT; i++) {
+ udelay (100);
+ if (!fpga_control(fpga, FPGA_INIT_IS_HIGH))
+ break;
+ }
+ if (i == FPGA_RESET_TIMEOUT)
+ goto failure;
+
+ /* Set PROG to high and wait til INIT goes high */
+ fpga_control(fpga, FPGA_PROG_SET_HIGH);
+ for (i = 0; i < FPGA_RESET_TIMEOUT; i++) {
+ udelay (100);
+ if (fpga_control(fpga, FPGA_INIT_IS_HIGH))
+ break;
+ }
+ if (i == FPGA_RESET_TIMEOUT)
+ goto failure;
+
+ return 0;
+ failure:
+ return 1;
+}
+
+/* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
+
+#define FPGA_LOAD_TIMEOUT 100 /* = 10 ms */
+
+static int fpga_load (fpga_t* fpga, ulong addr, int checkall)
+{
+ volatile uchar *fpga_addr = (volatile uchar *)fpga->conf_base;
+ image_header_t hdr;
+ ulong len, checksum;
+ uchar *data = (uchar *)&hdr;
+ char *s, msg[32];
+ int verify, i;
+
+ /*
+ * Check the image header and data of the net-list
+ */
+ memcpy (&hdr, (char *)addr, sizeof(image_header_t));
+
+ if (hdr.ih_magic != IH_MAGIC) {
+ strcpy (msg, "Bad Image Magic Number");
+ goto failure;
+ }
+
+ len = sizeof(image_header_t);
+
+ checksum = hdr.ih_hcrc;
+ hdr.ih_hcrc = 0;
+
+ if (crc32 (0, data, len) != checksum) {
+ strcpy (msg, "Bad Image Header CRC");
+ goto failure;
+ }
+
+ data = (uchar*)(addr + sizeof(image_header_t));
+ len = hdr.ih_size;
+
+ s = getenv ("verify");
+ verify = (s && (*s == 'n')) ? 0 : 1;
+ if (verify) {
+ if (crc32 (0, data, len) != hdr.ih_dcrc) {
+ strcpy (msg, "Bad Image Data CRC");
+ goto failure;
+ }
+ }
+
+ if (checkall && fpga_get_version(fpga, hdr.ih_name) < 0)
+ return 1;
+
+ /* align length */
+ if (len & 1)
+ ++len;
+
+ /*
+ * Reset FPGA and wait for completion
+ */
+ if (fpga_reset(fpga)) {
+ strcpy (msg, "Reset Timeout");
+ goto failure;
+ }
+
+ printf ("(%s)... ", hdr.ih_name);
+ /*
+ * Copy data to FPGA
+ */
+ fpga_control (fpga, FPGA_LOAD_MODE);
+ while (len--) {
+ *fpga_addr = *data++;
+ }
+ fpga_control (fpga, FPGA_READ_MODE);
+
+ /*
+ * Wait for completion and check error status if timeout
+ */
+ for (i = 0; i < FPGA_LOAD_TIMEOUT; i++) {
+ udelay (100);
+ if (fpga_control (fpga, FPGA_DONE_IS_HIGH))
+ break;
+ }
+ if (i == FPGA_LOAD_TIMEOUT) {
+ if (fpga_control(fpga, FPGA_INIT_IS_HIGH))
+ strcpy(msg, "Invalid Size");
+ else
+ strcpy(msg, "CRC Error");
+ goto failure;
+ }
+
+ printf("done\n");
+ return 0;
+
+ failure:
+
+ printf("ERROR: %s\n", msg);
+ return 1;
+}
+
+#if (CONFIG_COMMANDS & CFG_CMD_BSP)
+
+/* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
+
+int do_fpga (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+ ulong addr = 0;
+ int i;
+ fpga_t* fpga;
+
+ if (argc < 2)
+ goto failure;
+
+ if (strncmp(argv[1], "stat", 4) == 0) { /* status */
+ if (argc == 2) {
+ for (i = 0; i < fpga_count; i++) {
+ fpga_status (&fpga_list[i]);
+ }
+ }
+ else if (argc == 3) {
+ if ((fpga = fpga_get(argv[2])) == 0)
+ goto failure;
+ fpga_status (fpga);
+ }
+ else
+ goto failure;
+ }
+ else if (strcmp(argv[1],"load") == 0) { /* load */
+ if (argc == 3 && fpga_count == 1) {
+ fpga = &fpga_list[0];
+ }
+ else if (argc == 4) {
+ if ((fpga = fpga_get(argv[2])) == 0)
+ goto failure;
+ }
+ else
+ goto failure;
+
+ addr = simple_strtoul(argv[argc-1], NULL, 16);
+
+ printf ("FPGA load %s: addr %08lx: ",
+ fpga->name, addr);
+ fpga_load (fpga, addr, 1);
+
+ }
+ else if (strncmp(argv[1], "rese", 4) == 0) { /* reset */
+ if (argc == 2 && fpga_count == 1) {
+ fpga = &fpga_list[0];
+ }
+ else if (argc == 3) {
+ if ((fpga = fpga_get(argv[2])) == 0)
+ goto failure;
+ }
+ else
+ goto failure;
+
+ printf ("FPGA reset %s: ", fpga->name);
+ if (fpga_reset(fpga))
+ printf ("ERROR: Timeout\n");
+ else
+ printf ("done\n");
+ }
+ else
+ goto failure;
+
+ return 0;
+
+ failure:
+ printf ("Usage:\n%s\n", cmdtp->usage);
+ return 1;
+}
+
+#endif /* CONFIG_COMMANDS & CFG_CMD_BSP */
+
+/* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
+
+int fpga_init (void)
+{
+ ulong addr;
+ ulong new_id, old_id = 0;
+ image_header_t *hdr;
+ fpga_t* fpga;
+ int do_load, i, j;
+ char name[16], *s;
+
+ /*
+ * Port setup for FPGA control
+ */
+ for (i = 0; i < fpga_count; i++) {
+ fpga_control(&fpga_list[i], FPGA_INIT_PORTS);
+ }
+
+ /*
+ * Load FPGA(s): a new net-list is loaded if the FPGA is
+ * empty, Power-on-Reset or the old one is not up-to-date
+ */
+ for (i = 0; i < fpga_count; i++) {
+ fpga = &fpga_list[i];
+ printf ("%s: ", fpga->name);
+
+ for (j = 0; j < strlen(fpga->name); j++)
+ name[j] = tolower(fpga->name[j]);
+ name[j] = '\0';
+ sprintf(name, "%s_addr", name);
+ addr = 0;
+ if ((s = getenv(name)) != NULL)
+ addr = simple_strtoul(s, NULL, 16);
+
+ if (!addr) {
+ printf ("env. variable %s undefined\n", name);
+ return 1;
+ }
+
+ hdr = (image_header_t *)addr;
+ if ((new_id = fpga_get_version(fpga, hdr->ih_name)) == -1)
+ return 1;
+
+ do_load = 1;
+
+ if (!power_on_reset() && fpga_control(fpga, FPGA_DONE_IS_HIGH)) {
+ old_id = fpga_control(fpga, FPGA_GET_ID);
+ if (new_id == old_id)
+ do_load = 0;
+ }
+
+ if (do_load) {
+ printf ("loading ");
+ fpga_load (fpga, addr, 0);
+ } else {
+ printf ("loaded (%08lx)\n", old_id);
+ }
+ }
+
+ return 0;
+}
--- /dev/null
+/*
+ * (C) Copyright 2002
+ * Gary Jennejohn, DENX Software Engineering, <gj@denx.de>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
+/*OUTPUT_FORMAT("elf32-arm", "elf32-arm", "elf32-arm")*/
+OUTPUT_ARCH(arm)
+ENTRY(_start)
+SECTIONS
+{
+ . = 0x00000000;
+
+ . = ALIGN(4);
+ .text :
+ {
+ cpu/arm920t/start.o (.text)
+ *(.text)
+ }
+
+ . = ALIGN(4);
+ .rodata : { *(.rodata) }
+
+ . = ALIGN(4);
+ .data : { *(.data) }
+
+ . = ALIGN(4);
+ .got : { *(.got) }
+
+ armboot_end_data = .;
+
+ . = ALIGN(4);
+ .bss : { *(.bss) }
+
+ armboot_end = .;
+}
--- /dev/null
+/*
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Marius Groeger <mgroeger@sysgo.de>
+ *
+ * (C) Copyright 2002
+ * David Mueller, ELSOFT AG, <d.mueller@elsoft.ch>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <s3c2410.h>
+
+/* ------------------------------------------------------------------------- */
+
+#define FCLK_SPEED 1
+
+#if FCLK_SPEED==0 /* Fout = 203MHz, Fin = 12MHz for Audio */
+#define M_MDIV 0xC3
+#define M_PDIV 0x4
+#define M_SDIV 0x1
+#elif FCLK_SPEED==1 /* Fout = 202.8MHz */
+#define M_MDIV 0xA1
+#define M_PDIV 0x3
+#define M_SDIV 0x1
+#endif
+
+#define USB_CLOCK 1
+
+#if USB_CLOCK==0
+#define U_M_MDIV 0xA1
+#define U_M_PDIV 0x3
+#define U_M_SDIV 0x1
+#elif USB_CLOCK==1
+#define U_M_MDIV 0x48
+#define U_M_PDIV 0x3
+#define U_M_SDIV 0x2
+#endif
+
+static inline void delay (unsigned long loops)
+{
+ __asm__ volatile ("1:\n"
+ "subs %0, %1, #1\n"
+ "bne 1b":"=r" (loops):"0" (loops));
+}
+
+/*
+ * Miscellaneous platform dependent initialisations
+ */
+
+int board_init (void)
+{
+ DECLARE_GLOBAL_DATA_PTR;
+
+ /* to reduce PLL lock time, adjust the LOCKTIME register */
+ rLOCKTIME = 0xFFFFFF;
+
+ /* configure MPLL */
+ rMPLLCON = ((M_MDIV << 12) + (M_PDIV << 4) + M_SDIV);
+
+ /* some delay between MPLL and UPLL */
+ delay (4000);
+
+ /* configure UPLL */
+ rUPLLCON = ((U_M_MDIV << 12) + (U_M_PDIV << 4) + U_M_SDIV);
+
+ /* some delay between MPLL and UPLL */
+ delay (8000);
+
+ /* set up the I/O ports */
+ rGPACON = 0x007FFFFF;
+ rGPBCON = 0x00044555;
+ rGPBUP = 0x000007FF;
+ rGPCCON = 0xAAAAAAAA;
+ rGPCUP = 0x0000FFFF;
+ rGPDCON = 0xAAAAAAAA;
+ rGPDUP = 0x0000FFFF;
+ rGPECON = 0xAAAAAAAA;
+ rGPEUP = 0x0000FFFF;
+ rGPFCON = 0x000055AA;
+ rGPFUP = 0x000000FF;
+ rGPGCON = 0xFF95FFBA;
+ rGPGUP = 0x0000FFFF;
+ rGPHCON = 0x002AFAAA;
+ rGPHUP = 0x000007FF;
+
+ /* arch number of SMDK2410-Board */
+ gd->bd->bi_arch_number = 193;
+
+ /* adress of boot parameters */
+ gd->bd->bi_boot_params = 0x30000100;
+
+ icache_enable();
+ dcache_enable();
+
+ return 0;
+}
+
+int dram_init (void)
+{
+ DECLARE_GLOBAL_DATA_PTR;
+
+ gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
+ gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE;
+
+ return 0;
+}
--- /dev/null
+/*
+ * (C) Copyright 2000-2002
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <mpc8xx.h>
+
+#ifndef CFG_ENV_ADDR
+#define CFG_ENV_ADDR (CFG_FLASH_BASE + CFG_ENV_OFFSET)
+#endif
+
+flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */
+
+/*-----------------------------------------------------------------------
+ * 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);
+
+/*-----------------------------------------------------------------------
+ */
+
+unsigned long flash_init (void)
+{
+ volatile immap_t *immap = (immap_t *)CFG_IMMR;
+ volatile memctl8xx_t *memctl = &immap->im_memctl;
+ unsigned long size_b0, size_b1;
+ int i;
+
+ /* Init: no FLASHes known */
+ for (i=0; i<CFG_MAX_FLASH_BANKS; ++i) {
+ flash_info[i].flash_id = FLASH_UNKNOWN;
+ }
+
+ /* Static FLASH Bank configuration here - FIXME XXX */
+
+ size_b0 = flash_get_size((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);
+ }
+
+ size_b1 = flash_get_size((vu_long *)FLASH_BASE1_PRELIM, &flash_info[1]);
+
+ if (size_b1 > size_b0) {
+ printf ("## ERROR: "
+ "Bank 1 (0x%08lx = %ld MB) > Bank 0 (0x%08lx = %ld MB)\n",
+ size_b1, size_b1<<20,
+ size_b0, size_b0<<20
+ );
+ flash_info[0].flash_id = FLASH_UNKNOWN;
+ flash_info[1].flash_id = FLASH_UNKNOWN;
+ flash_info[0].sector_count = -1;
+ flash_info[1].sector_count = -1;
+ flash_info[0].size = 0;
+ flash_info[1].size = 0;
+ return (0);
+ }
+
+ /* Remap FLASH according to real size */
+ memctl->memc_or0 = CFG_OR_TIMING_FLASH | (-size_b0 & OR_AM_MSK);
+ memctl->memc_br0 = (CFG_FLASH_BASE & BR_BA_MSK) | BR_MS_GPCM | BR_V;
+
+ /* Re-do sizing to get full correct info */
+ size_b0 = flash_get_size((vu_long *)CFG_FLASH_BASE, &flash_info[0]);
+
+#if CFG_MONITOR_BASE >= CFG_FLASH_BASE
+ /* monitor protection ON by default */
+ flash_protect(FLAG_PROTECT_SET,
+ CFG_MONITOR_BASE,
+ CFG_MONITOR_BASE+CFG_MONITOR_LEN-1,
+ &flash_info[0]);
+#endif
+
+#ifdef CFG_ENV_IS_IN_FLASH
+ /* ENV protection ON by default */
+ flash_protect(FLAG_PROTECT_SET,
+ CFG_ENV_ADDR,
+ CFG_ENV_ADDR+CFG_ENV_SIZE-1,
+ &flash_info[0]);
+#endif
+
+ if (size_b1) {
+ memctl->memc_or1 = CFG_OR_TIMING_FLASH | (-size_b1 & 0xFFFF8000);
+ memctl->memc_br1 = ((CFG_FLASH_BASE + size_b0) & BR_BA_MSK) |
+ BR_MS_GPCM | BR_V;
+
+ /* Re-do sizing to get full correct info */
+ size_b1 = flash_get_size((vu_long *)(CFG_FLASH_BASE + size_b0),
+ &flash_info[1]);
+
+#if CFG_MONITOR_BASE >= CFG_FLASH_BASE
+ /* monitor protection ON by default */
+ flash_protect(FLAG_PROTECT_SET,
+ CFG_MONITOR_BASE,
+ CFG_MONITOR_BASE+CFG_MONITOR_LEN-1,
+ &flash_info[1]);
+#endif
+
+#ifdef CFG_ENV_IS_IN_FLASH
+ /* ENV protection ON by default */
+ flash_protect(FLAG_PROTECT_SET,
+ CFG_ENV_ADDR,
+ CFG_ENV_ADDR+CFG_ENV_SIZE-1,
+ &flash_info[1]);
+#endif
+ } else {
+ memctl->memc_br1 = 0; /* invalidate bank */
+
+ flash_info[1].flash_id = FLASH_UNKNOWN;
+ flash_info[1].sector_count = -1;
+ }
+
+ flash_info[0].size = size_b0;
+ flash_info[1].size = size_b1;
+
+ return (size_b0 + size_b1);
+}
+
+/*-----------------------------------------------------------------------
+ */
+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;
+ default: printf ("Unknown Vendor "); break;
+ }
+
+ switch (info->flash_id & FLASH_TYPEMASK) {
+ case FLASH_AM400B: printf ("AM29LV400B (4 Mbit, bottom boot sect)\n");
+ break;
+ case FLASH_AM400T: printf ("AM29LV400T (4 Mbit, top boot sector)\n");
+ break;
+ case FLASH_AM800B: printf ("AM29LV800B (8 Mbit, bottom boot sect)\n");
+ break;
+ case FLASH_AM800T: printf ("AM29LV800T (8 Mbit, top boot sector)\n");
+ break;
+ case FLASH_AM160B: printf ("AM29LV160B (16 Mbit, bottom boot sect)\n");
+ break;
+ case FLASH_AM160T: printf ("AM29LV160T (16 Mbit, top boot sector)\n");
+ break;
+ case FLASH_AM320B: printf ("AM29LV320B (32 Mbit, bottom boot sect)\n");
+ break;
+ case FLASH_AM320T: printf ("AM29LV320T (32 Mbit, top boot sector)\n");
+ break;
+ default: printf ("Unknown Chip Type\n");
+ break;
+ }
+
+ printf (" Size: %ld MB in %d Sectors\n",
+ info->size >> 20, info->sector_count);
+
+ printf (" Sector Start Addresses:");
+ for (i=0; i<info->sector_count; ++i) {
+ if ((i % 5) == 0)
+ printf ("\n ");
+ printf (" %08lX%s",
+ info->start[i],
+ info->protect[i] ? " (RO)" : " "
+ );
+ }
+ printf ("\n");
+ return;
+}
+
+/*-----------------------------------------------------------------------
+ */
+
+
+/*-----------------------------------------------------------------------
+ */
+
+/*
+ * 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;
+
+ /* Write auto select command: read Manufacturer ID */
+ addr[0x0555] = 0x00AA00AA;
+ addr[0x02AA] = 0x00550055;
+ addr[0x0555] = 0x00900090;
+
+ value = addr[0];
+
+ switch (value) {
+ case AMD_MANUFACT:
+ info->flash_id = FLASH_MAN_AMD;
+ break;
+ case FUJ_MANUFACT:
+ info->flash_id = FLASH_MAN_FUJ;
+ break;
+ default:
+ info->flash_id = FLASH_UNKNOWN;
+ info->sector_count = 0;
+ info->size = 0;
+ return (0); /* no or unknown flash */
+ }
+
+ value = addr[1]; /* device ID */
+
+ switch (value) {
+ case AMD_ID_LV400T:
+ info->flash_id += FLASH_AM400T;
+ info->sector_count = 11;
+ info->size = 0x00100000;
+ break; /* => 1 MB */
+
+ case AMD_ID_LV400B:
+ info->flash_id += FLASH_AM400B;
+ info->sector_count = 11;
+ info->size = 0x00100000;
+ break; /* => 1 MB */
+
+ case AMD_ID_LV800T:
+ info->flash_id += FLASH_AM800T;
+ info->sector_count = 19;
+ info->size = 0x00200000;
+ break; /* => 2 MB */
+
+ case AMD_ID_LV800B:
+ info->flash_id += FLASH_AM800B;
+ info->sector_count = 19;
+ info->size = 0x00200000;
+ break; /* => 2 MB */
+
+ case AMD_ID_LV160T:
+ info->flash_id += FLASH_AM160T;
+ info->sector_count = 35;
+ info->size = 0x00400000;
+ break; /* => 4 MB */
+
+ case AMD_ID_LV160B:
+ info->flash_id += FLASH_AM160B;
+ info->sector_count = 35;
+ info->size = 0x00400000;
+ break; /* => 4 MB */
+ case AMD_ID_LV320T:
+ info->flash_id += FLASH_AM320T;
+ info->sector_count = 71;
+ info->size = 0x00800000;
+ break; /* => 8 MB */
+
+ case AMD_ID_LV320B:
+ info->flash_id += FLASH_AM320B;
+ info->sector_count = 71;
+ info->size = 0x00800000;
+ break; /* => 8 MB */
+ default:
+ info->flash_id = FLASH_UNKNOWN;
+ return (0); /* => no or unknown flash */
+ }
+
+ /* set up sector start address table */
+ switch (value) {
+ case AMD_ID_LV400B:
+ case AMD_ID_LV800B:
+ case AMD_ID_LV160B:
+ /* set sector offsets for bottom boot block type */
+ info->start[0] = base + 0x00000000;
+ info->start[1] = base + 0x00008000;
+ info->start[2] = base + 0x0000C000;
+ info->start[3] = base + 0x00010000;
+ for (i = 4; i < info->sector_count; i++) {
+ info->start[i] = base + (i * 0x00020000) - 0x00060000;
+ }
+ break;
+ case AMD_ID_LV400T:
+ case AMD_ID_LV800T:
+ case AMD_ID_LV160T:
+ /* set sector offsets for top boot block type */
+ i = info->sector_count - 1;
+ info->start[i--] = base + info->size - 0x00008000;
+ info->start[i--] = base + info->size - 0x0000C000;
+ info->start[i--] = base + info->size - 0x00010000;
+ for (; i >= 0; i--) {
+ info->start[i] = base + i * 0x00020000;
+ }
+ break;
+ case AMD_ID_LV320B:
+ for (i = 0; i < info->sector_count; i++) {
+ info->start[i] = base;
+ /*
+ * The first 8 sectors are 8 kB,
+ * all the other ones are 64 kB
+ */
+ base += (i < 8)
+ ? 2 * ( 8 << 10)
+ : 2 * (64 << 10);
+ }
+ break;
+ case AMD_ID_LV320T:
+ for (i = 0; i < info->sector_count; i++) {
+ info->start[i] = base;
+ /*
+ * The last 8 sectors are 8 kB,
+ * all the other ones are 64 kB
+ */
+ base += (i < (info->sector_count - 8))
+ ? 2 * (64 << 10)
+ : 2 * ( 8 << 10);
+ }
+ break;
+ default:
+ return (0);
+ break;
+ }
+
+ /* check for protected sectors */
+ for (i = 0; i < info->sector_count; i++) {
+ /* read sector protection at sector address, (A7 .. A0) = 0x02 */
+ /* D0 = 1 if protected */
+ addr = (volatile unsigned long *)(info->start[i]);
+ info->protect[i] = addr[2] & 1;
+ }
+
+ /*
+ * Prevent writes to uninitialized FLASH.
+ */
+ if (info->flash_id != FLASH_UNKNOWN) {
+ addr = (volatile unsigned long *)info->start[0];
+
+ *addr = 0x00F000F0; /* reset bank */
+ }
+
+ return (info->size);
+}
+
+
+/*-----------------------------------------------------------------------
+ */
+
+int flash_erase (flash_info_t *info, int s_first, int s_last)
+{
+ vu_long *addr = (vu_long*)(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] = 0x00AA00AA;
+ addr[0x02AA] = 0x00550055;
+ addr[0x0555] = 0x00800080;
+ addr[0x0555] = 0x00AA00AA;
+ addr[0x02AA] = 0x00550055;
+
+ /* Start erase on unprotected sectors */
+ for (sect = s_first; sect<=s_last; sect++) {
+ if (info->protect[sect] == 0) { /* not protected */
+ addr = (vu_long*)(info->start[sect]);
+ addr[0] = 0x00300030;
+ 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_long*)(info->start[l_sect]);
+ while ((addr[0] & 0x00800080) != 0x00800080) {
+ if ((now = get_timer(start)) > CFG_FLASH_ERASE_TOUT) {
+ printf ("Timeout\n");
+ return 1;
+ }
+ /* show that we're waiting */
+ if ((now - last) > 1000) { /* every second */
+ putc ('.');
+ last = now;
+ }
+ }
+
+DONE:
+ /* reset to read mode */
+ addr = (volatile unsigned long *)info->start[0];
+ addr[0] = 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)
+{
+ vu_long *addr = (vu_long*)(info->start[0]);
+ ulong start;
+ int flag;
+
+ /* Check if Flash is (sufficiently) erased */
+ if ((*((vu_long *)dest) & data) != data) {
+ return (2);
+ }
+ /* Disable interrupts which might cause a timeout here */
+ flag = disable_interrupts();
+
+ addr[0x0555] = 0x00AA00AA;
+ addr[0x02AA] = 0x00550055;
+ addr[0x0555] = 0x00A000A0;
+
+ *((vu_long *)dest) = data;
+
+ /* re-enable interrupts if necessary */
+ if (flag)
+ enable_interrupts();
+
+ /* data polling for D7 */
+ start = get_timer (0);
+ while ((*((vu_long *)dest) & 0x00800080) != (data & 0x00800080)) {
+ if (get_timer(start) > CFG_FLASH_WRITE_TOUT) {
+ return (1);
+ }
+ }
+ return (0);
+}
+
+/*-----------------------------------------------------------------------
+ */
--- /dev/null
+/*
+ * (C) Copyright 2000, 2001, 2002
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <mpc8xx.h>
+
+/*-----------------------------------------------------------------------
+ * Process Hardware Information Block:
+ *
+ * If we boot on a system fresh from factory, check if the Hardware
+ * Information Block exists and save the information it contains.
+ *
+ * The TQM8xxL / TQM82xx Hardware Information Block is defined as
+ * follows:
+ * - located in first flash bank
+ * - starts at offset 0x0003FFC0
+ * - size 0x00000040
+ *
+ * Internal structure:
+ * - sequence of ASCII character strings
+ * - fields separated by a single space character (0x20)
+ * - last field terminated by NUL character (0x00)
+ * - remaining space filled with NUL characters (0x00)
+ *
+ * Fields in Hardware Information Block:
+ * 1) Module Type
+ * 2) Serial Number
+ * 3) First MAC Address
+ * 4) Number of additional MAC addresses
+ */
+
+void load_sernum_ethaddr (void)
+{
+ unsigned char *hwi;
+ unsigned char serial [CFG_HWINFO_SIZE];
+ unsigned char ethaddr[CFG_HWINFO_SIZE];
+ unsigned short ih, is, ie, part;
+
+ hwi = (unsigned char *)(CFG_FLASH_BASE + CFG_HWINFO_OFFSET);
+ ih = is = ie = 0;
+
+ if (*((unsigned long *)hwi) != (unsigned long)CFG_HWINFO_MAGIC) {
+ return;
+ }
+
+ part = 1;
+
+ /* copy serial # / MAC address */
+ while ((hwi[ih] != '\0') && (ih < CFG_HWINFO_SIZE)) {
+ if (hwi[ih] < ' ' || hwi[ih] > '~') { /* ASCII strings! */
+ return;
+ }
+ switch (part) {
+ default: /* Copy serial # */
+ if (hwi[ih] == ' ') {
+ ++part;
+ }
+ serial[is++] = hwi[ih];
+ break;
+ case 3: /* Copy MAC address */
+ if (hwi[ih] == ' ') {
+ ++part;
+ break;
+ }
+ ethaddr[ie++] = hwi[ih];
+ if ((ie % 3) == 2)
+ ethaddr[ie++] = ':';
+ break;
+ }
+ ++ih;
+ }
+ serial[is] = '\0';
+ if (ie && ethaddr[ie-1] == ':')
+ --ie;
+ ethaddr[ie] = '\0';
+
+ /* set serial# and ethaddr if not yet defined */
+ if (getenv("serial#") == NULL) {
+ setenv ("serial#", serial);
+ }
+
+ if (getenv("ethaddr") == NULL) {
+ setenv ("ethaddr", ethaddr);
+ }
+}
--- /dev/null
+
+The TRAB keyboard implementation is similar to that for LWMON and
+R360MPI boards. The only difference concerns key naming. There are 4
+keys on TRAB: 1, 2, 3, 4.
+
+1) The "kbd" command provides information about the current state of
+ the keys. For example,
+
+ TRAB # kbd
+ Keys: 1 0 1 0
+
+ means that keys 1 and 3 are pressed. The keyboard status is also
+ stored in the "keybd" environment variable. In this example we get
+
+ keybd=1010
+
+2) The "preboot" variable is set according to current environment
+ settings and keys pressed. This is an example:
+
+ TRAB # setenv magic_keys XY
+ TRAB # setenv key_magicX 12
+ TRAB # setenv key_cmdX echo ## Keys 1 + 2 pressed ##\;echo
+ TRAB # setenv key_magicY 13
+ TRAB # setenv key_cmdY echo ## Keys 1 + 3 pressed ##\;echo
+
+ Here "magic_keys=XY" means that the "key_magicX" and "key_magicY"
+ variables will be checked for a match. Each variable "key_magic*"
+ defines a set of keys. In the our example, if keys 1 and 3 are
+ pressed during reset, then "key_magicY" matches, so the "preboot"
+ variable will be set to the contents of "key_cmdY":
+
+ preboot=echo ## Keys 1 + 3 pressed ##;echo
+
+3) The TRAB board has optional modem support. When a certain key
+ combination is pressed on the keyboard at power-on, the firmware
+ performs the necessary initialization of the modem and allows for
+ dial-in. The key combination is specified in the
+ "include/configs/trab.h" file. For example:
+
+ #define CONFIG_MODEM_KEY_MAGIC "23"
+
+ means that modem will be initialized if and only if both keys 2, 3
+ are pressed. Note that the format of this string is similar to the
+ format of "key_magic*" environment variables described above.
--- /dev/null
+/*
+ * (C) Copyright 2002
+ * Gary Jennejohn, DENX Software Engineering, <gj@denx.de>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/* #define DEBUG */
+
+#include <common.h>
+#include <cmd_bsp.h>
+#include <malloc.h>
+#include <s3c2400.h>
+
+/* ------------------------------------------------------------------------- */
+
+#ifdef CONFIG_MODEM_SUPPORT
+static int key_pressed(void);
+extern void disable_putc(void);
+extern int do_mdm_init; /* defined in common/main.c */
+
+/*
+ * We need a delay of at least 500 us after turning on the VFD clock
+ * before we can read any useful information for the CPLD controlling
+ * the keyboard switches. Let's play safe and wait 5 ms. The problem
+ * is that timers are not available yet, so we use a manually timed
+ * loop.
+ */
+#define KBD_MDELAY 100000 /* 1000 */
+static void mdelay_no_timer (int msec)
+{
+ DECLARE_GLOBAL_DATA_PTR;
+
+ int i;
+ int delay = msec * 3;
+
+ for (i = 0; i < delay; i ++) gd->bd->bi_arch_number = 145;
+}
+#endif /* CONFIG_MODEM_SUPPORT */
+
+/*
+ * Miscellaneous platform dependent initialisations
+ */
+
+int board_init ()
+{
+ DECLARE_GLOBAL_DATA_PTR;
+
+ /* memory and cpu-speed are setup before relocation */
+#ifdef CONFIG_TRAB_50MHZ
+ /* change the clock to be 50 MHz 1:1:1 */
+ /* MDIV:0x5c PDIV:4 SDIV:2 */
+ rMPLLCON = 0x5c042;
+ rCLKDIVN = 0;
+#else
+ /* change the clock to be 133 MHz 1:2:4 */
+ /* MDIV:0x7d PDIV:4 SDIV:1 */
+ rMPLLCON = 0x7d041;
+ rCLKDIVN = 3;
+#endif
+
+ /* set up the I/O ports */
+ rPACON = 0x3ffff;
+ rPBCON = 0xaaaaaaaa;
+ rPBUP = 0xffff;
+ /* INPUT nCTS0 nRTS0 TXD[1] TXD[0] RXD[1] RXD[0] */
+ /* 00, 10, 10, 10, 10, 10, 10 */
+ rPFCON = (2<<0) | (2<<2) | (2<<4) | (2<<6) | (2<<8) | (2<<10);
+#ifdef CONFIG_HWFLOW
+ /* do not pull up RXD0, RXD1, TXD0, TXD1, CTS0, RTS0 */
+ rPFUP = (1<<0) | (1<<1) | (1<<2) | (1<<3) | (1<<4) | (1<<5);
+#else
+ /* do not pull up RXD0, RXD1, TXD0, TXD1 */
+ rPFUP = (1<<0) | (1<<1) | (1<<2) | (1<<3);
+#endif
+ rPGCON = 0x0;
+ rPGUP = 0x0;
+ rOPENCR= 0x0;
+
+ /* arch number of SAMSUNG-Board */
+ /* MACH_TYPE_SMDK2400 */
+ /* XXX this isn't really correct, but keep it for now */
+ gd->bd->bi_arch_number = 145;
+
+ /* adress of boot parameters */
+ gd->bd->bi_boot_params = 0x0c000100;
+
+#ifdef CONFIG_MODEM_SUPPORT
+ /* This stuff is needed to get interrupts on stop-position
+ * contact events.
+ * (Copied from the LCD initialization routine.)
+ */
+ if (rLCDCON1 == 0)
+ {
+ rPCCON = (rPCCON & 0xFFFFFF00)| 0x000000AA;
+ rPDCON = (rPDCON & 0xFFFFFF03)| 0x000000A8;
+#if 0
+ rPDCON = (rPDCON & 0xFFFFFF00)| 0x000000AA;
+#endif
+ rLCDCON2 = 0x000DC000;
+ rLCDCON3 = 0x0051000A;
+ rLCDCON4 = 0x00000001;
+ rLCDCON5 = 0x00000440;
+ rLCDCON1 = 0x00000B75;
+ }
+
+ mdelay_no_timer (KBD_MDELAY);
+
+ if (key_pressed()) {
+ disable_putc(); /* modem doesn't understand banner etc */
+ do_mdm_init = 1;
+ }
+#endif /* CONFIG_MODEM_SUPPORT */
+
+ 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;
+}
+
+/*-----------------------------------------------------------------------
+ * Keyboard Controller
+ */
+
+/* Maximum key number */
+#define KEYBD_KEY_NUM 4
+
+#define KBD_DATA (((*(volatile ulong *)0x04020000) >> 16) & 0xF)
+
+static uchar *key_match (ulong);
+
+int misc_init_r (void)
+{
+ ulong kbd_data = KBD_DATA;
+ uchar keybd_env[KEYBD_KEY_NUM + 1];
+ uchar *str;
+ int i;
+
+ for (i = 0; i < KEYBD_KEY_NUM; ++i) {
+ keybd_env[i] = '0' + ((kbd_data >> i) & 1);
+ }
+ keybd_env[i] = '\0';
+ debug ("** Setting keybd=\"%s\"\n", keybd_env);
+ setenv ("keybd", keybd_env);
+
+ str = strdup (key_match (kbd_data)); /* decode keys */
+
+#ifdef CONFIG_PREBOOT /* automatically configure "preboot" command on key match */
+ debug ("** Setting preboot=\"%s\"\n", str);
+ setenv ("preboot", str); /* set or delete definition */
+#endif /* CONFIG_PREBOOT */
+ if (str != NULL) {
+ free (str);
+ }
+
+ return (0);
+}
+
+#ifdef CONFIG_PREBOOT
+
+static uchar kbd_magic_prefix[] = "key_magic";
+static uchar kbd_command_prefix[] = "key_cmd";
+
+static int compare_magic (ulong kbd_data, uchar *str)
+{
+ uchar key_mask;
+
+ debug ("compare_magic: kbd: %04lx str: \"%s\"\n",kbd_data,str);
+ for (; *str; str++)
+ {
+ uchar c = *str - '1';
+
+ if (c >= KEYBD_KEY_NUM) /* bad key number */
+ return -1;
+
+ key_mask = 1 << c;
+
+ if (!(kbd_data & key_mask)) { /* key not pressed */
+ debug ( "compare_magic: "
+ "kbd: %04lx mask: %04lx - key not pressed\n",
+ kbd_data, key_mask );
+ return -1;
+ }
+
+ kbd_data &= ~key_mask;
+ }
+
+ if (kbd_data) { /* key(s) not released */
+ debug ( "compare_magic: "
+ "kbd: %04lx - key(s) not released\n", kbd_data);
+ return -1;
+ }
+
+ return 0;
+}
+
+/*-----------------------------------------------------------------------
+ * Check if pressed key(s) match magic sequence,
+ * and return the command string associated with that key(s).
+ *
+ * If no key press was decoded, NULL is returned.
+ *
+ * Note: the first character of the argument will be overwritten with
+ * the "magic charcter code" of the decoded key(s), or '\0'.
+ *
+ *
+ * Note: the string points to static environment data and must be
+ * saved before you call any function that modifies the environment.
+ */
+static uchar *key_match (ulong kbd_data)
+{
+ uchar magic[sizeof (kbd_magic_prefix) + 1];
+ uchar cmd_name[sizeof (kbd_command_prefix) + 1];
+ uchar *suffix;
+ uchar *kbd_magic_keys;
+
+ /*
+ * The following string defines the characters that can pe appended
+ * to "key_magic" to form the names of environment variables that
+ * hold "magic" key codes, i. e. such key codes that can cause
+ * pre-boot actions. If the string is empty (""), then only
+ * "key_magic" is checked (old behaviour); the string "125" causes
+ * checks for "key_magic1", "key_magic2" and "key_magic5", etc.
+ */
+ if ((kbd_magic_keys = getenv ("magic_keys")) == NULL)
+ kbd_magic_keys = "";
+
+ debug ("key_match: magic_keys=\"%s\"\n", kbd_magic_keys);
+
+ /* loop over all magic keys;
+ * use '\0' suffix in case of empty string
+ */
+ for (suffix=kbd_magic_keys; *suffix || suffix==kbd_magic_keys; ++suffix)
+ {
+ sprintf (magic, "%s%c", kbd_magic_prefix, *suffix);
+
+ debug ("key_match: magic=\"%s\"\n",
+ getenv(magic) ? getenv(magic) : "<UNDEFINED>");
+
+ if (compare_magic(kbd_data, getenv(magic)) == 0)
+ {
+ sprintf (cmd_name, "%s%c", kbd_command_prefix, *suffix);
+ debug ("key_match: cmdname %s=\"%s\"\n",
+ cmd_name,
+ getenv (cmd_name) ?
+ getenv (cmd_name) :
+ "<UNDEFINED>");
+ return (getenv (cmd_name));
+ }
+ }
+ debug ("key_match: no match\n");
+ return (NULL);
+}
+#endif /* CONFIG_PREBOOT */
+
+/* Read Keyboard status */
+int do_kbd (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
+{
+ ulong kbd_data = KBD_DATA;
+ uchar keybd_env[KEYBD_KEY_NUM + 1];
+ int i;
+
+ puts ("Keys:");
+ for (i = 0; i < KEYBD_KEY_NUM; ++i) {
+ keybd_env[i] = '0' + ((kbd_data >> i) & 1);
+ printf (" %c", keybd_env[i]);
+ }
+ keybd_env[i] = '\0';
+ putc ('\n');
+ setenv ("keybd", keybd_env);
+ return 0;
+}
+
+#ifdef CONFIG_MODEM_SUPPORT
+static int key_pressed(void)
+{
+ return (compare_magic(KBD_DATA, CONFIG_MODEM_KEY_MAGIC) == 0);
+}
+#endif /* CONFIG_MODEM_SUPPORT */
--- /dev/null
+/*
+ * (C) Copyright 2002
+ * Gary Jennejohn, DENX Software Engineering, <gj@denx.de>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
+/*OUTPUT_FORMAT("elf32-arm", "elf32-arm", "elf32-arm")*/
+OUTPUT_ARCH(arm)
+ENTRY(_start)
+SECTIONS
+{
+ . = 0x00000000;
+
+ . = ALIGN(4);
+ .text :
+ {
+ cpu/arm920t/start.o (.text)
+ lib_arm/_udivsi3.o (.text)
+ lib_arm/_umodsi3.o (.text)
+ lib_generic/zlib.o (.text)
+ lib_generic/crc32.o (.text)
+ lib_generic/string.o (.text)
+
+ . = env_offset;
+ common/environment.o (.ppcenv)
+
+ *(.text)
+ }
+
+ . = ALIGN(4);
+ .rodata : { *(.rodata) }
+
+ . = ALIGN(4);
+ .data : { *(.data) }
+
+ . = ALIGN(4);
+ .got : { *(.got) }
+
+ armboot_end_data = .;
+
+ . = ALIGN(4);
+ .bss : { *(.bss) }
+
+ armboot_end = .;
+}
--- /dev/null
+/*
+ * (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
+ */
+
+/************************************************************************/
+/* ** DEBUG SETTINGS */
+/************************************************************************/
+
+/* #define DEBUG */
+
+/************************************************************************/
+/* ** HEADER FILES */
+/************************************************************************/
+
+#include <config.h>
+#include <common.h>
+#include <version.h>
+#include <stdarg.h>
+#include <linux/types.h>
+#include <devices.h>
+#include <s3c2400.h>
+
+#ifdef CONFIG_VFD
+
+/************************************************************************/
+/* ** CONFIG STUFF -- should be moved to board config file */
+/************************************************************************/
+
+/************************************************************************/
+
+#ifndef PAGE_SIZE
+#define PAGE_SIZE 4096
+#endif
+
+#define ROT 0x09
+#define BLAU 0x0C
+#define VIOLETT 0X0D
+
+ulong vfdbase;
+ulong frame_buf_size;
+#define frame_buf_offs 4
+
+/* taken from armboot/common/vfd.c */
+ulong adr_vfd_table[112][18][2][4][2];
+unsigned char bit_vfd_table[112][18][2][4][2];
+
+/*
+ * initialize the values for the VFD-grid-control in the framebuffer
+ */
+void init_grid_ctrl(void)
+{
+ ulong adr, grid_cycle;
+ unsigned int bit, display;
+ unsigned char temp, bit_nr;
+
+ for (adr=vfdbase; adr<=(vfdbase+7168); adr+=4) /*clear frame buffer */
+ (*(volatile ulong*)(adr))=0;
+
+ for(display=0;display<=3;display++)
+ {
+ for(grid_cycle=0;grid_cycle<=55;grid_cycle++)
+ {
+ bit = grid_cycle*256*4+(grid_cycle+200)*4+frame_buf_offs+display;
+ /* wrap arround if offset (see manual S3C2400) */
+ if (bit>=frame_buf_size*8)
+ bit = bit-(frame_buf_size*8);
+ adr = vfdbase+(bit/32)*4+(3-(bit%32)/8);
+ bit_nr = bit%8;
+ bit_nr = (bit_nr>3)?bit_nr-4:bit_nr+4;
+ temp=(*(volatile unsigned char*)(adr));
+ temp|=(1<<bit_nr);
+ (*(volatile unsigned char*)(adr))=temp;
+
+ if(grid_cycle<55)
+ bit = grid_cycle*256*4+(grid_cycle+201)*4+frame_buf_offs+display;
+ else
+ bit = grid_cycle*256*4+200*4+frame_buf_offs+display-4; /* grid nr. 0 */
+ /* wrap arround if offset (see manual S3C2400) */
+ if (bit>=frame_buf_size*8)
+ bit = bit-(frame_buf_size*8);
+ adr = vfdbase+(bit/32)*4+(3-(bit%32)/8);
+ bit_nr = bit%8;
+ bit_nr = (bit_nr>3)?bit_nr-4:bit_nr+4;
+ temp=(*(volatile unsigned char*)(adr));
+ temp|=(1<<bit_nr);
+ (*(volatile unsigned char*)(adr))=temp;
+ }
+ }
+}
+
+/*
+ *create translation table for getting easy the right position in the
+ *physical framebuffer for some x/y-coordinates of the VFDs
+ */
+void create_vfd_table(void)
+{
+ unsigned int vfd_table[112][18][2][4][2];
+ ulong adr;
+ unsigned int x, y, color, display, entry, pixel, bit_nr;
+
+ /*
+ * Create translation table for Noritake-T119C-VFD-specific
+ * organized frame-buffer.
+ * Created is the number of the bit in the framebuffer (the
+ * first transferred pixel of each frame is bit 0).
+ */
+ for(y=0;y<=17;y++) /* Zeile */
+ {
+ for(x=0;x<=111;x++) /* Spalten */
+ {
+ /*Display 0 blaue Pixel Eintrag 1 */
+ vfd_table[x][y][0][0][0]=((x%4)*4+y*16+(x/4)*2048);
+ /*Display 0 rote Pixel Eintrag 1 */
+ vfd_table[x][y][1][0][0]=((x%4)*4+y*16+(x/4)*2048+512);
+ if(x<=1)
+ {
+ /*Display 0 blaue Pixel Eintrag 2 */
+ vfd_table[x][y][0][0][1]=(((x+112)%4)*4+y*16+((x+110)/4)*2048+1024);
+ /*Display 0 rote Pixel Eintrag 2 */
+ vfd_table[x][y][1][0][1]=(((x+112)%4)*4+y*16+((x+110)/4)*2048+512+1024);
+ }
+ else
+ {
+ /*Display 0 blaue Pixel Eintrag 2 */
+ vfd_table[x][y][0][0][1]=((x%4)*4+y*16+((x-2)/4)*2048+1024);
+ /*Display 0 rote Pixel Eintrag 2 */
+ vfd_table[x][y][1][0][1]=((x%4)*4+y*16+((x-2)/4)*2048+512+1024);
+ }
+ /*Display 1 blaue Pixel Eintrag 1 */
+ vfd_table[x][y][0][1][0]=((x%4)*4+y*16+(x/4)*2048+1);
+ /*Display 1 rote Pixel Eintrag 1 */
+ vfd_table[x][y][1][1][0]=((x%4)*4+y*16+(x/4)*2048+512+1);
+ if(x<=1)
+ {
+ /*Display 1 blaue Pixel Eintrag 2 */
+ vfd_table[x][y][0][1][1]=(((x+112)%4)*4+y*16+((x+110)/4)*2048+1+1024);
+ /*Display 1 rote Pixel Eintrag 2 */
+ vfd_table[x][y][1][1][1]=(((x+112)%4)*4+y*16+((x+110)/4)*2048+512+1+1024);
+ }
+ else
+ {
+ /*Display 1 blaue Pixel Eintrag 2 */
+ vfd_table[x][y][0][1][1]=((x%4)*4+y*16+((x-2)/4)*2048+1+1024);
+ /*Display 1 rote Pixel Eintrag 2 */
+ vfd_table[x][y][1][1][1]=((x%4)*4+y*16+((x-2)/4)*2048+512+1+1024);
+ }
+ /*Display 2 blaue Pixel Eintrag 1 */
+ vfd_table[x][y][0][2][0]=((x%4)*4+y*16+(x/4)*2048+2);
+ /*Display 2 rote Pixel Eintrag 1 */
+ vfd_table[x][y][1][2][0]=((x%4)*4+y*16+(x/4)*2048+512+2);
+ if(x<=1)
+ {
+ /*Display 2 blaue Pixel Eintrag 2 */
+ vfd_table[x][y][0][2][1]=(((x+112)%4)*4+y*16+((x+110)/4)*2048+2+1024);
+ /*Display 2 rote Pixel Eintrag 2 */
+ vfd_table[x][y][1][2][1]=(((x+112)%4)*4+y*16+((x+110)/4)*2048+512+2+1024);
+ }
+ else
+ {
+ /*Display 2 blaue Pixel Eintrag 2 */
+ vfd_table[x][y][0][2][1]=((x%4)*4+y*16+((x-2)/4)*2048+2+1024);
+ /*Display 2 rote Pixel Eintrag 2 */
+ vfd_table[x][y][1][2][1]=((x%4)*4+y*16+((x-2)/4)*2048+512+2+1024);
+ }
+ /*Display 3 blaue Pixel Eintrag 1 */
+ vfd_table[x][y][0][3][0]=((x%4)*4+y*16+(x/4)*2048+3);
+ /*Display 3 rote Pixel Eintrag 1 */
+ vfd_table[x][y][1][3][0]=((x%4)*4+y*16+(x/4)*2048+512+3);
+ if(x<=1)
+ {
+ /*Display 3 blaue Pixel Eintrag 2 */
+ vfd_table[x][y][0][3][1]=(((x+112)%4)*4+y*16+((x+110)/4)*2048+3+1024);
+ /*Display 3 rote Pixel Eintrag 2 */
+ vfd_table[x][y][1][3][1]=(((x+112)%4)*4+y*16+((x+110)/4)*2048+512+3+1024);
+ }
+ else
+ {
+ /*Display 3 blaue Pixel Eintrag 2 */
+ vfd_table[x][y][0][3][1]=((x%4)*4+y*16+((x-2)/4)*2048+3+1024);
+ /*Display 3 rote Pixel Eintrag 2 */
+ vfd_table[x][y][1][3][1]=((x%4)*4+y*16+((x-2)/4)*2048+512+3+1024);
+ }
+ }
+ }
+
+ /*
+ * Create translation table for Noritake-T119C-VFD-specific
+ * organized frame-buffer
+ * Create table with entries for physical byte adresses and
+ * bit-number within the byte
+ * from table with bit-numbers within the total framebuffer
+ */
+ for(y=0;y<=17;y++)
+ {
+ for(x=0;x<=111;x++)
+ {
+ for(color=0;color<=1;color++)
+ {
+ for(display=0;display<=3;display++)
+ {
+ for(entry=0;entry<=1;entry++)
+ {
+ pixel = vfd_table[x][y][color][display][entry] + frame_buf_offs;
+ /*
+ * wrap arround if offset
+ * (see manual S3C2400)
+ */
+ if (pixel>=frame_buf_size*8)
+ pixel = pixel-(frame_buf_size*8);
+ adr = vfdbase+(pixel/32)*4+(3-(pixel%32)/8);
+ bit_nr = pixel%8;
+ bit_nr = (bit_nr>3)?bit_nr-4:bit_nr+4;
+ adr_vfd_table[x][y][color][display][entry] = adr;
+ bit_vfd_table[x][y][color][display][entry] = bit_nr;
+ }
+ }
+ }
+ }
+ }
+}
+
+/*
+ * Set/clear pixel of the VFDs
+ */
+void set_vfd_pixel(unsigned char x, unsigned char y, unsigned char color, unsigned char display, unsigned char value)
+{
+ ulong adr;
+ unsigned char bit_nr, temp;
+
+ if (value!=0)
+ {
+ /* Pixel-Eintrag Nr. 1 */
+ adr = adr_vfd_table[x][y][color][display][0];
+ /* Pixel-Eintrag Nr. 1 */
+ bit_nr = bit_vfd_table[x][y][color][display][0];
+ temp=(*(volatile unsigned char*)(adr));
+ temp|=1<<bit_nr;
+ (*(volatile unsigned char*)(adr))=temp;
+
+ /* Pixel-Eintrag Nr. 2 */
+ adr = adr_vfd_table[x][y][color][display][1];
+ /* Pixel-Eintrag Nr. 2 */
+ bit_nr = bit_vfd_table[x][y][color][display][1];
+ temp=(*(volatile unsigned char*)(adr));
+ temp|=1<<bit_nr;
+ (*(volatile unsigned char*)(adr))=temp;
+ }
+ else
+ {
+ /* Pixel-Eintrag Nr. 1 */
+ adr = adr_vfd_table[x][y][color][display][0];
+ /* Pixel-Eintrag Nr. 1 */
+ bit_nr = bit_vfd_table[x][y][color][display][0];
+ temp=(*(volatile unsigned char*)(adr));
+ temp&=~(1<<bit_nr);
+ (*(volatile unsigned char*)(adr))=temp;
+
+ /* Pixel-Eintrag Nr. 2 */
+ adr = adr_vfd_table[x][y][color][display][1];
+ /* Pixel-Eintrag Nr. 2 */
+ bit_nr = bit_vfd_table[x][y][color][display][1];
+ temp=(*(volatile unsigned char*)(adr));
+ temp&=~(1<<bit_nr);
+ (*(volatile unsigned char*)(adr))=temp;
+ }
+}
+
+/*
+ * transfer image from BMP-File
+ */
+void transfer_pic(int display, unsigned char *adr, int height, int width)
+{
+ int x, y;
+ unsigned char temp;
+
+ for (; height > 0; height -= 18)
+ {
+ if (height > 18)
+ y = 18;
+ else
+ y = height;
+ for (; y > 0; y--)
+ {
+ for (x = 0; x < width; x += 2)
+ {
+ temp = *adr++;
+ set_vfd_pixel(x, y-1, 0, display, 0);
+ set_vfd_pixel(x, y-1, 1, display, 0);
+ if ((temp >> 4) == BLAU)
+ set_vfd_pixel(x, y-1, 0, display, 1);
+ else if ((temp >> 4) == ROT)
+ set_vfd_pixel(x, y-1, 1, display, 1);
+ else if ((temp >> 4) == VIOLETT)
+ {
+ set_vfd_pixel(x, y-1, 0, display, 1);
+ set_vfd_pixel(x, y-1, 1, display, 1);
+ }
+ set_vfd_pixel(x+1, y-1, 0, display, 0);
+ set_vfd_pixel(x+1, y-1, 1, display, 0);
+ if ((temp & 0x0F) == BLAU)
+ set_vfd_pixel(x+1, y-1, 0, display, 1);
+ else if ((temp & 0x0F) == ROT)
+ set_vfd_pixel(x+1, y-1, 1, display, 1);
+ else if ((temp & 0x0F) == VIOLETT)
+ {
+ set_vfd_pixel(x+1, y-1, 0, display, 1);
+ set_vfd_pixel(x+1, y-1, 1, display, 1);
+ }
+ }
+ }
+ display++;
+ if (display > 3)
+ display = 0;
+ }
+}
+
+/*
+ * initialize LCD-Controller of the S3C2400 for using VFDs
+ */
+int drv_vfd_init(void)
+{
+ ulong palette;
+
+ DECLARE_GLOBAL_DATA_PTR;
+
+ vfdbase = gd->fb_base;
+ create_vfd_table();
+ init_grid_ctrl();
+
+ /*
+ * Hinweis: Der Framebuffer ist um genau ein Nibble verschoben
+ * Das erste angezeigte Pixel wird aus dem zweiten Nibble geholt
+ * das letzte angezeigte Pixel wird aus dem ersten Nibble geholt
+ * (wrap around)
+ * see manual S3C2400
+ */
+ /* frame buffer startadr */
+ rLCDSADDR1 = vfdbase >> 1;
+ /* frame buffer endadr */
+ rLCDSADDR2 = (vfdbase + frame_buf_size) >> 1;
+ rLCDSADDR3 = ((256/4));
+
+ /* Port-Pins als LCD-Ausgang */
+ rPCCON = (rPCCON & 0xFFFFFF00)| 0x000000AA;
+ /* Port-Pins als LCD-Ausgang */
+ rPDCON = (rPDCON & 0xFFFFFF03)| 0x000000A8;
+#ifdef WITH_VFRAME
+ /* mit VFRAME zum Messen */
+ rPDCON = (rPDCON & 0xFFFFFF00)| 0x000000AA;
+#endif
+
+ rLCDCON2 = 0x000DC000;
+ rLCDCON3 = 0x0051000A;
+ rLCDCON4 = 0x00000001;
+ rLCDCON5 = 0x00000440;
+ rLCDCON1 = 0x00000B75;
+
+ debug ("LCDSADDR1: %lX\n", rLCDSADDR1);
+ debug ("LCDSADDR2: %lX\n", rLCDSADDR2);
+ debug ("LCDSADDR3: %lX\n", rLCDSADDR3);
+
+ for(palette=0;palette<=15;palette++)
+ (*(volatile unsigned int*)(PALETTE+(palette*4)))=palette;
+ for(palette=16;palette<=255;palette++)
+ (*(volatile unsigned int*)(PALETTE+(palette*4)))=0x00;
+
+ return 0;
+}
+
+/************************************************************************/
+/* ** ROM capable initialization part - needed to reserve FB memory */
+/************************************************************************/
+
+/*
+ * This is called early in the system initialization to grab memory
+ * for the VFD controller.
+ *
+ * Note that this is running from ROM, so no write access to global data.
+ */
+ulong vfd_setmem (ulong addr)
+{
+ ulong size;
+
+ /* MAGIC */
+ frame_buf_size = (256*4*56)/8;
+
+ /* Round up to nearest full page */
+ size = (frame_buf_size + (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1);
+
+ debug ("Reserving %ldk for VFD Framebuffer at: %08lx\n", size>>10, addr);
+
+ return (size);
+}
+
+#endif /* CONFIG_VFD */
--- /dev/null
+/*
+ * (C) Copyright 2001
+ * Rob Taylor, Flying Pig Systems. robt@flyingpig.com.
+ *
+ * (C) Copyright 2002
+ * Gregory E. Allen, gallen@arlut.utexas.edu
+ * Matthew E. Karger, karger@arlut.utexas.edu
+ * Applied Research Laboratories, The University of Texas at Austin
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <mpc824x.h>
+#include <asm/processor.h>
+#include <asm/io.h>
+#include <pci.h>
+
+#define SAVE_SZ 32
+
+
+int checkboard(void)
+{
+ ulong busfreq = get_bus_freq(0);
+ char buf[32];
+
+ printf("Board: UTX8245 Local Bus at %s MHz\n", strmhz(buf, busfreq));
+ return 0;
+}
+
+
+long int initdram(int board_type)
+{
+#if 1
+ int i, cnt;
+ volatile uchar *base = CFG_SDRAM_BASE;
+ volatile ulong *addr;
+ ulong save[SAVE_SZ];
+ ulong val, ret = 0;
+
+ for (i=0; i<SAVE_SZ; i++) {save[i] = 0;} /* clear table */
+
+ for (i=0, cnt=(CFG_MAX_RAM_SIZE / sizeof(long)) >> 1; cnt > 0; cnt >>= 1)
+ {
+ addr = (volatile ulong *)base + cnt;
+ save[i++] = *addr;
+ *addr = ~cnt;
+ }
+
+ addr = (volatile ulong *)base;
+ save[i] = *addr;
+ *addr = 0;
+
+ if (*addr != 0)
+ {
+ *addr = save[i];
+ goto Done;
+ }
+
+ for (cnt = 1; cnt < CFG_MAX_RAM_SIZE / sizeof(long); cnt <<= 1)
+ {
+ addr = (volatile ulong *)base + cnt;
+ val = *addr;
+ *addr = save[--i];
+ if (val != ~cnt)
+ {
+ ulong new_bank0_end = cnt * sizeof(long) - 1;
+ ulong mear1 = mpc824x_mpc107_getreg(MEAR1);
+ ulong emear1 = mpc824x_mpc107_getreg(EMEAR1);
+ mear1 = (mear1 & 0xFFFFFF00) |
+ ((new_bank0_end & MICR_ADDR_MASK) >> MICR_ADDR_SHIFT);
+ emear1 = (emear1 & 0xFFFFFF00) |
+ ((new_bank0_end & MICR_ADDR_MASK) >> MICR_EADDR_SHIFT);
+ mpc824x_mpc107_setreg(MEAR1, mear1);
+ mpc824x_mpc107_setreg(EMEAR1, emear1);
+
+ ret = cnt * sizeof(long);
+ goto Done;
+ }
+ }
+
+ ret = CFG_MAX_RAM_SIZE;
+Done:
+ return ret;
+#else
+ return (CFG_MAX_RAM_SIZE);
+#endif
+
+}
+
+
+/*
+ * Initialize PCI Devices, report devices found.
+ */
+
+static struct pci_config_table pci_utx8245_config_table[] = {
+#ifndef CONFIG_PCI_PNP
+ { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
+ pci_cfgfunc_config_device, { PCI_ENET0_IOADDR,
+ PCI_ENET0_MEMADDR,
+ PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER }},
+ { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
+ pci_cfgfunc_config_device, { PCI_FIREWIRE_IOADDR,
+ PCI_FIREWIRE_MEMADDR,
+ PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER }},
+#endif /*CONFIG_PCI_PNP*/
+ { }
+};
+
+
+static void pci_utx8245_fixup_irq(struct pci_controller *hose, pci_dev_t dev)
+{
+ if (PCI_DEV(dev) == 11)
+ /* assign serial interrupt line 9 (int25) to FireWire */
+ pci_hose_write_config_byte(hose, dev, PCI_INTERRUPT_LINE, 25);
+
+ else if (PCI_DEV(dev) == 12)
+ /* assign serial interrupt line 8 (int24) to Ethernet */
+ pci_hose_write_config_byte(hose, dev, PCI_INTERRUPT_LINE, 24);
+}
+
+static struct pci_controller utx8245_hose = {
+#ifndef CONFIG_PCI_PNP
+ config_table: pci_utx8245_config_table,
+ fixup_irq: pci_utx8245_fixup_irq,
+ write_byte: pci_hose_write_config_byte
+#endif /*CONFIG_PCI_PNP*/
+};
+
+void pci_init (void)
+{
+ pci_mpc824x_init(&utx8245_hose);
+
+ icache_enable();
+}
+
--- /dev/null
+/*
+ * (C) Copyright 2001
+ * Erik Theisen, Wave 7 Optics, etheisen@mindspring.com.
+ * Based on code by:
+ * 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 <ppc4xx.h>
+#include <asm/processor.h>
+
+#include <watchdog.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_word8(flash_info_t *info, ulong dest, ulong data);
+static int write_word32 (flash_info_t *info, ulong dest, ulong data);
+static void flash_get_offsets (ulong base, flash_info_t *info);
+
+/*-----------------------------------------------------------------------
+ */
+
+unsigned long flash_init (void)
+{
+ int i;
+ unsigned long size_b0, base_b0;
+ unsigned long size_b1, base_b1;
+
+ /* Init: no FLASHes known */
+ for (i = 0; i < CFG_MAX_FLASH_BANKS; ++i) {
+ flash_info[i].flash_id = FLASH_UNKNOWN;
+ }
+
+ /* Get Size of Boot and Main Flashes */
+ 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);
+ return 0;
+ }
+ size_b1 = flash_get_size((vu_long *)FLASH_BASE1_PRELIM, &flash_info[1]);
+ if (flash_info[1].flash_id == FLASH_UNKNOWN) {
+ printf ("## Unknown FLASH on Bank 1 - Size = 0x%08lx = %ld MB\n",
+ size_b1, size_b1<<20);
+ return 0;
+ }
+
+ /* Calculate base addresses */
+ base_b0 = -size_b0;
+ base_b1 = -size_b1;
+
+ /* Setup offsets for Boot Flash */
+ flash_get_offsets (base_b0, &flash_info[0]);
+
+ /* Protect board level data */
+ (void)flash_protect(FLAG_PROTECT_SET,
+ base_b0,
+ flash_info[0].start[1] - 1,
+ &flash_info[0]);
+
+
+ /* Monitor protection ON by default */
+ (void)flash_protect(FLAG_PROTECT_SET,
+ base_b0 + size_b0 - CFG_MONITOR_LEN,
+ base_b0 + size_b0 - 1,
+ &flash_info[0]);
+
+ /* Protect the FPGA image */
+ (void)flash_protect(FLAG_PROTECT_SET,
+ FLASH_BASE1_PRELIM,
+ FLASH_BASE1_PRELIM + CFG_FPGA_IMAGE_LEN - 1,
+ &flash_info[1]);
+
+ /* Protect the default boot image */
+ (void)flash_protect(FLAG_PROTECT_SET,
+ FLASH_BASE1_PRELIM + CFG_FPGA_IMAGE_LEN,
+ FLASH_BASE1_PRELIM + CFG_FPGA_IMAGE_LEN + 0x600000 - 1,
+ &flash_info[1]);
+
+ /* Setup offsets for Main Flash */
+ flash_get_offsets (FLASH_BASE1_PRELIM, &flash_info[1]);
+
+ return (size_b0 + size_b1);
+} /* end flash_init() */
+
+/*-----------------------------------------------------------------------
+ */
+static void flash_get_offsets (ulong base, flash_info_t *info)
+{
+ int i;
+
+ /* set up sector start address table - FOR BOOT ROM ONLY!!! */
+ if ((info->flash_id & FLASH_TYPEMASK) == FLASH_AM040) {
+ for (i = 0; i < info->sector_count; i++)
+ info->start[i] = base + (i * 0x00010000);
+ }
+} /* end flash_get_offsets() */
+
+/*-----------------------------------------------------------------------
+ */
+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 ("1 x AMD "); break;
+ case FLASH_MAN_STM: printf ("1 x STM "); break;
+ case FLASH_MAN_INTEL: printf ("2 x Intel "); break;
+ default: printf ("Unknown Vendor ");
+ }
+
+ switch (info->flash_id & FLASH_TYPEMASK) {
+ case FLASH_AM040:
+ if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_AMD)
+ printf ("AM29LV040 (4096 Kbit, uniform sector size)\n");
+ else if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_STM)
+ printf ("M29W040B (4096 Kbit, uniform block size)\n");
+ else
+ printf ("UNKNOWN 29x040x (4096 Kbit, uniform sector size)\n");
+ break;
+ case FLASH_28F320J3A:
+ printf ("28F320J3A (32 Mbit = 128K x 32)\n");
+ break;
+ case FLASH_28F640J3A:
+ printf ("28F640J3A (64 Mbit = 128K x 64)\n");
+ break;
+ case FLASH_28F128J3A:
+ printf ("28F128J3A (128 Mbit = 128K x 128)\n");
+ break;
+ default:
+ printf ("Unknown Chip Type\n");
+ }
+
+ if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_STM) {
+ printf (" Size: %ld KB in %d Blocks\n",
+ info->size >> 10, info->sector_count);
+ } else {
+ 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 ");
+ printf (" %08lX%s%s",
+ info->start[i],
+ erased ? " E" : " ",
+ info->protect[i] ? "RO " : " "
+ );
+ }
+ printf ("\n");
+} /* end flash_print_info() */
+
+/*
+ * The following code cannot be run from FLASH!
+ */
+static ulong flash_get_size (vu_long *addr, flash_info_t *info)
+{
+ short i;
+ ulong base = (ulong)addr;
+
+ /* Setup default type */
+ info->flash_id = FLASH_UNKNOWN;
+ info->sector_count =0;
+ info->size = 0;
+
+ /* Test for Boot Flash */
+ if (base == FLASH_BASE0_PRELIM) {
+ unsigned char value;
+ volatile unsigned char * addr2 = (unsigned char *)addr;
+
+ /* Write auto select command: read Manufacturer ID */
+ *(addr2 + 0x555) = 0xaa;
+ *(addr2 + 0x2aa) = 0x55;
+ *(addr2 + 0x555) = 0x90;
+
+ /* Manufacture ID */
+ value = *addr2;
+ switch (value) {
+ case (unsigned char)AMD_MANUFACT:
+ info->flash_id = FLASH_MAN_AMD;
+ break;
+ case (unsigned char)STM_MANUFACT:
+ info->flash_id = FLASH_MAN_STM;
+ break;
+ default:
+ *addr2 = 0xf0; /* no or unknown flash */
+ return 0;
+ }
+
+ /* Device ID */
+ value = *(addr2 + 1);
+ switch (value) {
+ case (unsigned char)AMD_ID_LV040B:
+ case (unsigned char)STM_ID_29W040B:
+ info->flash_id += FLASH_AM040;
+ info->sector_count = 8;
+ info->size = 0x00080000;
+ break; /* => 512Kb */
+ default:
+ *addr2 = 0xf0; /* => no or unknown flash */
+ return 0;
+ }
+ }
+ else { /* MAIN Flash */
+ unsigned long value;
+ volatile unsigned long * addr2 = (unsigned long *)addr;
+
+ /* Write auto select command: read Manufacturer ID */
+ *addr2 = 0x90909090;
+
+ /* Manufacture ID */
+ value = *addr2;
+ switch (value) {
+ case (unsigned long)INTEL_MANUFACT:
+ info->flash_id = FLASH_MAN_INTEL;
+ break;
+ default:
+ *addr2 = 0xff; /* no or unknown flash */
+ return 0;
+ }
+
+ /* Device ID - This shit is interleaved... */
+ value = *(addr2 + 1);
+ switch (value) {
+ case (unsigned long)INTEL_ID_28F320J3A:
+ info->flash_id += FLASH_28F320J3A;
+ info->sector_count = 32;
+ info->size = 0x00400000 * 2;
+ break; /* => 2 X 4 MB */
+ case (unsigned long)INTEL_ID_28F640J3A:
+ info->flash_id += FLASH_28F640J3A;
+ info->sector_count = 64;
+ info->size = 0x00800000 * 2;
+ break; /* => 2 X 8 MB */
+ case (unsigned long)INTEL_ID_28F128J3A:
+ info->flash_id += FLASH_28F128J3A;
+ info->sector_count = 128;
+ info->size = 0x01000000 * 2;
+ break; /* => 2 X 16 MB */
+ default:
+ *addr2 = 0xff; /* => no or unknown flash */
+ }
+ }
+
+ /* Make sure we don't exceed CFG_MAX_FLASH_SECT */
+ if (info->sector_count > CFG_MAX_FLASH_SECT) {
+ printf ("** ERROR: sector count %d > max (%d) **\n",
+ info->sector_count, CFG_MAX_FLASH_SECT);
+ info->sector_count = CFG_MAX_FLASH_SECT;
+ }
+
+ /* set up sector start address table */
+ switch (info->flash_id & FLASH_TYPEMASK) {
+ case FLASH_AM040:
+ for (i = 0; i < info->sector_count; i++)
+ info->start[i] = base + (i * 0x00010000);
+ break;
+ case FLASH_28F320J3A:
+ case FLASH_28F640J3A:
+ case FLASH_28F128J3A:
+ for (i = 0; i < info->sector_count; i++)
+ info->start[i] = base + (i * 0x00020000 * 2); /* 2 Banks */
+ break;
+ }
+
+ /* Test for Boot Flash */
+ if (base == FLASH_BASE0_PRELIM) {
+ volatile unsigned char *addr2;
+ /* check for protected sectors */
+ for (i = 0; i < info->sector_count; i++) {
+ /* read sector protection at sector address, (AX .. A0) = 0x02 */
+ /* D0 = 1 if protected */
+ addr2 = (volatile unsigned char *)(info->start[i]);
+ info->protect[i] = *(addr2 + 2) & 1;
+ }
+
+ /* Restore read mode */
+ *(unsigned char *)base = 0xF0; /* Reset NORMAL Flash */
+ }
+ else { /* Main Flash */
+ volatile unsigned long *addr2;
+ /* check for protected sectors */
+ for (i = 0; i < info->sector_count; i++) {
+ /* read sector protection at sector address, (AX .. A0) = 0x02 */
+ /* D0 = 1 if protected */
+ addr2 = (volatile unsigned long *)(info->start[i]);
+ info->protect[i] = *(addr2 + 2) & 0x1;
+ }
+
+ /* Restore read mode */
+ *(unsigned long *)base = 0xFFFFFFFF; /* Reset Flash */
+ }
+
+ return (info->size);
+} /* end flash_get_size() */
+
+/*-----------------------------------------------------------------------
+ */
+
+static int wait_for_DQ7(ulong addr, uchar cmp_val, ulong tout)
+{
+ int i;
+
+ volatile uchar *vaddr = (uchar *)addr;
+
+ /* Loop X times */
+ for (i = 1; i <= (100 * tout); i++) { /* Wait up to tout ms */
+ udelay(10);
+ /* Pause 10 us */
+
+ /* Check for completion */
+ if ((vaddr[0] & 0x80) == (cmp_val & 0x80)) {
+ return 0;
+ }
+
+ /* KEEP THE LUSER HAPPY - Print a dot every 1.1 seconds */
+ if (!(i % 110000))
+ putc('.');
+
+ /* Kick the dog if needed */
+ WATCHDOG_RESET();
+ }
+
+ return 1;
+} /* wait_for_DQ7() */
+
+/*-----------------------------------------------------------------------
+ */
+
+static int flash_erase8(flash_info_t *info, int s_first, int s_last)
+{
+ int tcode, rcode = 0;
+ volatile uchar *addr = (uchar *)(info->start[0]);
+ volatile uchar *sector_addr;
+ int flag, prot, sect;
+
+ /* Validate arguments */
+ 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;
+ }
+
+ /* Check for KNOWN flash type */
+ if (info->flash_id == FLASH_UNKNOWN) {
+ printf ("Can't erase unknown flash type - aborted\n");
+ return 1;
+ }
+
+ /* Check for protected sectors */
+ prot = 0;
+ for (sect = s_first; sect <= s_last; ++sect) {
+ if (info->protect[sect])
+ prot++;
+ }
+ if (prot)
+ printf ("- Warning: %d protected sectors will not be erased!\n", prot);
+ else
+ printf ("\n");
+
+ /* Start erase on unprotected sectors */
+ for (sect = s_first; sect <= s_last; sect++) {
+ if (info->protect[sect] == 0) { /* not protected */
+ sector_addr = (uchar *)(info->start[sect]);
+
+ if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_STM)
+ printf("Erasing block %p\n", sector_addr);
+ else
+ printf("Erasing sector %p\n", sector_addr);
+
+ /* Disable interrupts which might cause Flash to timeout */
+ flag = disable_interrupts();
+
+ *(addr + 0x555) = (uchar)0xAA;
+ *(addr + 0x2aa) = (uchar)0x55;
+ *(addr + 0x555) = (uchar)0x80;
+ *(addr + 0x555) = (uchar)0xAA;
+ *(addr + 0x2aa) = (uchar)0x55;
+ *sector_addr = (uchar)0x30; /* sector erase */
+
+ /*
+ * 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)!!
+ * Takes up to 6 seconds.
+ */
+ tcode = wait_for_DQ7((ulong)sector_addr, 0x80, 6000);
+
+ /* re-enable interrupts if necessary */
+ if (flag)
+ enable_interrupts();
+
+ /* Make sure we didn't timeout */
+ if (tcode) {
+ printf ("Timeout\n");
+ rcode = 1;
+ }
+ }
+ }
+
+ /* wait at least 80us - let's wait 1 ms */
+ udelay (1000);
+
+ /* reset to read mode */
+ addr = (uchar *)info->start[0];
+ *addr = (uchar)0xF0; /* reset bank */
+
+ printf (" done\n");
+ return rcode;
+} /* end flash_erase8() */
+
+static int flash_erase32(flash_info_t *info, int s_first, int s_last)
+{
+ int flag, sect;
+ ulong start, now, last;
+ int prot = 0;
+
+ /* Validate arguments */
+ 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;
+ }
+
+ /* Check for KNOWN flash type */
+ if ((info->flash_id & FLASH_VENDMASK) != FLASH_MAN_INTEL) {
+ printf ("Can erase only Intel flash types - aborted\n");
+ return 1;
+ }
+
+ /* Check for protected sectors */
+ for (sect = s_first; sect <= s_last; ++sect) {
+ if (info->protect[sect])
+ prot++;
+ }
+ if (prot)
+ printf ("- Warning: %d protected sectors will not be erased!\n", prot);
+ else
+ printf ("\n");
+
+ start = get_timer (0);
+ last = start;
+ /* Start erase on unprotected sectors */
+ for (sect = s_first; sect <= s_last; sect++) {
+ WATCHDOG_RESET();
+ if (info->protect[sect] == 0) { /* not protected */
+ vu_long *addr = (vu_long *)(info->start[sect]);
+ unsigned long status;
+
+ /* Disable interrupts which might cause a timeout here */
+ flag = disable_interrupts();
+
+ *addr = 0x00500050; /* clear status register */
+ *addr = 0x00200020; /* erase setup */
+ *addr = 0x00D000D0; /* erase confirm */
+
+ /* re-enable interrupts if necessary */
+ if (flag)
+ enable_interrupts();
+
+ /* Wait at least 80us - let's wait 1 ms */
+ udelay (1000);
+
+ while (((status = *addr) & 0x00800080) != 0x00800080) {
+ if ((now = get_timer(start)) > CFG_FLASH_ERASE_TOUT) {
+ printf ("Timeout\n");
+ *addr = 0x00B000B0; /* suspend erase */
+ *addr = 0x00FF00FF; /* reset to read mode */
+ return 1;
+ }
+
+ /* show that we're waiting */
+ if ((now - last) > 990) { /* every second */
+ putc ('.');
+ last = now;
+ }
+ }
+ *addr = 0x00FF00FF; /* reset to read mode */
+ }
+ }
+ printf (" done\n");
+ return 0;
+} /* end flash_erase32() */
+
+int flash_erase(flash_info_t *info, int s_first, int s_last)
+{
+ if ((info->flash_id & FLASH_TYPEMASK) == FLASH_AM040)
+ return flash_erase8(info, s_first, s_last);
+ else
+ return flash_erase32(info, s_first, s_last);
+} /* end flash_erase() */
+
+/*-----------------------------------------------------------------------
+ * Copy memory to flash, returns:
+ * 0 - OK
+ * 1 - write timeout
+ * 2 - Flash not erased
+ */
+static int write_buff8(flash_info_t *info, uchar *src, ulong addr, ulong cnt)
+{
+ ulong cp, wp, data;
+ ulong start;
+ int i, l, rc;
+
+ start = get_timer (0);
+
+ 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_word8(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_word8(info, wp, data)) != 0) {
+ return (rc);
+ }
+ wp += 4;
+ cnt -= 4;
+ if (get_timer(start) > 1000) { /* every second */
+ WATCHDOG_RESET();
+ putc ('.');
+ start = get_timer(0);
+ }
+ }
+
+ 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_word8(info, wp, data));
+} /* end write_buff8() */
+
+#define FLASH_WIDTH 4 /* flash bus width in bytes */
+static int write_buff32 (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
+{
+ ulong cp, wp, data;
+ int i, l, rc;
+ ulong start;
+
+ start = get_timer (0);
+
+ if (info->flash_id == FLASH_UNKNOWN) {
+ return 4;
+ }
+
+ wp = (addr & ~(FLASH_WIDTH-1)); /* get lower FLASH_WIDTH 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<FLASH_WIDTH && cnt>0; ++i) {
+ data = (data << 8) | *src++;
+ --cnt;
+ ++cp;
+ }
+ for (; cnt==0 && i<FLASH_WIDTH; ++i, ++cp) {
+ data = (data << 8) | (*(uchar *)cp);
+ }
+
+ if ((rc = write_word32(info, wp, data)) != 0) {
+ return (rc);
+ }
+ wp += FLASH_WIDTH;
+ }
+
+ /*
+ * handle FLASH_WIDTH aligned part
+ */
+ while (cnt >= FLASH_WIDTH) {
+ data = 0;
+ for (i=0; i<FLASH_WIDTH; ++i) {
+ data = (data << 8) | *src++;
+ }
+ if ((rc = write_word32(info, wp, data)) != 0) {
+ return (rc);
+ }
+ wp += FLASH_WIDTH;
+ cnt -= FLASH_WIDTH;
+ if (get_timer(start) > 990) { /* every second */
+ putc ('.');
+ start = get_timer(0);
+ }
+ }
+
+ if (cnt == 0) {
+ return (0);
+ }
+
+ /*
+ * handle unaligned tail bytes
+ */
+ data = 0;
+ for (i=0, cp=wp; i<FLASH_WIDTH && cnt>0; ++i, ++cp) {
+ data = (data << 8) | *src++;
+ --cnt;
+ }
+ for (; i<FLASH_WIDTH; ++i, ++cp) {
+ data = (data << 8) | (*(uchar *)cp);
+ }
+
+ return (write_word32(info, wp, data));
+} /* write_buff32() */
+
+int write_buff(flash_info_t *info, uchar *src, ulong addr, ulong cnt)
+{
+ int retval;
+
+ if ((info->flash_id & FLASH_TYPEMASK) == FLASH_AM040)
+ retval = write_buff8(info, src, addr, cnt);
+ else
+ retval = write_buff32(info, src, addr, cnt);
+
+ return retval;
+} /* end write_buff() */
+
+/*-----------------------------------------------------------------------
+ * Write a word to Flash, returns:
+ * 0 - OK
+ * 1 - write timeout
+ * 2 - Flash not erased
+ */
+
+static int write_word8(flash_info_t *info, ulong dest, ulong data)
+{
+ volatile uchar *addr2 = (uchar *)(info->start[0]);
+ volatile uchar *dest2 = (uchar *)dest;
+ volatile uchar *data2 = (uchar *)&data;
+ int flag;
+ int i, tcode, rcode = 0;
+
+ /* Check if Flash is (sufficently) erased */
+ if ((*((volatile uchar *)dest) &
+ (uchar)data) != (uchar)data) {
+ return (2);
+ }
+
+ for (i=0; i < (4 / sizeof(uchar)); i++) {
+ /* Disable interrupts which might cause a timeout here */
+ flag = disable_interrupts();
+
+ *(addr2 + 0x555) = (uchar)0xAA;
+ *(addr2 + 0x2aa) = (uchar)0x55;
+ *(addr2 + 0x555) = (uchar)0xA0;
+
+ dest2[i] = data2[i];
+
+ /* Wait for write to complete, up to 1ms */
+ tcode = wait_for_DQ7((ulong)&dest2[i], data2[i], 1);
+
+ /* re-enable interrupts if necessary */
+ if (flag)
+ enable_interrupts();
+
+ /* Make sure we didn't timeout */
+ if (tcode) {
+ rcode = 1;
+ }
+ }
+
+ return rcode;
+} /* end write_word8() */
+
+static int write_word32(flash_info_t *info, ulong dest, ulong data)
+{
+ vu_long *addr = (vu_long *)dest;
+ ulong status;
+ ulong start;
+ 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();
+
+ *addr = 0x00400040; /* write setup */
+ *addr = data;
+
+ /* re-enable interrupts if necessary */
+ if (flag)
+ enable_interrupts();
+
+ start = get_timer (0);
+
+ while (((status = *addr) & 0x00800080) != 0x00800080) {
+ WATCHDOG_RESET();
+ if (get_timer(start) > CFG_FLASH_WRITE_TOUT) {
+ *addr = 0x00FF00FF; /* restore read mode */
+ return (1);
+ }
+ }
+
+ *addr = 0x00FF00FF; /* restore read mode */
+
+ return (0);
+} /* end write_word32() */
+
+
+static int _flash_protect(flash_info_t *info, long sector)
+{
+ int i;
+ int flag;
+ ulong status;
+ int rcode = 0;
+ volatile long *addr = (unsigned long *)sector;
+
+ switch(info->flash_id & FLASH_TYPEMASK) {
+ case FLASH_28F320J3A:
+ case FLASH_28F640J3A:
+ case FLASH_28F128J3A:
+ /* Disable interrupts which might cause Flash to timeout */
+ flag = disable_interrupts();
+
+ /* Issue command */
+ *addr = 0x00500050L; /* Clear the status register */
+ *addr = 0x00600060L; /* Set lock bit setup */
+ *addr = 0x00010001L; /* Set lock bit confirm */
+
+ /* Wait for command completion */
+ for (i = 0; i < 10; i++) { /* 75us timeout, wait 100us */
+ udelay(10);
+ if ((*addr & 0x00800080L) == 0x00800080L)
+ break;
+ }
+
+ /* Not successful? */
+ status = *addr;
+ if (status != 0x00800080L) {
+ printf("Protect %x sector failed: %x\n",
+ (uint)sector, (uint)status);
+ rcode = 1;
+ }
+
+ /* Restore read mode */
+ *addr = 0x00ff00ffL;
+
+ /* re-enable interrupts if necessary */
+ if (flag)
+ enable_interrupts();
+
+ break;
+ case FLASH_AM040: /* No soft sector protection */
+ break;
+ }
+
+ /* Turn protection on for this sector */
+ for (i = 0; i < info->sector_count; i++) {
+ if (info->start[i] == sector) {
+ info->protect[i] = 1;
+ break;
+ }
+ }
+
+ return rcode;
+} /* end _flash_protect() */
+
+static int _flash_unprotect(flash_info_t *info, long sector)
+{
+ int i;
+ int flag;
+ ulong status;
+ int rcode = 0;
+ volatile long *addr = (unsigned long *)sector;
+
+ switch(info->flash_id & FLASH_TYPEMASK) {
+ case FLASH_28F320J3A:
+ case FLASH_28F640J3A:
+ case FLASH_28F128J3A:
+ /* Disable interrupts which might cause Flash to timeout */
+ flag = disable_interrupts();
+
+ *addr = 0x00500050L; /* Clear the status register */
+ *addr = 0x00600060L; /* Clear lock bit setup */
+ *addr = 0x00D000D0L; /* Clear lock bit confirm */
+
+ /* Wait for command completion */
+ for (i = 0; i < 80 ; i++) { /* 700ms timeout, wait 800 */
+ udelay(10000); /* Delay 10ms */
+ if ((*addr & 0x00800080L) == 0x00800080L)
+ break;
+ }
+
+ /* Not successful? */
+ status = *addr;
+ if (status != 0x00800080L) {
+ printf("Un-protect %x sector failed: %x\n",
+ (uint)sector, (uint)status);
+ *addr = 0x00ff00ffL;
+ rcode = 1;
+ }
+
+ /* restore read mode */
+ *addr = 0x00ff00ffL;
+
+ /* re-enable interrupts if necessary */
+ if (flag)
+ enable_interrupts();
+
+ break;
+ case FLASH_AM040: /* No soft sector protection */
+ break;
+ }
+
+ /*
+ * Fix Intel's little red wagon. Reprotect
+ * sectors that were protected before we undid
+ * protection on a specific sector.
+ */
+ for (i = 0; i < info->sector_count; i++) {
+ if (info->start[i] != sector) {
+ if (info->protect[i]) {
+ if (_flash_protect(info, info->start[i]))
+ rcode = 1;
+ }
+ }
+ else /* Turn protection off for this sector */
+ info->protect[i] = 0;
+ }
+
+ return rcode;
+} /* end _flash_unprotect() */
+
+
+int flash_real_protect(flash_info_t *info, long sector, int prot)
+{
+ int rcode;
+
+ if (prot)
+ rcode = _flash_protect(info, info->start[sector]);
+ else
+ rcode = _flash_unprotect(info, info->start[sector]);
+
+ return rcode;
+} /* end flash_real_protect() */
+
+/*-----------------------------------------------------------------------
+ */
+
--- /dev/null
+/*
+ * (C) Copyright 2001
+ * Erik Theisen, Wave 7 Optics, etheisen@mindspring.com
+ * and
+ * Bill Hunter, Wave 7 Optics, william.hunter@mediaone.net
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+#include <config.h>
+#include <common.h>
+#include "w7o.h"
+#include <asm/processor.h>
+#include "errors.h"
+
+static void
+fpga_img_write(unsigned long *src, unsigned long len, unsigned short *daddr)
+{
+ unsigned long i;
+ volatile unsigned long val;
+ volatile unsigned short *dest = daddr; /* volatile-bypass optimizer */
+
+ for (i = 0; i < len; i++, src++) {
+ val = *src;
+ *dest = (unsigned short)((val & 0xff000000L) >> 16);
+ *dest = (unsigned short)((val & 0x00ff0000L) >> 8);
+ *dest = (unsigned short)(val & 0x0000ff00L);
+ *dest = (unsigned short)((val & 0x000000ffL) << 8);
+ }
+
+ /* Terminate programming with 4 C clocks */
+ dest = daddr;
+ val = *(unsigned short *)dest;
+ val = *(unsigned short *)dest;
+ val = *(unsigned short *)dest;
+ val = *(unsigned short *)dest;
+
+}
+
+
+int
+fpgaDownload(unsigned char *saddr,
+ unsigned long size,
+ unsigned short *daddr)
+{
+ int i; /* index, intr disable flag */
+ int start; /* timer */
+ unsigned long greg, grego; /* GPIO & output register */
+ unsigned long length; /* image size in words */
+ unsigned long *source; /* image source addr */
+ unsigned short *dest; /* destination FPGA addr */
+ volatile unsigned short *ndest; /* temp dest FPGA addr */
+ volatile unsigned short val; /* temp val */
+ unsigned long cnfg = GPIO_XCV_CNFG; /* FPGA CNFG */
+ unsigned long eirq = GPIO_XCV_IRQ;
+ int retval = -1; /* Function return value */
+
+ /* Setup some basic values */
+ length = (size / 4) + 1; /* size in words, rounding UP
+ is OK */
+ source = (unsigned long *)saddr;
+ dest = (unsigned short *)daddr;
+
+ /* Get DCR output register */
+ grego = in32(IBM405GP_GPIO0_OR);
+
+ /* Reset FPGA */
+ grego &= ~GPIO_XCV_PROG; /* PROG line low */
+ out32(IBM405GP_GPIO0_OR, grego);
+
+ /* Setup timeout timer */
+ start = get_timer(0);
+
+ /* Wait for FPGA init line */
+ while(in32(IBM405GP_GPIO0_IR) & GPIO_XCV_INIT) { /* Wait INIT line low */
+ /* Check for timeout - 100us max, so use 3ms */
+ if (get_timer(start) > 3) {
+ printf(" failed to start init.\n");
+ log_warn(ERR_XINIT0); /* Don't halt */
+
+ /* Reset line stays low */
+ goto done; /* I like gotos... */
+ }
+ }
+
+ /* Unreset FPGA */
+ grego |= GPIO_XCV_PROG; /* PROG line high */
+ out32(IBM405GP_GPIO0_OR, grego);
+
+ /* Wait for FPGA end of init period . */
+ while(!(in32(IBM405GP_GPIO0_IR) & GPIO_XCV_INIT)) { /* Wait for INIT hi */
+
+ /* Check for timeout */
+ if (get_timer(start) > 3) {
+ printf(" failed to exit init.\n");
+ log_warn(ERR_XINIT1);
+
+ /* Reset FPGA */
+ grego &= ~GPIO_XCV_PROG; /* PROG line low */
+ out32(IBM405GP_GPIO0_OR, grego);
+
+ goto done;
+ }
+ }
+
+ /* Now program FPGA ... */
+ ndest = dest;
+ for (i = 0; i < CONFIG_NUM_FPGAS; i++) {
+ /* Toggle IRQ/GPIO */
+ greg = mfdcr(CPC0_CR0); /* get chip ctrl register */
+ greg |= eirq; /* toggle irq/gpio */
+ mtdcr(CPC0_CR0, greg); /* ... just do it */
+
+ /* turn on open drain for CNFG */
+ greg = in32(IBM405GP_GPIO0_ODR); /* get open drain register */
+ greg |= cnfg; /* CNFG open drain */
+ out32(IBM405GP_GPIO0_ODR, greg); /* .. just do it */
+
+ /* Turn output enable on for CNFG */
+ greg = in32(IBM405GP_GPIO0_TCR); /* get tristate register */
+ greg |= cnfg; /* CNFG tristate inactive */
+ out32(IBM405GP_GPIO0_TCR, greg); /* ... just do it */
+
+ /* Setup FPGA for programming */
+ grego &= ~cnfg; /* CONFIG line low */
+ out32(IBM405GP_GPIO0_OR, grego);
+
+ /*
+ * Program the FPGA
+ */
+ printf("\n destination: 0x%lx ", (unsigned long)ndest);
+
+ fpga_img_write(source, length, (unsigned short *)ndest);
+
+ /* Done programming */
+ grego |= cnfg; /* CONFIG line high */
+ out32(IBM405GP_GPIO0_OR, grego);
+
+ /* Turn output enable OFF for CNFG */
+ greg = in32(IBM405GP_GPIO0_TCR); /* get tristate register */
+ greg &= ~cnfg; /* CNFG tristate inactive */
+ out32(IBM405GP_GPIO0_TCR, greg); /* ... just do it */
+
+ /* Toggle IRQ/GPIO */
+ greg = mfdcr(CPC0_CR0); /* get chip ctrl register */
+ greg &= ~eirq; /* toggle irq/gpio */
+ mtdcr(CPC0_CR0, greg); /* ... just do it */
+
+ ndest = (unsigned short *)((char *)ndest + 0x00100000L); /* XXX - Next FPGA addr */
+ cnfg >>= 1; /* XXX - Next */
+ eirq >>= 1;
+ }
+
+ /* Terminate programming with 4 C clocks */
+ ndest = dest;
+ for (i = 0; i < CONFIG_NUM_FPGAS; i++) {
+ val = *ndest;
+ val = *ndest;
+ val = *ndest;
+ val = *ndest;
+ ndest = (unsigned short *)((char *)ndest + 0x00100000L);
+ }
+
+ /* Setup timer */
+ start = get_timer(0);
+
+ /* Wait for FPGA end of programming period . */
+ while(!(in32(IBM405GP_GPIO0_IR) & GPIO_XCV_DONE)) { /* Test DONE low */
+
+ /* Check for timeout */
+ if (get_timer(start) > 3) {
+ printf(" done failed to come high.\n");
+ log_warn(ERR_XDONE1);
+
+ /* Reset FPGA */
+ grego &= ~GPIO_XCV_PROG; /* PROG line low */
+ out32(IBM405GP_GPIO0_OR, grego);
+
+ goto done;
+ }
+ }
+
+ printf("\n FPGA load succeeded\n");
+ retval = 0; /* Program OK */
+
+done:
+ return retval;
+}
+
+/* FPGA image is stored in flash */
+extern flash_info_t flash_info[];
+
+int init_fpga(void)
+{
+ unsigned int i,j,ptr; /* General purpose */
+ unsigned char bufchar; /* General purpose character */
+ unsigned char *buf; /* Start of image pointer */
+ unsigned long len; /* Length of image */
+ unsigned char *fn_buf; /* Start of filename string */
+ unsigned int fn_len; /* Length of filename string */
+ unsigned char *xcv_buf; /* Pointer to start of image */
+ unsigned long xcv_len; /* Length of image */
+ unsigned long crc; /* 30bit crc in image */
+ unsigned long calc_crc; /* Calc'd 30bit crc */
+ int retval = -1;
+
+ /* Tell the world what we are doing */
+ printf("FPGA: ");
+
+ /*
+ * Get address of first sector where the FPGA
+ * image is stored.
+ */
+ buf = (unsigned char *)flash_info[1].start[0];
+
+ /*
+ * Get the stored image's CRC & length.
+ */
+ crc = *(unsigned long *)(buf+4); /* CRC is first long word */
+ len = *(unsigned long *)(buf+8); /* Image len is next long */
+
+ /* Pedantic */
+ if ((len < 0x133A4) || (len > 0x80000))
+ goto bad_image;
+
+ /*
+ * Get the file name pointer and length.
+ */
+ fn_len = (*(unsigned short *)(buf+12) & 0xff); /* filename length
+ is next short */
+ fn_buf = buf + 14;
+
+ /*
+ * Get the FPGA image pointer and length length.
+ */
+ xcv_buf = fn_buf + fn_len; /* pointer to fpga image */
+ xcv_len = len - 14 - fn_len; /* fpga image length */
+
+ /* Check for uninitialized FLASH */
+ if ((strncmp(buf, "w7o", 3)!=0) || (len > 0x0007ffffL) || (len == 0))
+ goto bad_image;
+
+ /*
+ * Calculate and Check the image's CRC.
+ */
+ calc_crc = crc32(0, xcv_buf, xcv_len);
+ if (crc != calc_crc) {
+ printf("\nfailed - bad CRC\n");
+ goto done;
+ }
+
+ /* Output the file name */
+ printf("file name : ");
+ for (i=0;i<fn_len;i++) {
+ bufchar = fn_buf[+i];
+ if (bufchar<' ' || bufchar>'~') bufchar = '.';
+ putc(bufchar);
+ }
+
+ /*
+ * find rest of display data
+ */
+ ptr = 15; /* Offset to ncd filename
+ length in fpga image */
+ j = xcv_buf[ptr]; /* Get len of ncd filename */
+ if (j > 32) goto bad_image;
+ ptr = ptr + j + 3; /* skip ncd filename string +
+ 3 bytes more bytes */
+
+ /*
+ * output target device string
+ */
+ j = xcv_buf[ptr++] - 1; /* len of targ str less term */
+ if (j > 32) goto bad_image;
+ printf("\n target : ");
+ for (i = 0; i < j; i++) {
+ bufchar = (xcv_buf[ptr++]);
+ if (bufchar<' ' || bufchar>'~') bufchar = '.';
+ putc(bufchar);
+ }
+
+ /*
+ * output compilation date string and time string
+ */
+ ptr += 3; /* skip 2 bytes */
+ printf("\n synth time : ");
+ j = (xcv_buf[ptr++] - 1); /* len of date str less term */
+ if (j > 32) goto bad_image;
+ for (i = 0; i < j; i++) {
+ bufchar = (xcv_buf[ptr++]);
+ if (bufchar<' ' || bufchar>'~') bufchar = '.';
+ putc(bufchar);
+ }
+
+ ptr += 3; /* Skip 2 bytes */
+ printf(" - ");
+ j = (xcv_buf[ptr++] - 1); /* slen = targ dev str len */
+ if (j > 32) goto bad_image;
+ for (i = 0; i < j; i++) {
+ bufchar = (xcv_buf[ptr++]);
+ if (bufchar<' ' || bufchar>'~') bufchar = '.';
+ putc(bufchar);
+ }
+
+ /*
+ * output crc and length strings
+ */
+ printf("\n len & crc : 0x%lx 0x%lx", len, crc);
+
+ /*
+ * Program the FPGA.
+ */
+ retval = fpgaDownload((unsigned char*)xcv_buf, xcv_len,
+ (unsigned short *)0xfd000000L);
+ return retval;
+
+bad_image:
+ printf("\n BAD FPGA image format @ %lx\n", flash_info[1].start[0]);
+ log_warn(ERR_XIMAGE);
+done:
+ return retval;
+}
+
+void test_fpga(unsigned short *daddr)
+{
+ int i;
+ volatile unsigned short *ndest = daddr;
+
+ for (i = 0; i < CONFIG_NUM_FPGAS; i++) {
+#if defined(CONFIG_W7OLMG)
+ ndest[0x7e] = 0x55aa;
+ if (ndest[0x7e] != 0x55aa)
+ log_warn(ERR_XRW1 + i);
+ ndest[0x7e] = 0xaa55;
+ if (ndest[0x7e] != 0xaa55)
+ log_warn(ERR_XRW1 + i);
+ ndest[0x7e] = 0xc318;
+ if (ndest[0x7e] != 0xc318)
+ log_warn(ERR_XRW1 + i);
+
+#elif defined(CONFIG_W7OLMC)
+ ndest[0x800] = 0x55aa;
+ ndest[0x801] = 0xaa55;
+ ndest[0x802] = 0xc318;
+ ndest[0x4800] = 0x55aa;
+ ndest[0x4801] = 0xaa55;
+ ndest[0x4802] = 0xc318;
+ if ((ndest[0x800] != 0x55aa) ||
+ (ndest[0x801] != 0xaa55) ||
+ (ndest[0x802] != 0xc318))
+ log_warn(ERR_XRW1 + (2 * i)); /* Auto gen error code */
+ if ((ndest[0x4800] != 0x55aa) ||
+ (ndest[0x4801] != 0xaa55) ||
+ (ndest[0x4802] != 0xc318))
+ log_warn(ERR_XRW2 + (2 * i)); /* Auto gen error code */
+
+#else
+# error "Unknown W7O board configuration"
+#endif
+ }
+
+ printf(" FPGA ready\n");
+ return;
+}
+
--- /dev/null
+/******************************************************************************
+ *
+ * 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
+ *
+ *****************************************************************************/
+#include <config.h>
+#include <ppc4xx.h>
+
+#define _LINUX_CONFIG_H 1 /* avoid reading Linux autoconf.h file */
+
+#include <ppc_asm.tmpl>
+#include <ppc_defs.h>
+
+#include <asm/cache.h>
+#include <asm/mmu.h>
+
+/******************************************************************************
+ * Function: ext_bus_cntlr_init
+ *
+ * Description: Configures EBC Controller and a few basic chip selects.
+ *
+ * CS0 is setup to get the Boot Flash out of the addresss range
+ * so that we may setup a stack. CS7 is setup so that we can
+ * access and reset the hardware watchdog.
+ *
+ * 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.
+ *
+ * Notes: Does NOT use the stack.
+ *****************************************************************************/
+ .section ".text"
+ .align 2
+ .globl ext_bus_cntlr_init
+ .type ext_bus_cntlr_init, @function
+ext_bus_cntlr_init:
+ mflr r0
+ /********************************************************************
+ * Prefetch entire ext_bus_cntrl_init function into the icache.
+ * This is necessary because we are going to change the same CS we
+ * are executing from. Otherwise a CPU lockup may occur.
+ *******************************************************************/
+ bl ..getAddr
+..getAddr:
+ mflr r3 /* get address of ..getAddr */
+
+ /* Calculate number of cache lines for this function */
+ addi r4, 0, (((.Lfe0 - ..getAddr) / CFG_CACHELINE_SIZE) + 2)
+ mtctr r4
+..ebcloop:
+ icbt r0, r3 /* prefetch cache line for addr in r3*/
+ addi r3, r3, CFG_CACHELINE_SIZE /* move to next cache line */
+ bdnz ..ebcloop /* continue for $CTR 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 /* wait 200us from reset */
+ mtctr r3
+..spinlp:
+ bdnz ..spinlp /* spin loop */
+
+ /********************************************************************
+ * Setup External Bus Controller (EBC).
+ *******************************************************************/
+ addi r3, 0, epcr
+ mtdcr ebccfga, r3
+ addis r4, 0, 0xb040 /* Device base timeout = 1024 cycles */
+ ori r4, r4, 0x0 /* Drive CS with external master */
+ mtdcr ebccfgd, r4
+
+ /********************************************************************
+ * Change PCIINT signal to PerWE
+ *******************************************************************/
+ mfdcr r4, cntrl1
+ ori r4, r4, 0x4000
+ mtdcr cntrl1, r4
+
+ /********************************************************************
+ * Memory Bank 0 (Flash Bank 0) initialization
+ *******************************************************************/
+ addi r3, 0, pb0ap
+ mtdcr ebccfga, r3
+ addis r4, 0, CFG_W7O_EBC_PB0AP@h
+ ori r4, r4, CFG_W7O_EBC_PB0AP@l
+ mtdcr ebccfgd, r4
+
+ addi r3, 0, pb0cr
+ mtdcr ebccfga, r3
+ addis r4, 0, CFG_W7O_EBC_PB0CR@h
+ ori r4, r4, CFG_W7O_EBC_PB0CR@l
+ mtdcr ebccfgd, r4
+
+ /********************************************************************
+ * Memory Bank 7 LEDs - NEEDED BECAUSE OF HW WATCHDOG AND LEDs.
+ *******************************************************************/
+ addi r3, 0, pb7ap
+ mtdcr ebccfga, r3
+ addis r4, 0, CFG_W7O_EBC_PB7AP@h
+ ori r4, r4, CFG_W7O_EBC_PB7AP@l
+ mtdcr ebccfgd, r4
+
+ addi r3, 0, pb7cr
+ mtdcr ebccfga, r3
+ addis r4, 0, CFG_W7O_EBC_PB7CR@h
+ ori r4, r4, CFG_W7O_EBC_PB7CR@l
+ mtdcr ebccfgd, r4
+
+ /* We are all done */
+ mtlr r0 /* Restore link register */
+ blr /* Return to calling function */
+.Lfe0: .size ext_bus_cntlr_init,.Lfe0-ext_bus_cntlr_init
+/* end ext_bus_cntlr_init() */
+
+/******************************************************************************
+ * Function: sdram_init
+ *
+ * Description: Configures SDRAM memory banks.
+ *
+ * Serial Presence Detect, "SPD," reads the SDRAM EEPROM
+ * via the IIC bus and then configures the SDRAM memory
+ * banks appropriately. If Auto Memory Configuration is
+ * is not used, it is assumed that a 4MB 11x8x2, non-ECC,
+ * SDRAM is soldered down.
+ *
+ * Notes: Expects that the stack is already setup.
+ *****************************************************************************/
+ .section ".text"
+ .align 2
+ .globl sdram_init
+ .type sdram_init, @function
+sdram_init:
+ /* save the return info on stack */
+ mflr r0 /* Get link register */
+ stwu r1, -8(r1) /* Save back chain and move SP */
+ stw r0, +12(r1) /* Save link register */
+
+ /*
+ * First call spd_sdram to try to init SDRAM according to the
+ * contents of the SPD EEPROM. If the SPD EEPROM is blank or
+ * erronious, spd_sdram returns 0 in R3.
+ */
+ bl spd_sdram
+ addic. r3, r3, 0 /* Check for error, save dram size */
+ bne ..sdri_done /* If it worked, we're done... */
+
+ /********************************************************************
+ * If SPD detection fails, we'll default to 4MB, 11x8x2, as this
+ * is the SMALLEST SDRAM size the 405 supports. We can do this
+ * because W7O boards have soldered on RAM, and there will always
+ * be some amount present. If we were using DIMMs, we should hang
+ * the board instead, since it doesn't have any RAM to continue
+ * running with.
+ *******************************************************************/
+
+ /*
+ * Disable memory controller to allow
+ * values to be changed.
+ */
+ addi r3, 0, mem_mcopt1
+ mtdcr memcfga, r3
+ addis r4, 0, 0x0
+ ori r4, r4, 0x0
+ mtdcr memcfgd, r4
+
+ /*
+ * Set MB0CF for ext bank 0. (0-4MB) Address Mode 5 since 11x8x2
+ * All other banks are disabled.
+ */
+ addi r3, 0, mem_mb0cf
+ mtdcr memcfga, r3
+ addis r4, 0, 0x0000 /* BA=0x0, SZ=4MB */
+ ori r4, r4, 0x8001 /* Mode is 5, 11x8x2or4, BE=Enabled */
+ mtdcr memcfgd, r4
+
+ /* Clear MB1CR,MB2CR,MB3CR to turn other banks off */
+ addi r4, 0, 0 /* Zero the data reg */
+
+ addi r3, r3, 4 /* Point to MB1CF reg */
+ mtdcr memcfga, r3 /* Set the address */
+ mtdcr memcfgd, r4 /* Zero the reg */
+
+ addi r3, r3, 4 /* Point to MB2CF reg */
+ mtdcr memcfga, r3 /* Set the address */
+ mtdcr memcfgd, r4 /* Zero the reg */
+
+ addi r3, r3, 4 /* Point to MB3CF reg */
+ mtdcr memcfga, r3 /* Set the address */
+ mtdcr memcfgd, r4 /* Zero the reg */
+
+ /********************************************************************
+ * Set the SDRAM Timing reg, SDTR1 and the refresh timer reg, RTR.
+ * To set the appropriate timings, we assume sdram is
+ * 100MHz (pc100 compliant).
+ *******************************************************************/
+
+ /*
+ * Set up SDTR1
+ */
+ addi r3, 0, mem_sdtr1
+ mtdcr memcfga, r3
+ addis r4, 0, 0x0086 /* SDTR1 value for 100Mhz */
+ ori r4, r4, 0x400D
+ mtdcr memcfgd, r4
+
+ /*
+ * Set RTR
+ */
+ addi r3, 0, mem_rtr
+ mtdcr memcfga, r3
+ addis r4, 0, 0x05F0 /* RTR refresh val = 15.625ms@100Mhz */
+ mtdcr memcfgd, r4
+
+ /********************************************************************
+ * Delay to ensure 200usec have elapsed since reset. Assume worst
+ * case that the core is running 200Mhz:
+ * 200,000,000 (cycles/sec) X .000200 (sec) = 0x9C40 cycles
+ *******************************************************************/
+ addis r3, 0, 0x0000
+ ori r3, r3, 0xA000 /* Wait 200us from reset */
+ mtctr r3
+..spinlp2:
+ bdnz ..spinlp2 /* spin loop */
+
+ /********************************************************************
+ * Set memory controller options reg, MCOPT1.
+ *******************************************************************/
+ addi r3, 0, mem_mcopt1
+ mtdcr memcfga, r3
+ addis r4, 0, 0x80E0 /* DC_EN=1,SRE=0,PME=0,MEMCHK=0 */
+ ori r4, r4, 0x0000 /* REGEN=0,DRW=00,BRPF=01,ECCDD=1 */
+ mtdcr memcfgd, r4 /* EMDULR=1 */
+
+..sdri_done:
+ /* restore and return */
+ lwz r0, +12(r1) /* Get saved link register */
+ addi r1, r1, +8 /* Remove frame from stack */
+ mtlr r0 /* Restore link register */
+ blr /* Return to calling function */
+.Lfe1: .size sdram_init,.Lfe1-sdram_init
+/* end sdram_init() */
+
--- /dev/null
+/*
+ * (C) Copyright 2001
+ * Bill Hunter, Wave 7 Optics, william.hunter@mediaone.net
+ * and
+ * Erik Theisen, Wave 7 Optics, etheisen@mindspring.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
+ */
+/*
+ * Description:
+ * Routine to exercise memory for the bringing up of our boards.
+ */
+#include <config.h>
+#include <ppc4xx.h>
+
+#define _LINUX_CONFIG_H 1 /* avoid reading Linux autoconf.h file */
+
+#include <ppc_asm.tmpl>
+#include <ppc_defs.h>
+
+#include <asm/cache.h>
+#include <asm/mmu.h>
+
+#include <watchdog.h>
+
+#include "errors.h"
+
+#define _ASMLANGUAGE
+
+ .globl test_sdram
+ .globl test_led
+ .globl log_stat
+ .globl log_warn
+ .globl log_err
+ .globl temp_uart_init
+ .globl post_puts
+ .globl disp_hex
+
+/*****************************************************
+******* Text Strings for low level printing ******
+******* In section got2 *******
+*****************************************************/
+
+/*
+ * Define the text strings for errors and warnings.
+ * Switch to .data section.
+ */
+ .section ".data"
+err_str: .asciz "*** POST ERROR = "
+warn_str: .asciz "*** POST WARNING = "
+end_str: .asciz "\r\n"
+
+/*
+ * Enter the labels in Global Entry Table (GOT).
+ * Switch to .got2 section.
+ */
+ START_GOT
+ GOT_ENTRY(err_str)
+ GOT_ENTRY(warn_str)
+ GOT_ENTRY(end_str)
+ END_GOT
+
+/*
+ * Switch back to .text section.
+ */
+ .text
+
+/****************************************
+ ****************************************
+ ******** LED register test ********
+ ****************************************
+ ***************************************/
+test_led:
+ /* save the return info on stack */
+ mflr r0 /* Get link register */
+ stwu r1, -12(r1) /* Save back chain and move SP */
+ stw r0, +16(r1) /* Save link register */
+ stw r4, +8(r1) /* save R4 */
+
+ WATCHDOG_RESET /* Reset the watchdog */
+
+ addi r3, 0, ERR_FF /* first test value is ffff */
+ addi r4, r3, 0 /* save copy of pattern */
+ bl set_led /* store first test value */
+ bl get_led /* read it back */
+ xor. r4, r4, r3 /* compare to original */
+#if defined(CONFIG_W7OLMC)
+ andi. r4, r4, 0x00ff /* lmc has 8 bits */
+#else
+ andi. r4, r4, 0xffff /* lmg has 16 bits */
+#endif
+ beq LED2 /* next test */
+ addi r3, 0, ERR_LED /* error code = 1 */
+ bl log_err /* display error and halt */
+LED2: addi r3, 0, ERR_00 /* 2nd test value is 0000 */
+ addi r4, r3, 0 /* save copy of pattern */
+ bl set_led /* store first test value */
+ bl get_led /* read it back */
+ xor. r4, r4, r3 /* compare to original */
+#if defined(CONFIG_W7OLMC)
+ andi. r4, r4, 0x00ff /* lmc has 8 bits */
+#else
+ andi. r4, r4, 0xffff /* lmg has 16 bits */
+#endif
+ beq LED3 /* next test */
+ addi r3, 0, ERR_LED /* error code = 1 */
+ bl log_err /* display error and halt */
+
+LED3: /* restore stack and return */
+ lwz r0, +16(r1) /* Get saved link register */
+ mtlr r0 /* Restore link register */
+ lwz r4, +8(r1) /* restore r4 */
+ addi r1, r1, +12 /* Remove frame from stack */
+ blr /* Return to calling function */
+
+/****************************************
+ ****************************************
+ ******** SDRAM TESTS ********
+ ****************************************
+ ***************************************/
+test_sdram:
+ /* called with mem size in r3 */
+ /* save the return info on stack */
+ mflr r0 /* Get link register */
+ stwu r1, -16(r1) /* Save back chain and move SP */
+ stw r0, +20(r1) /* Save link register */
+ stmw r30, +8(r1) /* save R30,R31 */
+ /* r30 is log2(mem size) */
+ /* r31 is mem size */
+
+ /* take log2 of total mem size */
+ addi r31, r3, 0 /* save total mem size */
+ addi r30, 0, 0 /* clear r30 */
+l2_loop:
+ srwi. r31, r31, 1 /* shift right 1 */
+ addi r30, r30, 1 /* count shifts */
+ bne l2_loop /* loop till done */
+ addi r30, r30, -1 /* correct for over count */
+ addi r31, r3, 0 /* save original size */
+
+ /* now kick the dog and test the mem */
+ WATCHDOG_RESET /* Reset the watchdog */
+ bl Data_Buster /* test crossed/shorted data lines */
+ addi r3, r30, 0 /* get log2(memsize) */
+ addi r4, r31, 0 /* get memsize */
+ bl Ghost_Buster /* test crossed/shorted addr lines */
+ addi r3, r31, 0 /* get mem size */
+ bl Bit_Buster /* check for bad internal bits */
+
+ /* restore stack and return */
+ lmw r30, +8(r1) /* Restore r30, r31 */
+ lwz r0, +20(r1) /* Get saved link register */
+ mtlr r0 /* Restore link register */
+ addi r1, r1, +16 /* Remove frame from stack */
+ blr /* Return to calling function */
+
+
+/****************************************
+ ******** sdram data bus test ********
+ ***************************************/
+Data_Buster:
+ /* save the return info on stack */
+ mflr r0 /* Get link register */
+ stwu r1, -24(r1) /* Save back chain and move SP */
+ stw r0, +28(r1) /* Save link register */
+ stmw r28, 8(r1) /* save r28 - r31 on stack */
+ /* r31 i/o register */
+ /* r30 sdram base address */
+ /* r29 5555 syndrom */
+ /* r28 aaaa syndrom */
+
+ /* set up led register for this test */
+ addi r3, 0, ERR_RAMG /* set led code to 1 */
+ bl log_stat /* store test value */
+ /* now test the dram data bus */
+ xor r30, r30, r30 /* load r30 with base addr of sdram */
+ addis r31, 0, 0x5555 /* load r31 with test value */
+ ori r31, r31, 0x5555
+ stw r31,0(r30) /* sto the value */
+ lwz r29,0(r30) /* read it back */
+ xor r29,r31,r29 /* compare it to original */
+ addis r31, 0, 0xaaaa /* load r31 with test value */
+ ori r31, r31, 0xaaaa
+ stw r31,0(r30) /* sto the value */
+ lwz r28,0(r30) /* read it back */
+ xor r28,r31,r28 /* compare it to original */
+ or r3,r28,r29 /* or together both error terms */
+ /*
+ * Now that we have the error bits,
+ * we have to decide which part they are in.
+ */
+ bl get_idx /* r5 is now index to error */
+ addi r3, r3, ERR_RAMG
+ cmpwi r3, ERR_RAMG /* check for errors */
+ beq db_done /* skip if no errors */
+ bl log_err /* log the error */
+
+db_done:
+ lmw r28, 8(r1) /* restore r28 - r31 from stack */
+ lwz r0, +28(r1) /* Get saved link register */
+ addi r1, r1, +24 /* Remove frame from stack */
+ mtlr r0 /* Restore link register */
+ blr /* Return to calling function */
+
+
+/****************************************************
+ ******** test for address ghosting in dram ********
+ ***************************************************/
+
+Ghost_Buster:
+ /* save the return info on stack */
+ mflr r0 /* Get link register */
+ stwu r1, -36(r1) /* Save back chain and move SP */
+ stw r0, +40(r1) /* Save link register */
+ stmw r25, 8(r1) /* save r25 - r31 on stack */
+ /* r31 = scratch register */
+ /* r30 is main referance loop counter,
+ 0 to 23 */
+ /* r29 is ghost loop count, 0 to 22 */
+ /* r28 is referance address */
+ /* r27 is ghost address */
+ /* r26 is log2 (mem size) =
+ number of byte addr bits */
+ /* r25 is mem size */
+
+ /* save the log2(mem size) and mem size */
+ addi r26, r3, 0 /* r26 is number of byte addr bits */
+ addi r25, r4, 0 /* r25 is mem size in bytes */
+
+ /* set the leds for address ghost test */
+ addi r3, 0, ERR_ADDG
+ bl set_led
+
+ /* first fill memory with zeros */
+ srwi r31, r25, 2 /* convert bytes to longs */
+ mtctr r31 /* setup byte counter */
+ addi r28, 0, 0 /* start at address at 0 */
+ addi r31, 0, 0 /* data value = 0 */
+clr_loop:
+ stw r31, 0(r28) /* Store zero value */
+ addi r28, r28, 4 /* Increment to next word */
+ andi. r27, r28, 0xffff /* check for 2^16 loops */
+ bne clr_skip /* if not there, then skip */
+ WATCHDOG_RESET /* kick the dog every now and then */
+clr_skip:
+ bdnz clr_loop /* Round and round... */
+
+ /* now do main test */
+ addi r30, 0, 0 /* start referance counter at 0 */
+outside:
+ /*
+ * Calculate the referance address
+ * the referance address is calculated by setting the (r30-1)
+ * bit of the base address
+ * when r30=0, the referance address is the base address.
+ * thus the sequence 0,1,2,4,8,..,2^(n-1)
+ * setting the bit is done with the following shift functions.
+ */
+ WATCHDOG_RESET /* Reset the watchdog */
+
+ addi r31, 0, 1 /* r31 = 1 */
+ slw r28, r31, r30 /* set bit coresponding to loop cnt */
+ srwi r28, r28, 1 /* then shift it right one so */
+ /* we start at location 0 */
+ /* fill referance address with Fs */
+ addi r31, 0, 0x00ff /* r31 = one byte of set bits */
+ stb r31,0(r28) /* save ff in referance address */
+
+ /* ghost (inner) loop, now check all posible ghosted addresses */
+ addi r29, 0, 0 /* start ghosted loop counter at 0 */
+inside:
+ /*
+ * Calculate the ghost address by flipping one
+ * bit of referance address. This gives the
+ * sequence 1,2,4,8,...,2^(n-1)
+ */
+ addi r31, 0, 1 /* r31 = 1 */
+ slw r27, r31, r29 /* set bit coresponding to loop cnt */
+ xor r27, r28, r27 /* ghost address = ref addr with
+ bit flipped*/
+
+ /* now check for ghosting */
+ lbz r31,0(r27) /* get content of ghost addr */
+ cmpwi r31, 0 /* compare read value to 0 */
+ bne Casper /* we found a ghost! */
+
+ /* now close ghost ( inner ) loop */
+ addi r29, r29, 1 /* increment inner loop counter */
+ cmpw r29, r26 /* check for last inner loop */
+ blt inside /* do more inner loops */
+
+ /* now close referance ( outer ) loop */
+ addi r31, 0, 0 /* r31 = zero */
+ stb r31, 0(28) /* zero out the altered address loc. */
+ /*
+ * Increment and check for end, count is zero based.
+ * With the ble, this gives us one more loops than
+ * address bits for sequence 0,1,2,4,8,...2^(n-1)
+ */
+ addi r30, r30, 1 /* increment outer loop counter */
+ cmpw r30, r26 /* check for last inner loop */
+ ble outside /* do more outer loops */
+
+ /* were done, lets go home */
+ b gb_done
+Casper: /* we found a ghost !! */
+ addi r3, 0, ERR_ADDF /* get indexed error message */
+ bl log_err /* log error led error code */
+gb_done: /* pack your bags, and go home */
+ lmw r25, 8(r1) /* restore r25 - r31 from stack */
+ lwz r0, +40(r1) /* Get saved link register */
+ addi r1, r1, +36 /* Remove frame from stack */
+ mtlr r0 /* Restore link register */
+ blr /* Return to calling function */
+
+/****************************************************
+ ******** SDRAM data fill tests **********
+ ***************************************************/
+Bit_Buster:
+ /* called with mem size in r3 */
+ /* save the return info on stack */
+ mflr r0 /* Get link register */
+ stwu r1, -16(r1) /* Save back chain and move SP */
+ stw r0, +20(r1) /* Save link register */
+ stw r4, +8(r1) /* save R4 */
+ stw r5, +12(r1) /* save r5 */
+
+ addis r5, r3, 0 /* save mem size */
+
+ /* Test 55555555 */
+ addi r3, 0, ERR_R55G /* set up error code in case we fail */
+ bl log_stat /* store test value */
+ addis r4, 0, 0x5555
+ ori r4, r4, 0x5555
+ bl fill_test
+
+ /* Test aaaaaaaa */
+ addi r3, 0, ERR_RAAG /* set up error code in case we fail */
+ bl log_stat /* store test value */
+ addis r4, 0, 0xAAAA
+ ori r4, r4, 0xAAAA
+ bl fill_test
+
+ /* Test 00000000 */
+ addi r3, 0, ERR_R00G /* set up error code in case we fail */
+ bl log_stat /* store test value */
+ addis r4, 0, 0
+ ori r4, r4, 0
+ bl fill_test
+
+ /* restore stack and return */
+ lwz r5, +12(r1) /* restore r4 */
+ lwz r4, +8(r1) /* restore r4 */
+ lwz r0, +20(r1) /* Get saved link register */
+ addi r1, r1, +16 /* Remove frame from stack */
+ mtlr r0 /* Restore link register */
+ blr /* Return to calling function */
+
+
+
+/****************************************************
+ ******** fill test ********
+ ***************************************************/
+/* tests memory by filling with value, and reading back */
+/* r5 = Size of memory in bytes */
+/* r4 = Value to write */
+/* r3 = Error code */
+fill_test:
+ mflr r0 /* Get link register */
+ stwu r1, -32(r1) /* Save back chain and move SP */
+ stw r0, +36(r1) /* Save link register */
+ stmw r27, 8(r1) /* save r27 - r31 on stack */
+ /* r31 - scratch register */
+ /* r30 - memory address */
+ mr r27, r3
+ mr r28, r4
+ mr r29, r5
+
+ WATCHDOG_RESET /* Reset the watchdog */
+
+ /* first fill memory with Value */
+ srawi r31, r29, 2 /* convert bytes to longs */
+ mtctr r31 /* setup counter */
+ addi r30, 0, 0 /* Make r30 = addr 0 */
+ft_0: stw r28, 0(r30) /* Store value */
+ addi r30, r30, 4 /* Increment to next word */
+ andi. r31, r30, 0xffff /* check for 2^16 loops */
+ bne ft_0a /* if not there, then skip */
+ WATCHDOG_RESET /* kick the dog every now and then */
+ft_0a: bdnz ft_0 /* Round and round... */
+
+ WATCHDOG_RESET /* Reset the watchdog */
+
+ /* Now confirm Value is in memory */
+ srawi r31, r29, 2 /* convert bytes to longs */
+ mtctr r31 /* setup counter */
+ addi r30, 0, 0 /* Make r30 = addr 0 */
+ft_1: lwz r31, 0(r30) /* get value from memory */
+ xor. r31, r31, r28 /* Writen = Read ? */
+ bne ft_err /* If bad, than halt */
+ addi r30, r30, 4 /* Increment to next word */
+ andi. r31, r30, 0xffff /* check for 2^16 loops*/
+ bne ft_1a /* if not there, then skip */
+ WATCHDOG_RESET /* kick the dog every now and then */
+ft_1a: bdnz ft_1 /* Round and round... */
+
+ WATCHDOG_RESET /* Reset the watchdog */
+
+ b fill_done /* restore and return */
+
+ft_err: addi r29, r27, 0 /* save current led code */
+ addi r27, r31, 0 /* get pattern in r27 */
+ bl get_idx /* get index from r27 */
+ add r27, r27, r29 /* add index to old led code */
+ bl log_err /* output led err code, halt CPU */
+
+fill_done:
+ lmw r27, 8(r1) /* restore r27 - r31 from stack */
+ lwz r0, +36(r1) /* Get saved link register */
+ addi r1, r1, +32 /* Remove frame from stack */
+ mtlr r0 /* Restore link register */
+ blr /* Return to calling function */
+
+
+/****************************************************
+ ******* get error index from r3 pattern ********
+ ***************************************************/
+get_idx: /* r3 = (MSW(r3) !=0)*2 +
+ (LSW(r3) !=0) */
+ /* save the return info on stack */
+ mflr r0 /* Get link register */
+ stwu r1, -12(r1) /* Save back chain and move SP */
+ stw r0, +16(r1) /* Save link register */
+ stw r4, +8(r1) /* save R4 */
+
+ andi. r4, r3, 0xffff /* check for lower bits */
+ beq gi2 /* skip if no bits set */
+ andis. r4, r3, 0xffff /* check for upper bits */
+ beq gi3 /* skip if no bits set */
+ addi r3, 0, 3 /* both upper and lower bits set */
+ b gi_done
+gi2: andis. r4, r3, 0xffff /* check for upper bits*/
+ beq gi4 /* skip if no bits set */
+ addi r3, 0, 2 /* only upper bits set */
+ b gi_done
+gi3: addi r3, 0, 1 /* only lower bits set */
+ b gi_done
+gi4: addi r3, 0, 0 /* no bits set */
+gi_done:
+ /* restore stack and return */
+ lwz r0, +16(r1) /* Get saved link register */
+ mtlr r0 /* Restore link register */
+ lwz r4, +8(r1) /* restore r4 */
+ addi r1, r1, +12 /* Remove frame from stack */
+ blr /* Return to calling function */
+
+/****************************************************
+ ******** set LED to R5 and hang ********
+ ***************************************************/
+log_stat: /* output a led code and continue */
+set_led:
+ /* save the return info on stack */
+ mflr r0 /* Get link register */
+ stwu r1, -12(r1) /* Save back chain and move SP */
+ stw r0, +16(r1) /* Save link register */
+ stw r4, +8(r1) /* save R4 */
+
+ addis r4, 0, 0xfe00 /* LED buffer is at 0xfe000000 */
+#if defined(CONFIG_W7OLMG) /* only on gateway, invert outputs */
+ xori r3,r3, 0xffff /* complement led code, active low */
+ sth r3, 0(r4) /* store first test value */
+ xori r3,r3, 0xffff /* complement led code, active low */
+#else /* if not gateway, then don't invert */
+ sth r3, 0(r4) /* store first test value */
+#endif
+
+ /* restore stack and return */
+ lwz r0, +16(r1) /* Get saved link register */
+ mtlr r0 /* Restore link register */
+ lwz r4, +8(r1) /* restore r4 */
+ addi r1, r1, +12 /* Remove frame from stack */
+ blr /* Return to calling function */
+
+get_led:
+ /* save the return info on stack */
+ mflr r0 /* Get link register */
+ stwu r1, -12(r1) /* Save back chain and move SP */
+ stw r0, +16(r1) /* Save link register */
+ stw r4, +8(r1) /* save R4 */
+
+ addis r4, 0, 0xfe00 /* LED buffer is at 0xfe000000 */
+ lhz r3, 0(r4) /* store first test value */
+#if defined(CONFIG_W7OLMG) /* only on gateway, invert inputs */
+ xori r3,r3, 0xffff /* complement led code, active low */
+#endif
+
+ /* restore stack and return */
+ lwz r0, +16(r1) /* Get saved link register */
+ mtlr r0 /* Restore link register */
+ lwz r4, +8(r1) /* restore r4 */
+ addi r1, r1, +12 /* Remove frame from stack */
+ blr /* Return to calling function */
+
+log_err: /* output the error and hang the board ( for now ) */
+ /* save the return info on stack */
+ mflr r0 /* Get link register */
+ stwu r1, -12(r1) /* Save back chain and move SP */
+ stw r0, +16(r1) /* Save link register */
+ stw r3, +8(r1) /* save a copy of error code */
+ bl set_led /* set the led pattern */
+ GET_GOT /* get GOT address in r14 */
+ lwz r3,GOT(err_str) /* get address of string */
+ bl post_puts /* output the warning string */
+ lwz r3, +8(r1) /* get error code */
+ addi r4, 0, 2 /* set disp length to 2 nibbles */
+ bl disp_hex /* output the error code */
+ lwz r3,GOT(end_str) /* get address of string */
+ bl post_puts /* output the warning string */
+halt:
+ b halt /* hang */
+
+ /* restore stack and return */
+ lwz r0, +16(r1) /* Get saved link register */
+ mtlr r0 /* Restore link register */
+ addi r1, r1, +12 /* Remove frame from stack */
+ blr /* Return to calling function */
+
+log_warn: /* output a warning, then continue with operations */
+ /* save the return info on stack */
+ mflr r0 /* Get link register */
+ stwu r1, -16(r1) /* Save back chain and move SP */
+ stw r0, +20(r1) /* Save link register */
+ stw r3, +8(r1) /* save a copy of error code */
+ stw r14, +12(r1) /* save a copy of r14 (used by GOT) */
+
+ bl set_led /* set the led pattern */
+ GET_GOT /* get GOT address in r14 */
+ lwz r3,GOT(warn_str) /* get address of string */
+ bl post_puts /* output the warning string */
+ lwz r3, +8(r1) /* get error code */
+ addi r4, 0, 2 /* set disp length to 2 nibbles */
+ bl disp_hex /* output the error code */
+ lwz r3,GOT(end_str) /* get address of string */
+ bl post_puts /* output the warning string */
+
+ addis r3, 0, 64 /* has a long delay */
+ mtctr r3
+log_2:
+ WATCHDOG_RESET /* this keeps dog from barking, */
+ /* and takes time */
+ bdnz log_2 /* loop till time expires */
+
+ /* restore stack and return */
+ lwz r0, +20(r1) /* Get saved link register */
+ lwz r14, +12(r1) /* restore r14 */
+ mtlr r0 /* Restore link register */
+ addi r1, r1, +16 /* Remove frame from stack */
+ blr /* Return to calling function */
+
+/*******************************************************************
+ * temp_uart_init
+ * Temporary UART initialization routine
+ * Sets up UART0 to run at 9600N81 off of the internal clock.
+ * R3-R4 are used.
+ ******************************************************************/
+temp_uart_init:
+ /* save the return info on stack */
+ mflr r0 /* Get link register */
+ stwu r1, -8(r1) /* Save back chain and move SP */
+ stw r0, +12(r1) /* Save link register */
+
+ addis r3, 0, 0xef60
+ ori r3, r3, 0x0303 /* r3 = UART0_LCR */
+ addi r4, 0, 0x83 /* n81 format, divisor regs enabled */
+ stb r4, 0(r3)
+
+ /* set baud rate to use internal clock,
+ baud = (200e6/16)/31/42 = 9600 */
+
+ addis r3, 0, 0xef60 /* Address of baud divisor reg */
+ ori r3, r3, 0x0300 /* UART0_DLM */
+ addi r4, 0, +42 /* uart baud divisor LSB = 93 */
+ stb r4, 0(r3) /* baud = (200 /16)/14/93 */
+
+ addi r3, r3, 0x0001 /* uart baud divisor addr */
+ addi r4, 0, 0
+ stb r4, 0(r3) /* Divisor Latch MSB = 0 */
+
+ addis r3, 0, 0xef60
+ ori r3, r3, 0x0303 /* r3 = UART0_LCR */
+ addi r4, 0, 0x03 /* n81 format, tx/rx regs enabled */
+ stb r4, 0(r3)
+
+ /* output a few line feeds */
+ addi r3, 0, '\n' /* load line feed */
+ bl post_putc /* output the char */
+ addi r3, 0, '\n' /* load line feed */
+ bl post_putc /* output the char */
+
+ /* restore stack and return */
+ lwz r0, +12(r1) /* Get saved link register */
+ mtlr r0 /* Restore link register */
+ addi r1, r1, +8 /* Remove frame from stack */
+ blr /* Return to calling function */
+
+/**********************************************************************
+ ** post_putc
+ ** outputs charactor in R3
+ ** r3 returns the error code ( -1 if there is an error )
+ *********************************************************************/
+
+post_putc:
+
+ /* save the return info on stack */
+ mflr r0 /* Get link register */
+ stwu r1, -20(r1) /* Save back chain and move SP */
+ stw r0, +24(r1) /* Save link register */
+ stmw r29, 8(r1) /* save r29 - r31 on stack
+ r31 - uart base address
+ r30 - delay counter
+ r29 - scratch reg */
+
+ addis r31, 0, 0xef60 /* Point to uart base */
+ ori r31, r31, 0x0300
+ addis r30, 0, 152 /* Load about 10,000,000 ticks. */
+pputc_lp:
+ lbz r29, 5(r31) /* Read Line Status Register */
+ andi. r29, r29, 0x20 /* Check THRE status */
+ bne thre_set /* Branch if FIFO empty */
+ addic. r30, r30, -1 /* Decrement and check if empty. */
+ bne pputc_lp /* Try, try again */
+ addi r3, 0, -1 /* Load error code for timeout */
+ b pputc_done /* Bail out with error code set */
+thre_set:
+ stb r3, 0(r31) /* Store character to UART */
+ addi r3, 0, 0 /* clear error code */
+pputc_done:
+ lmw r29, 8(r1) /*restore r29 - r31 from stack */
+ lwz r0, +24(r1) /* Get saved link register */
+ addi r1, r1, +20 /* Remove frame from stack */
+ mtlr r0 /* Restore link register */
+ blr /* Return to calling function */
+
+
+/****************************************************************
+ post_puts
+ Accepts a null-terminated string pointed to by R3
+ Outputs to the serial port until 0x00 is found.
+ r3 returns the error code ( -1 if there is an error )
+*****************************************************************/
+post_puts:
+
+ /* save the return info on stack */
+ mflr r0 /* Get link register */
+ stwu r1, -12(r1) /* Save back chain and move SP */
+ stw r0, +16(r1) /* Save link register */
+ stw r31, 8(r1) /* save r31 - char pointer */
+
+ addi r31, r3, 0 /* move pointer to R31 */
+pputs_nxt:
+ lbz r3, 0(r31) /* Get next character */
+ addic. r3, r3, 0 /* Check for zero */
+ beq pputs_term /* bail out if zero */
+ bl post_putc /* output the char */
+ addic. r3, r3, 0 /* check for error */
+ bne pputs_err
+ addi r31, r31, 1 /* point to next char */
+ b pputs_nxt /* loop till term */
+pputs_err:
+ addi r3, 0, -1 /* set error code */
+ b pputs_end /* were outa here */
+pputs_term:
+ addi r3, 0, 1 /* set success code */
+ /* restore stack and return */
+pputs_end:
+ lwz r31, 8(r1) /* restore r27 - r31 from stack */
+ lwz r0, +16(r1) /* Get saved link register */
+ addi r1, r1, +12 /* Remove frame from stack */
+ mtlr r0 /* Restore link register */
+ blr /* Return to calling function */
+
+
+
+/********************************************************************
+ ***** disp_hex
+ ***** Routine to display a hex value from a register.
+ ***** R3 is value to display
+ ***** R4 is number of nibbles to display ie 2 for byte 8 for (long)word
+ ***** Returns -1 in R3 if there is an error ( ie serial port hangs )
+ ***** Returns 0 in R3 if no error
+ *******************************************************************/
+disp_hex:
+ /* save the return info on stack */
+ mflr r0 /* Get link register */
+ stwu r1, -16(r1) /* Save back chain and move SP */
+ stw r0, +20(r1) /* Save link register */
+ stmw r30, 8(r1) /* save r30 - r31 on stack */
+ /* r31 output char */
+ /* r30 uart base address */
+ addi r30, 0, 8 /* Go through 8 nibbles. */
+ addi r31, r3, 0
+pputh_nxt:
+ rlwinm r31, r31, 4, 0, 31 /* Rotate next nibble into position */
+ andi. r3, r31, 0x0f /* Get nibble. */
+ addi r3, r3, 0x30 /* Add zero's ASCII code. */
+ cmpwi r3, 0x03a
+ blt pputh_out
+ addi r3, r3, 0x07 /* 0x27 for lower case. */
+pputh_out:
+ cmpw r30, r4
+ bgt pputh_skip
+ bl post_putc
+ addic. r3, r3, 0 /* check for error */
+ bne pputh_err
+pputh_skip:
+ addic. r30, r30, -1
+ bne pputh_nxt
+ xor r3, r3, r3 /* Clear error code */
+ b pputh_done
+pputh_err:
+ addi r3, 0, -1 /* set error code */
+pputh_done:
+ /* restore stack and return */
+ lmw r30, 8(r1) /* restore r30 - r31 from stack */
+ lwz r0, +20(r1) /* Get saved link register */
+ addi r1, r1, +16 /* Remove frame from stack */
+ mtlr r0 /* Restore link register */
+ blr /* Return to calling function */
+
--- /dev/null
+/*
+ * (C) Copyright 2001
+ * Bill Hunter, Wave 7 Optics, williamhunter@mediaone.net
+ * and
+ * Erik Theisen, Wave 7 Optics, etheisen@mindspring.com.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <config.h>
+#include <rtc.h>
+#include "errors.h"
+#include "dtt.h"
+
+#if defined(CONFIG_RTC_M48T35A)
+void rtctest(void)
+{
+ volatile uchar *tchar = (uchar*)(CFG_NVRAM_BASE_ADDR + CFG_NVRAM_SIZE - 9);
+ struct rtc_time tmp;
+
+ /* set up led code for RTC tests */
+ log_stat(ERR_RTCG);
+
+ /*
+ * Do RTC battery test. The first write after power up
+ * fails if battery is low.
+ */
+ *tchar = 0xaa;
+ if ((*tchar ^ 0xaa) != 0x0) log_warn(ERR_RTCBAT);
+ *tchar = 0x55; /* Reset test address */
+
+ /*
+ * Now lets check the validity of the values in the RTC.
+ */
+ rtc_get(&tmp);
+ if ((tmp.tm_sec < 0) | (tmp.tm_sec > 59) |
+ (tmp.tm_min < 0) | (tmp.tm_min > 59) |
+ (tmp.tm_hour < 0) | (tmp.tm_hour > 23) |
+ (tmp.tm_mday < 1 ) | (tmp.tm_mday > 31) |
+ (tmp.tm_mon < 1 ) | (tmp.tm_mon > 12) |
+ (tmp.tm_year < 2000) | (tmp.tm_year > 2500) |
+ (tmp.tm_wday < 1 ) | (tmp.tm_wday > 7)) {
+ log_warn(ERR_RTCTIM);
+ rtc_reset();
+ }
+
+ /*
+ * Now lets do a check to see if the NV RAM is there.
+ */
+ *tchar = 0xaa;
+ if ((*tchar ^ 0xaa) != 0x0) log_err(ERR_RTCVAL);
+ *tchar = 0x55; /* Reset test address */
+
+} /* rtctest() */
+#endif /* CONFIG_RTC_M48T35A */
+
+
+#ifdef CONFIG_DTT_LM75
+int dtt_test(int sensor)
+{
+ short temp, trip, hyst;
+
+ /* get values */
+ temp = dtt_read(sensor, DTT_READ_TEMP) / 256;
+ trip = dtt_read(sensor, DTT_TEMP_SET) / 256;
+ hyst = dtt_read(sensor, DTT_TEMP_HYST) / 256;
+
+ /* check values */
+ if ((hyst != (CFG_DTT_MAX_TEMP - CFG_DTT_HYSTERESIS)) ||
+ (trip != CFG_DTT_MAX_TEMP) ||
+ (temp < CFG_DTT_LOW_TEMP) || (temp > CFG_DTT_MAX_TEMP))
+ return 1;
+
+ return 0;
+} /* dtt_test() */
+#endif /* CONFIG_DTT_LM75 */
+
+/*****************************************/
+
+void post2(void)
+{
+#if defined(CONFIG_RTC_M48T35A)
+ rtctest();
+#endif /* CONFIG_RTC_M48T35A */
+
+#ifdef CONFIG_DTT_LM75
+ log_stat(ERR_TempG);
+ if(dtt_test(2) != 0) log_warn(ERR_Ttest0);
+ if(dtt_test(4) != 0) log_warn(ERR_Ttest1);
+#endif /* CONFIG_DTT_LM75 */
+} /* post2() */
+
--- /dev/null
+/*
+ * (C) Copyright 2001
+ * Erik Theisen, Wave 7 Optics, etheisen@mindspring.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
+ */
+
+#if defined(VXWORKS)
+# include <stdio.h>
+# include <string.h>
+# define CFG_DEF_EEPROM_ADDR 0xa0
+extern char iicReadByte( char, char );
+extern ulong_t crc32( unsigned char *, unsigned long );
+#else
+#include <common.h>
+#endif
+
+#include "vpd.h"
+
+/*
+ * vpd_reader() - reads VPD data from I2C EEPROMS.
+ * returns pointer to buffer or NULL.
+ */
+static unsigned char *
+vpd_reader(unsigned char *buf, unsigned dev_addr, unsigned off, unsigned count)
+{
+ unsigned offset = off; /* Calculated offset */
+
+ /*
+ * The main board EEPROM contains
+ * SDRAM SPD in the first 128 bytes,
+ * so skew the offset.
+ */
+ if (dev_addr == CFG_DEF_EEPROM_ADDR)
+ offset += SDRAM_SPD_DATA_SIZE;
+
+ /* Try to read the I2C EEPROM */
+#if defined(VXWORKS)
+ {
+ int i;
+ for( i = 0; i < count; ++i ) {
+ buf[ i ] = iicReadByte( dev_addr, offset+i );
+ }
+ }
+#else
+ if (eeprom_read(dev_addr, offset, buf, count)) {
+ printf("Failed to read %d bytes from VPD EEPROM 0x%x @ 0x%x\n",
+ count, dev_addr, offset);
+ return NULL;
+ }
+#endif
+
+ return buf;
+} /* vpd_reader() */
+
+
+/*
+ * vpd_get_packet() - returns next VPD packet or NULL.
+ */
+static vpd_packet_t *vpd_get_packet(vpd_packet_t *vpd_packet)
+{
+ vpd_packet_t *packet = vpd_packet;
+
+ if (packet != NULL) {
+ if (packet->identifier == VPD_PID_TERM)
+ return NULL;
+ else
+ packet = (vpd_packet_t *)((char *)packet + packet->size + 2);
+ }
+
+ return packet;
+} /* vpd_get_packet() */
+
+
+/*
+ * vpd_find_packet() - Locates and returns the specified
+ * VPD packet or NULL on error.
+ */
+static vpd_packet_t *vpd_find_packet(vpd_t *vpd, unsigned char ident)
+{
+ vpd_packet_t *packet = (vpd_packet_t *)&vpd->packets;
+
+ /* Guaranteed illegal */
+ if (ident == VPD_PID_GI)
+ return NULL;
+
+ /* Scan tuples looking for a match */
+ while ((packet->identifier != ident) &&
+ (packet->identifier != VPD_PID_TERM))
+ packet = vpd_get_packet(packet);
+
+ /* Did we find it? */
+ if ((packet->identifier) && (packet->identifier != ident))
+ return NULL;
+ return packet;
+}
+
+
+/*
+ * vpd_is_valid() - Validates contents of VPD data
+ * in I2C EEPROM. Returns 1 for
+ * success or 0 for failure.
+ */
+static int vpd_is_valid(unsigned dev_addr, unsigned char *buf)
+{
+ unsigned num_bytes;
+ vpd_packet_t *packet;
+ vpd_t *vpd = (vpd_t *)buf;
+ unsigned short stored_crc16, calc_crc16 = 0xffff;
+
+ /* Check Eyecatcher */
+ if (strncmp(vpd->header.eyecatcher, VPD_EYECATCHER, VPD_EYE_SIZE) != 0) {
+ unsigned offset = 0;
+ if (dev_addr == CFG_DEF_EEPROM_ADDR)
+ offset += SDRAM_SPD_DATA_SIZE;
+ printf("Error: VPD EEPROM 0x%x corrupt @ 0x%x\n", dev_addr, offset);
+
+ return 0;
+ }
+
+ /* Check Length */
+ if (vpd->header.size> VPD_MAX_EEPROM_SIZE) {
+ printf("Error: VPD EEPROM 0x%x contains bad size 0x%x\n",
+ dev_addr, vpd->header.size);
+ return 0;
+ }
+
+ /* Now find the termination packet */
+ if ((packet = vpd_find_packet(vpd, VPD_PID_TERM)) == NULL) {
+ printf("Error: VPD EEPROM 0x%x missing termination packet\n",
+ dev_addr);
+ return 0;
+ }
+
+ /* Calculate data size */
+ num_bytes = (unsigned long)((unsigned char *)packet -
+ (unsigned char *)vpd + sizeof(vpd_packet_t));
+
+ /* Find stored CRC and clear it */
+ if ((packet = vpd_find_packet(vpd, VPD_PID_CRC)) == NULL) {
+ printf("Error: VPD EEPROM 0x%x missing CRC\n", dev_addr);
+ return 0;
+ }
+ stored_crc16 = *((ushort *)packet->data);
+ *(ushort *)packet->data = 0;
+
+ /* OK, lets calculate the CRC and check it */
+#if defined(VXWORKS)
+ calc_crc16 = (0xffff & crc32(buf, num_bytes));
+#else
+ calc_crc16 = (0xffff & crc32(0, buf, num_bytes));
+#endif
+ *(ushort *)packet->data = stored_crc16; /* Now restore the CRC */
+ if (stored_crc16 != calc_crc16) {
+ printf("Error: VPD EEPROM 0x%x has bad CRC 0x%x\n",
+ dev_addr, stored_crc16);
+ return 0;
+ }
+
+ return 1;
+} /* vpd_is_valid() */
+
+
+/*
+ * size_ok() - Check to see if packet size matches
+ * size of data we want. Returns 1 for
+ * good match or 0 for failure.
+ */
+static int size_ok(vpd_packet_t *packet, unsigned long size)
+{
+ if (packet->size != size) {
+ printf("VPD Packet 0x%x corrupt.\n", packet->identifier);
+ return 0;
+ }
+ return 1;
+} /* size_ok() */
+
+
+/*
+ * strlen_ok() - Check to see if packet size matches
+ * strlen of the string we want to populate.
+ * Returns 1 for valid length or 0 for failure.
+ */
+static int strlen_ok(vpd_packet_t *packet, unsigned long length)
+{
+ if (packet->size >= length) {
+ printf("VPD Packet 0x%x corrupt.\n", packet->identifier);
+ return 0;
+ }
+ return 1;
+} /* strlen_ok() */
+
+
+/*
+ * get_vpd_data() - populates the passed VPD structure 'vpdInfo'
+ * with data obtained from the specified
+ * I2C EEPROM 'dev_addr'. Returns 0 for
+ * success or 1 for failure.
+ */
+int vpd_get_data(unsigned char dev_addr, VPD *vpdInfo)
+{
+ unsigned char buf[VPD_EEPROM_SIZE];
+ vpd_t *vpd = (vpd_t *)buf;
+ vpd_packet_t *packet;
+
+ if (vpdInfo == NULL)
+ return 1;
+
+ /*
+ * Fill vpdInfo with 0s to blank out
+ * unused fields, fill vpdInfo->ethAddrs
+ * with all 0xffs so that other's code can
+ * determine how many real Ethernet addresses
+ * there are. OUIs starting with 0xff are
+ * broadcast addresses, and would never be
+ * permantely stored.
+ */
+ memset((void *)vpdInfo, 0, sizeof(VPD));
+ memset((void *)&vpdInfo->ethAddrs, 0xff, sizeof(vpdInfo->ethAddrs));
+ vpdInfo->_devAddr = dev_addr;
+
+ /* Read the minimum size first */
+ if (vpd_reader(buf, dev_addr, 0, VPD_EEPROM_SIZE) == NULL) {
+ return 1;
+ }
+
+ /* Check validity of VPD data */
+ if (!vpd_is_valid(dev_addr, buf)) {
+ printf("VPD Data is INVALID!\n");
+ return 1;
+ }
+
+ /*
+ * Walk all the packets and populate
+ * the VPD info structure.
+ */
+ packet = (vpd_packet_t *)&vpd->packets;
+ do {
+ switch (packet->identifier) {
+ case VPD_PID_GI:
+ printf("Error: Illegal VPD value\n");
+ break;
+ case VPD_PID_PID:
+ if (strlen_ok(packet, MAX_PROD_ID)) {
+ strncpy(vpdInfo->productId,
+ packet->data, packet->size);
+ }
+ break;
+ case VPD_PID_REV:
+ if (size_ok(packet, sizeof(char)))
+ vpdInfo->revisionId = *packet->data;
+ break;
+ case VPD_PID_SN:
+ if (size_ok(packet, sizeof(unsigned long))) {
+ vpdInfo->serialNum =
+ *(unsigned long *)packet->data;
+ }
+ break;
+ case VPD_PID_MANID:
+ if (size_ok(packet, sizeof(unsigned char)))
+ vpdInfo->manuID = *packet->data;
+ break;
+ case VPD_PID_PCO:
+ if (size_ok(packet, sizeof(unsigned long))) {
+ vpdInfo->configOpt =
+ *(unsigned long *)packet->data;
+ }
+ break;
+ case VPD_PID_SYSCLK:
+ if (size_ok(packet, sizeof(unsigned long)))
+ vpdInfo->sysClk = *(unsigned long *)packet->data;
+ break;
+ case VPD_PID_SERCLK:
+ if (size_ok(packet, sizeof(unsigned long)))
+ vpdInfo->serClk = *(unsigned long *)packet->data;
+ break;
+ case VPD_PID_FLASH:
+ if (size_ok(packet, 9)) { /* XXX - hardcoded,
+ padding in struct */
+ memcpy(&vpdInfo->flashCfg, packet->data, 9);
+ }
+ break;
+ case VPD_PID_ETHADDR:
+ memcpy(vpdInfo->ethAddrs, packet->data, packet->size);
+ break;
+ case VPD_PID_POTS:
+ if (size_ok(packet, sizeof(char)))
+ vpdInfo->numPOTS = (unsigned)*packet->data;
+ break;
+ case VPD_PID_DS1:
+ if (size_ok(packet, sizeof(char)))
+ vpdInfo->numDS1 = (unsigned)*packet->data;
+ case VPD_PID_GAL:
+ case VPD_PID_CRC:
+ case VPD_PID_TERM:
+ break;
+ default:
+ printf("Warning: Found unknown VPD packet ID 0x%x\n",
+ packet->identifier);
+ break;
+ }
+ } while ((packet = vpd_get_packet(packet)));
+
+ return 0;
+} /* end get_vpd_data() */
+
+
+/*
+ * vpd_init() - Initialize default VPD environment
+ */
+int vpd_init(unsigned char dev_addr)
+{
+ return (0);
+} /* vpd_init() */
+
+
+/*
+ * vpd_print() - Pretty print the VPD data.
+ */
+void vpd_print(VPD *vpdInfo)
+{
+ const char *const sp = "";
+ const char *const sfmt = "%4s%-20s: \"%s\"\n";
+ const char *const cfmt = "%4s%-20s: '%c'\n";
+ const char *const dfmt = "%4s%-20s: %ld\n";
+ const char *const hfmt = "%4s%-20s: %08lX\n";
+ const char *const dsfmt = "%4s%-20s: %d\n";
+ const char *const hsfmt = "%4s%-20s: %04X\n";
+ const char *const dhfmt = "%4s%-20s: %ld (%lX)\n";
+
+ printf("VPD read from I2C device: %02X\n", vpdInfo->_devAddr);
+
+ if (vpdInfo->productId[0])
+ printf(sfmt, sp, "Product ID", vpdInfo->productId);
+ else
+ printf(sfmt, sp, "Product ID", "UNKNOWN");
+
+ if (vpdInfo->revisionId)
+ printf(cfmt, sp, "Revision ID", vpdInfo->revisionId);
+
+ if (vpdInfo->serialNum)
+ printf(dfmt, sp, "Serial Number", vpdInfo->serialNum);
+
+ if (vpdInfo->manuID)
+ printf(dfmt, sp, "Manufacture ID", (long)vpdInfo->manuID);
+
+ if (vpdInfo->configOpt)
+ printf(hfmt, sp, "Configuration", vpdInfo->configOpt);
+
+ if (vpdInfo->sysClk)
+ printf(dhfmt, sp, "System Clock", vpdInfo->sysClk, vpdInfo->sysClk);
+
+ if (vpdInfo->serClk)
+ printf(dhfmt, sp, "Serial Clock", vpdInfo->serClk, vpdInfo->serClk);
+
+ if (vpdInfo->numPOTS)
+ printf(dfmt, sp, "Number of POTS lines", vpdInfo->numPOTS);
+
+ if (vpdInfo->numDS1)
+ printf(dfmt, sp, "Number of DS1s", vpdInfo->numDS1);
+
+ /* Print Ethernet Addresses */
+ if (vpdInfo->ethAddrs[0][0] != 0xff) {
+ int i, j;
+ printf("%4sEtherNet Address(es): ", sp);
+ for (i = 0; i < MAX_ETH_ADDRS; i++) {
+ if (vpdInfo->ethAddrs[i][0] != 0xff) {
+ for (j = 0; j < 6; j++) {
+ printf("%02X", vpdInfo->ethAddrs[i][j]);
+ if (((j + 1) % 6) != 0)
+ printf(":");
+ else
+ printf(" ");
+ }
+ if (((i + 1) % 3) == 0) printf("\n%24s: ", sp);
+ }
+ }
+ printf("\n");
+ }
+
+ if (vpdInfo->flashCfg.mfg && vpdInfo->flashCfg.dev) {
+ printf("Main Flash Configuration:\n");
+ printf(hsfmt, sp, "Manufacture ID", vpdInfo->flashCfg.mfg);
+ printf(hsfmt, sp, "Device ID", vpdInfo->flashCfg.dev);
+ printf(dsfmt, sp, "Device Width", vpdInfo->flashCfg.devWidth);
+ printf(dsfmt, sp, "Num. Devices", vpdInfo->flashCfg.numDevs);
+ printf(dsfmt, sp, "Num. Columns", vpdInfo->flashCfg.numCols);
+ printf(dsfmt, sp, "Column Width", vpdInfo->flashCfg.colWidth);
+ printf(dsfmt, sp, "WE Data Width", vpdInfo->flashCfg.weDataWidth);
+ }
+} /* vpd_print() */
+
--- /dev/null
+/*
+ * (C) Copyright 2001
+ * Erik Theisen, Wave 7 Optics, etheisen@mindspring.com.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef _VPD_H_
+#define _VPD_H_
+
+/*
+ * Main Flash Configuration.
+ */
+typedef struct flashCfg_s {
+ unsigned short mfg; /* Manufacture ID */
+ unsigned short dev; /* Device ID */
+ unsigned char devWidth; /* Device Width */
+ unsigned char numDevs; /* Number of devices */
+ unsigned char numCols; /* Number of columns */
+ unsigned char colWidth; /* Width of a column */
+ unsigned char weDataWidth; /* Write/Erase Data Width */
+} flashCfg_t;
+
+/*
+ * Vital Product Data - VPD
+ */
+#define MAX_PROD_ID 15
+#define MAX_ETH_ADDRS 10
+typedef unsigned char EthAddr[6];
+typedef struct vpd {
+ unsigned char _devAddr; /* Device address during read */
+ char productId[MAX_PROD_ID]; /* Product ID */
+ char revisionId; /* Revision ID as a char */
+ unsigned long serialNum; /* Serial number */
+ unsigned char manuID; /* Manufact ID - byte int */
+ unsigned long configOpt; /* Config Option - bit field */
+ unsigned long sysClk; /* System clock in Hertz */
+ unsigned long serClk; /* Ext. clock in Hertz */
+ flashCfg_t flashCfg; /* Flash configuration */
+ unsigned long numPOTS; /* Number of POTS lines */
+ unsigned long numDS1; /* Number of DS1 circuits */
+ EthAddr ethAddrs[MAX_ETH_ADDRS]; /* Ethernet MAC, 1st = craft */
+} VPD;
+
+
+#define VPD_MAX_EEPROM_SIZE 512 /* Max size VPD EEPROM */
+#define SDRAM_SPD_DATA_SIZE 128 /* Size SPD in VPD EEPROM */
+
+/*
+ * PIDs - Packet Identifiers
+ */
+#define VPD_PID_GI 0x0 /* Guaranted Illegal */
+#define VPD_PID_PID 0x1 /* Product Identifier */
+#define VPD_PID_REV 0x2 /* Product Revision */
+#define VPD_PID_SN 0x3 /* Serial Number */
+#define VPD_PID_MANID 0x4 /* Manufacture ID */
+#define VPD_PID_PCO 0x5 /* Product configuration */
+#define VPD_PID_SYSCLK 0x6 /* System Clock */
+#define VPD_PID_SERCLK 0x7 /* Ser. Clk. Speed in Hertz */
+#define VPD_PID_CRC 0x8 /* VPD CRC */
+#define VPD_PID_FLASH 0x9 /* Flash Configuration */
+#define VPD_PID_ETHADDR 0xA /* Ethernet Address(es) */
+#define VPD_PID_GAL 0xB /* Galileo Switch Config */
+#define VPD_PID_POTS 0xC /* Number of POTS Lines */
+#define VPD_PID_DS1 0xD /* Number of DS1s */
+#define VPD_PID_TERM 0xFF /* Termination packet */
+
+/*
+ * VPD - Eyecatcher/Magic
+ */
+#define VPD_EYECATCHER "W7O"
+#define VPD_EYE_SIZE 3
+typedef struct vpd_header {
+ unsigned char eyecatcher[VPD_EYE_SIZE]; /* eyecatcher - "W7O" */
+ unsigned short size __attribute__((packed)); /* size of EEPROM */
+} vpd_header_t;
+
+
+#define VPD_DATA_SIZE (VPD_MAX_EEPROM_SIZE - SDRAM_SPD_DATA_SIZE - \
+ sizeof(vpd_header_t))
+typedef struct vpd_s {
+ vpd_header_t header;
+ unsigned char packets[VPD_DATA_SIZE];
+} vpd_t;
+
+typedef struct vpd_packet {
+ unsigned char identifier;
+ unsigned char size;
+ unsigned char data[1];
+} vpd_packet_t;
+
+/*
+ * VPD configOpt bit mask
+ */
+#define VPD_HAS_BBRAM 0x1 /* Battery backed SRAM */
+#define VPD_HAS_RTC 0x2 /* Battery backed RTC */
+#define VPD_HAS_EXT_SER_CLK 0x4 /* External serial clock */
+#define VPD_HAS_SER_TRANS_1 0x8 /* COM1 transceiver */
+#define VPD_HAS_SER_TRANS_2 0x10 /* COM2 transceiver */
+#define VPD_HAS_CRAFT_PHY 0x20 /* CRAFT Ethernet */
+#define VPD_HAS_DTT_1 0x40 /* I2C Digital therm. #1 */
+#define VPD_HAS_DTT_2 0x80 /* I2C Digital therm. #2 */
+#define VPD_HAS_1000_UP_LASER 0x100 /* GMM - 1000Mbit Uplink */
+#define VPD_HAS_70KM_UP_LASER 0x200 /* CMM - 70KM Uplink laser */
+#define VPD_HAS_2_UPLINKS 0x400 /* CMM - 2 uplink lasers */
+#define VPD_HAS_FPGA 0x800 /* Has 1 or more FPGAs */
+#define VPD_HAS_DFA 0x1000 /* CLM - Has 2 Fiber Inter. */
+#define VPD_HAS_GAL_SWITCH 0x2000 /* GMM - Has a Gal switch */
+#define VPD_HAS_POTS_LINES 0x4000 /* GMM - Has POTS lines */
+#define VPD_HAS_DS1_CHANNELS 0x8000 /* GMM - Has DS1 channels */
+#define VPD_HAS_CABLE_RETURN 0x10000 /* GBM/GBR - Cable ret. path */
+
+#define VPD_EEPROM_SIZE (256 - SDRAM_SPD_DATA_SIZE) /* Size EEPROM */
+
+extern int vpd_get_data(unsigned char dev_addr, VPD *vpd);
+extern void vpd_print(VPD *vpdInfo);
+
+#endif /* _VPD_H_ */
+
--- /dev/null
+/*
+ * (C) Copyright 2001
+ * Erik Theisen, Wave 7 Optics, etheisen@mindspring.com.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include "w7o.h"
+#include <asm/processor.h>
+
+#include "vpd.h"
+#include "errors.h"
+#include <watchdog.h>
+
+unsigned long get_dram_size(void);
+
+/*
+ * Macros to transform values
+ * into environment strings.
+ */
+#define XMK_STR(x) #x
+#define MK_STR(x) XMK_STR(x)
+
+/* ------------------------------------------------------------------------- */
+
+int board_pre_init (void)
+{
+#if defined(CONFIG_W7OLMG)
+ /*
+ * Setup GPIO pins - reset devices.
+ */
+ out32(IBM405GP_GPIO0_ODR, 0x10000000); /* one open drain pin */
+ out32(IBM405GP_GPIO0_OR, 0x3E000000); /* set output pins to default */
+ out32(IBM405GP_GPIO0_TCR, 0x7f800000); /* setup for output */
+
+ /*
+ * IRQ 0-15 405GP internally generated; active high; level sensitive
+ * IRQ 16 405GP internally generated; active low; level sensitive
+ * IRQ 17-24 RESERVED
+ * IRQ 25 (EXT IRQ 0) XILINX; active low; level sensitive
+ * IRQ 26 (EXT IRQ 1) PCI INT A; active low; level sensitive
+ * IRQ 27 (EXT IRQ 2) PCI INT B; active low; level sensitive
+ * IRQ 28 (EXT IRQ 3) SAM 2; active low; level sensitive
+ * IRQ 29 (EXT IRQ 4) Battery Bad; active low; level sensitive
+ * IRQ 30 (EXT IRQ 5) Level One PHY; active low; level sensitive
+ * IRQ 31 (EXT IRQ 6) SAM 1; active high; level sensitive
+ */
+ mtdcr(uicsr, 0xFFFFFFFF); /* clear all ints */
+ mtdcr(uicer, 0x00000000); /* disable all ints */
+
+ mtdcr(uiccr, 0x00000000); /* set all to be non-critical*/
+ mtdcr(uicpr, 0xFFFFFF80); /* set int polarities */
+ mtdcr(uictr, 0x10000000); /* set int trigger levels */
+ mtdcr(uicvcr, 0x00000001); /* set vect base=0,
+ INT0 highest priority*/
+
+ mtdcr(uicsr, 0xFFFFFFFF); /* clear all ints */
+
+#elif defined(CONFIG_W7OLMC)
+ /*
+ * Setup GPIO pins
+ */
+ out32(IBM405GP_GPIO0_ODR, 0x01800000); /* XCV Done Open Drain */
+ out32(IBM405GP_GPIO0_OR, 0x03800000); /* set out pins to default */
+ out32(IBM405GP_GPIO0_TCR, 0x66C00000); /* setup for output */
+
+ /*
+ * IRQ 0-15 405GP internally generated; active high; level sensitive
+ * IRQ 16 405GP internally generated; active low; level sensitive
+ * IRQ 17-24 RESERVED
+ * IRQ 25 (EXT IRQ 0) DBE 0; active low; level sensitive
+ * IRQ 26 (EXT IRQ 1) DBE 1; active low; level sensitive
+ * IRQ 27 (EXT IRQ 2) DBE 2; active low; level sensitive
+ * IRQ 28 (EXT IRQ 3) DBE Common; active low; level sensitive
+ * IRQ 29 (EXT IRQ 4) PCI; active low; level sensitive
+ * IRQ 30 (EXT IRQ 5) RCMM Reset; active low; level sensitive
+ * IRQ 31 (EXT IRQ 6) PHY; active high; level sensitive
+ */
+ mtdcr(uicsr, 0xFFFFFFFF); /* clear all ints */
+ mtdcr(uicer, 0x00000000); /* disable all ints */
+
+ mtdcr(uiccr, 0x00000000); /* set all to be non-critical*/
+ mtdcr(uicpr, 0xFFFFFF80); /* set int polarities */
+ mtdcr(uictr, 0x10000000); /* set int trigger levels */
+ mtdcr(uicvcr, 0x00000001); /* set vect base=0,
+ INT0 highest priority*/
+
+ mtdcr(uicsr, 0xFFFFFFFF); /* clear all ints */
+
+#else /* Unknown */
+# error "Unknown W7O board configuration"
+#endif
+
+ WATCHDOG_RESET(); /* Reset the watchdog */
+ temp_uart_init(); /* init the uart for debug */
+ WATCHDOG_RESET(); /* Reset the watchdog */
+ test_led(); /* test the LEDs */
+ test_sdram(get_dram_size()); /* test the dram */
+ log_stat(ERR_POST1); /* log status,post1 complete */
+ return 0;
+}
+
+
+/* ------------------------------------------------------------------------- */
+
+/*
+ * Check Board Identity:
+ */
+int checkboard (void)
+{
+ VPD vpd;
+
+ puts ("Board: ");
+
+ /* VPD data present in I2C EEPROM */
+ if (vpd_get_data(CFG_DEF_EEPROM_ADDR, &vpd) == 0) {
+ /*
+ * Known board type.
+ */
+ if (vpd.productId[0] &&
+ ((strncmp(vpd.productId, "GMM", 3) == 0) ||
+ (strncmp(vpd.productId, "CMM", 3) == 0))) {
+
+ /* Output board information on startup */
+ printf("\"%s\", revision '%c', serial# %ld, manufacturer %u\n",
+ vpd.productId, vpd.revisionId, vpd.serialNum, vpd.manuID);
+ return (0);
+ }
+ }
+
+ puts ("### Unknown HW ID - assuming NOTHING\n");
+ return (0);
+}
+
+/* ------------------------------------------------------------------------- */
+
+long int initdram (int board_type)
+{
+ return get_dram_size();
+}
+
+unsigned long get_dram_size (void)
+{
+ int tmp, i, regs[4];
+ int size = 0;
+
+ /* Get bank Size registers */
+ mtdcr(memcfga, mem_mb0cf); /* get bank 0 config reg */
+ regs[0] = mfdcr(memcfgd);
+
+ mtdcr(memcfga, mem_mb1cf); /* get bank 1 config reg */
+ regs[1] = mfdcr(memcfgd);
+
+ mtdcr(memcfga, mem_mb2cf); /* get bank 2 config reg */
+ regs[2] = mfdcr(memcfgd);
+
+ mtdcr(memcfga, mem_mb3cf); /* get bank 3 config reg */
+ regs[3] = mfdcr(memcfgd);
+
+ /* compute the size, add each bank if enabled */
+ for(i = 0; i < 4; i++) {
+ if (regs[i] & 0x0001) { /* if enabled, */
+ tmp = ((regs[i] >> (31 - 14)) & 0x7); /* get size bits */
+ tmp = 0x400000 << tmp; /* Size bits X 4MB = size */
+ size += tmp;
+ }
+ }
+
+ return size;
+}
+
+int misc_init_f (void)
+{
+ return 0;
+}
+
+static void
+w7o_env_init(VPD *vpd)
+{
+ /*
+ * Read VPD
+ */
+ if (vpd_get_data(CFG_DEF_EEPROM_ADDR, vpd) != 0)
+ return;
+
+ /*
+ * Known board type.
+ */
+ if (vpd->productId[0] &&
+ ((strncmp(vpd->productId, "GMM", 3) == 0) ||
+ (strncmp(vpd->productId, "CMM", 3) == 0))) {
+ char buf[30];
+ char *eth;
+ unsigned char *serial = getenv("serial#");
+ unsigned char *ethaddr = getenv("ethaddr");
+
+ /* Set 'serial#' envvar if serial# isn't set */
+ if (!serial) {
+ sprintf(buf, "%s-%ld", vpd->productId, vpd->serialNum);
+ setenv("serial#", buf);
+ }
+
+ /* Set 'ethaddr' envvar if 'ethaddr' envvar is the default */
+ eth = vpd->ethAddrs[0];
+ if (ethaddr && (strcmp(ethaddr, MK_STR(CONFIG_ETHADDR)) == 0)) {
+ /* Now setup ethaddr */
+ sprintf(buf, "%02x:%02x:%02x:%02x:%02x:%02x",
+ eth[0], eth[1], eth[2], eth[3], eth[4], eth[5]);
+ setenv("ethaddr", buf);
+ }
+ }
+} /* w7o_env_init() */
+
+
+int misc_init_r (void)
+{
+ VPD vpd; /* VPD information */
+
+#if defined(CONFIG_W7OLMG)
+ unsigned long greg; /* GPIO Register */
+
+ greg = in32(IBM405GP_GPIO0_OR);
+
+ /*
+ * XXX - Unreset devices - this should be moved into VxWorks driver code
+ */
+ greg |= 0x41800000L; /* SAM, PHY, Galileo */
+
+ out32(IBM405GP_GPIO0_OR, greg); /* set output pins to default */
+#endif /* CONFIG_W7OLMG */
+
+ /*
+ * Initialize W7O environment variables
+ */
+ w7o_env_init(&vpd);
+
+ /*
+ * Initialize the FPGA(s).
+ */
+ if (init_fpga() == 0)
+ test_fpga((unsigned short *)CONFIG_FPGAS_BASE);
+
+ /* More POST testing. */
+ post2();
+
+ /* Done with hardware initialization and POST. */
+ log_stat(ERR_POSTOK);
+
+ /* Call silly, fail safe boot init routine */
+ init_fsboot();
+
+ return (0);
+}
+
--- /dev/null
+/*
+ * Driver for Disk-On-Chip 2000 and Millennium
+ * (c) 1999 Machine Vision Holdings, Inc.
+ * (c) 1999, 2000 David Woodhouse <dwmw2@infradead.org>
+ *
+ * $Id: doc2000.c,v 1.46 2001/10/02 15:05:13 dwmw2 Exp $
+ */
+
+#include <common.h>
+#include <config.h>
+#include <command.h>
+#include <malloc.h>
+#include <asm/io.h>
+
+#ifdef CONFIG_SHOW_BOOT_PROGRESS
+# include <status_led.h>
+# define SHOW_BOOT_PROGRESS(arg) show_boot_progress(arg)
+#else
+# define SHOW_BOOT_PROGRESS(arg)
+#endif
+
+#if (CONFIG_COMMANDS & CFG_CMD_DOC)
+
+#include <linux/mtd/nand.h>
+#include <linux/mtd/nand_ids.h>
+#include <linux/mtd/doc2000.h>
+#include <linux/mtd/nftl.h>
+
+#ifdef CFG_DOC_SUPPORT_2000
+#define DoC_is_2000(doc) (doc->ChipID == DOC_ChipID_Doc2k)
+#else
+#define DoC_is_2000(doc) (0)
+#endif
+
+#ifdef CFG_DOC_SUPPORT_MILLENNIUM
+#define DoC_is_Millennium(doc) (doc->ChipID == DOC_ChipID_DocMil)
+#else
+#define DoC_is_Millennium(doc) (0)
+#endif
+
+/* CFG_DOC_PASSIVE_PROBE:
+ In order to ensure that the BIOS checksum is correct at boot time, and
+ hence that the onboard BIOS extension gets executed, the DiskOnChip
+ goes into reset mode when it is read sequentially: all registers
+ return 0xff until the chip is woken up again by writing to the
+ DOCControl register.
+
+ Unfortunately, this means that the probe for the DiskOnChip is unsafe,
+ because one of the first things it does is write to where it thinks
+ the DOCControl register should be - which may well be shared memory
+ for another device. I've had machines which lock up when this is
+ attempted. Hence the possibility to do a passive probe, which will fail
+ to detect a chip in reset mode, but is at least guaranteed not to lock
+ the machine.
+
+ If you have this problem, uncomment the following line:
+#define CFG_DOC_PASSIVE_PROBE
+*/
+
+#undef DOC_DEBUG
+#undef ECC_DEBUG
+#undef PSYCHO_DEBUG
+#undef NFTL_DEBUG
+
+static struct DiskOnChip doc_dev_desc[CFG_MAX_DOC_DEVICE];
+
+/* Current DOC Device */
+static int curr_device = -1;
+
+/* ------------------------------------------------------------------------- */
+
+int do_doc (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+ int rcode = 0;
+
+ switch (argc) {
+ case 0:
+ case 1:
+ printf ("Usage:\n%s\n", cmdtp->usage);
+ return 1;
+ case 2:
+ if (strcmp(argv[1],"info") == 0) {
+ int i;
+
+ putc ('\n');
+
+ for (i=0; i<CFG_MAX_DOC_DEVICE; ++i) {
+ if(doc_dev_desc[i].ChipID == DOC_ChipID_UNKNOWN)
+ continue; /* list only known devices */
+ printf ("Device %d: ", i);
+ doc_print(&doc_dev_desc[i]);
+ }
+ return 0;
+
+ } else if (strcmp(argv[1],"device") == 0) {
+ if ((curr_device < 0) || (curr_device >= CFG_MAX_DOC_DEVICE)) {
+ puts ("\nno devices available\n");
+ return 1;
+ }
+ printf ("\nDevice %d: ", curr_device);
+ doc_print(&doc_dev_desc[curr_device]);
+ return 0;
+ }
+ printf ("Usage:\n%s\n", cmdtp->usage);
+ return 1;
+ case 3:
+ if (strcmp(argv[1],"device") == 0) {
+ int dev = (int)simple_strtoul(argv[2], NULL, 10);
+
+ printf ("\nDevice %d: ", dev);
+ if (dev >= CFG_MAX_DOC_DEVICE) {
+ puts ("unknown device\n");
+ return 1;
+ }
+ doc_print(&doc_dev_desc[dev]);
+ /*doc_print (dev);*/
+
+ if (doc_dev_desc[dev].ChipID == DOC_ChipID_UNKNOWN) {
+ return 1;
+ }
+
+ curr_device = dev;
+
+ puts ("... is now current device\n");
+
+ return 0;
+ }
+
+ printf ("Usage:\n%s\n", cmdtp->usage);
+ return 1;
+ default:
+ /* at least 4 args */
+
+ if (strcmp(argv[1],"read") == 0 || strcmp(argv[1],"write") == 0) {
+ ulong addr = simple_strtoul(argv[2], NULL, 16);
+ ulong off = simple_strtoul(argv[3], NULL, 16);
+ ulong size = simple_strtoul(argv[4], NULL, 16);
+ int cmd = (strcmp(argv[1],"read") == 0);
+ int ret, total;
+
+ printf ("\nDOC %s: device %d offset %ld, size %ld ... ",
+ cmd ? "read" : "write", curr_device, off, size);
+
+ ret = doc_rw(doc_dev_desc + curr_device, cmd, off, size,
+ &total, (u_char*)addr);
+
+ printf ("%d bytes %s: %s\n", total, cmd ? "read" : "write",
+ ret ? "ERROR" : "OK");
+
+ return ret;
+ } else if (strcmp(argv[1],"erase") == 0) {
+ ulong off = simple_strtoul(argv[2], NULL, 16);
+ ulong size = simple_strtoul(argv[3], NULL, 16);
+ int ret;
+
+ printf ("\nDOC erase: device %d offset %ld, size %ld ... ",
+ curr_device, off, size);
+
+ ret = doc_erase (doc_dev_desc + curr_device, off, size);
+
+ printf("%s\n", ret ? "ERROR" : "OK");
+
+ return ret;
+ } else {
+ printf ("Usage:\n%s\n", cmdtp->usage);
+ rcode = 1;
+ }
+
+ return rcode;
+ }
+}
+
+int do_docboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+ char *boot_device = NULL;
+ char *ep;
+ int dev;
+ ulong cnt;
+ ulong addr;
+ ulong offset = 0;
+ image_header_t *hdr;
+ int rcode = 0;
+
+ switch (argc) {
+ case 1:
+ addr = CFG_LOAD_ADDR;
+ boot_device = getenv ("bootdevice");
+ break;
+ case 2:
+ addr = simple_strtoul(argv[1], NULL, 16);
+ boot_device = getenv ("bootdevice");
+ break;
+ case 3:
+ addr = simple_strtoul(argv[1], NULL, 16);
+ boot_device = argv[2];
+ break;
+ case 4:
+ addr = simple_strtoul(argv[1], NULL, 16);
+ boot_device = argv[2];
+ offset = simple_strtoul(argv[3], NULL, 16);
+ break;
+ default:
+ printf ("Usage:\n%s\n", cmdtp->usage);
+ SHOW_BOOT_PROGRESS (-1);
+ return 1;
+ }
+
+ if (!boot_device) {
+ puts ("\n** No boot device **\n");
+ SHOW_BOOT_PROGRESS (-1);
+ return 1;
+ }
+
+ dev = simple_strtoul(boot_device, &ep, 16);
+
+ if ((dev >= CFG_MAX_DOC_DEVICE) ||
+ (doc_dev_desc[dev].ChipID == DOC_ChipID_UNKNOWN)) {
+ printf ("\n** Device %d not available\n", dev);
+ SHOW_BOOT_PROGRESS (-1);
+ return 1;
+ }
+
+ printf ("\nLoading from device %d: %s at 0x%lX (offset 0x%lX)\n",
+ dev, doc_dev_desc[dev].name, doc_dev_desc[dev].physadr,
+ offset);
+
+ if (doc_rw (doc_dev_desc + dev, 1, offset,
+ SECTORSIZE, NULL, (u_char *)addr)) {
+ printf ("** Read error on %d\n", dev);
+ SHOW_BOOT_PROGRESS (-1);
+ return 1;
+ }
+
+ hdr = (image_header_t *)addr;
+
+ if (hdr->ih_magic == IH_MAGIC) {
+
+ print_image_hdr (hdr);
+
+ cnt = (hdr->ih_size + sizeof(image_header_t));
+ cnt -= SECTORSIZE;
+ } else {
+ puts ("\n** Bad Magic Number **\n");
+ SHOW_BOOT_PROGRESS (-1);
+ return 1;
+ }
+
+ if (doc_rw (doc_dev_desc + dev, 1, offset + SECTORSIZE, cnt,
+ NULL, (u_char *)(addr+SECTORSIZE))) {
+ printf ("** Read error on %d\n", dev);
+ SHOW_BOOT_PROGRESS (-1);
+ return 1;
+ }
+
+ /* Loading ok, update default load address */
+
+ load_addr = addr;
+
+ /* Check if we should attempt an auto-start */
+ if (((ep = getenv("autostart")) != NULL) && (strcmp(ep,"yes") == 0)) {
+ char *local_args[2];
+ extern int do_bootm (cmd_tbl_t *, int, int, char *[]);
+
+ local_args[0] = argv[0];
+ local_args[1] = NULL;
+
+ printf ("Automatic boot of image at addr 0x%08lX ...\n", addr);
+
+ do_bootm (cmdtp, 0, 1, local_args);
+ rcode = 1;
+ }
+ return rcode;
+}
+
+int doc_rw (struct DiskOnChip* this, int cmd,
+ loff_t from, size_t len,
+ size_t * retlen, u_char * buf)
+{
+ int noecc, ret = 0, n, total = 0;
+ char eccbuf[6];
+
+ while(len) {
+ /* The ECC will not be calculated correctly if
+ less than 512 is written or read */
+ noecc = (from != (from | 0x1ff) + 1) || (len < 0x200);
+
+ if (cmd)
+ ret = doc_read_ecc(this, from, len,
+ &n, (u_char*)buf,
+ noecc ? NULL : eccbuf);
+ else
+ ret = doc_write_ecc(this, from, len,
+ &n, (u_char*)buf,
+ noecc ? NULL : eccbuf);
+
+ if (ret)
+ break;
+
+ from += n;
+ buf += n;
+ total += n;
+ len -= n;
+ }
+
+ if (retlen)
+ *retlen = total;
+
+ return ret;
+}
+
+void doc_print(struct DiskOnChip *this) {
+ printf("%s at 0x%lX,\n"
+ "\t %d chip%s %s, size %d MB, \n"
+ "\t total size %ld MB, sector size %ld kB\n",
+ this->name, this->physadr, this->numchips,
+ this->numchips>1 ? "s" : "", this->chips_name,
+ 1 << (this->chipshift - 20),
+ this->totlen >> 20, this->erasesize >> 10);
+
+ if (this->nftl_found) {
+ struct NFTLrecord *nftl = &this->nftl;
+ unsigned long bin_size, flash_size;
+
+ bin_size = nftl->nb_boot_blocks * this->erasesize;
+ flash_size = (nftl->nb_blocks - nftl->nb_boot_blocks) * this->erasesize;
+
+ printf("\t NFTL boot record:\n"
+ "\t Binary partition: size %ld%s\n"
+ "\t Flash disk partition: size %ld%s, offset 0x%lx\n",
+ bin_size > (1 << 20) ? bin_size >> 20 : bin_size >> 10,
+ bin_size > (1 << 20) ? "MB" : "kB",
+ flash_size > (1 << 20) ? flash_size >> 20 : flash_size >> 10,
+ flash_size > (1 << 20) ? "MB" : "kB", bin_size);
+ } else {
+ puts ("\t No NFTL boot record found.\n");
+ }
+}
+
+/* ------------------------------------------------------------------------- */
+
+/* This function is needed to avoid calls of the __ashrdi3 function. */
+static int shr(int val, int shift) {
+ return val >> shift;
+}
+
+/* Perform the required delay cycles by reading from the appropriate register */
+static void DoC_Delay(struct DiskOnChip *doc, unsigned short cycles)
+{
+ volatile char dummy;
+ int i;
+
+ for (i = 0; i < cycles; i++) {
+ if (DoC_is_Millennium(doc))
+ dummy = ReadDOC(doc->virtadr, NOP);
+ else
+ dummy = ReadDOC(doc->virtadr, DOCStatus);
+ }
+
+}
+
+/* DOC_WaitReady: Wait for RDY line to be asserted by the flash chip */
+static int _DoC_WaitReady(struct DiskOnChip *doc)
+{
+ unsigned long docptr = doc->virtadr;
+ unsigned long start = get_timer(0);
+
+#ifdef PSYCHO_DEBUG
+ puts ("_DoC_WaitReady called for out-of-line wait\n");
+#endif
+
+ /* Out-of-line routine to wait for chip response */
+ while (!(ReadDOC(docptr, CDSNControl) & CDSN_CTRL_FR_B)) {
+#ifdef CFG_DOC_SHORT_TIMEOUT
+ /* it seems that after a certain time the DoC deasserts
+ * the CDSN_CTRL_FR_B although it is not ready...
+ * using a short timout solve this (timer increments every ms) */
+ if (get_timer(start) > 10) {
+ return DOC_ETIMEOUT;
+ }
+#else
+ if (get_timer(start) > 10 * 1000) {
+ puts ("_DoC_WaitReady timed out.\n");
+ return DOC_ETIMEOUT;
+ }
+#endif
+ udelay(1);
+ }
+
+ return 0;
+}
+
+static int DoC_WaitReady(struct DiskOnChip *doc)
+{
+ unsigned long docptr = doc->virtadr;
+ /* This is inline, to optimise the common case, where it's ready instantly */
+ int ret = 0;
+
+ /* 4 read form NOP register should be issued in prior to the read from CDSNControl
+ see Software Requirement 11.4 item 2. */
+ DoC_Delay(doc, 4);
+
+ if (!(ReadDOC(docptr, CDSNControl) & CDSN_CTRL_FR_B))
+ /* Call the out-of-line routine to wait */
+ ret = _DoC_WaitReady(doc);
+
+ /* issue 2 read from NOP register after reading from CDSNControl register
+ see Software Requirement 11.4 item 2. */
+ DoC_Delay(doc, 2);
+
+ return ret;
+}
+
+/* DoC_Command: Send a flash command to the flash chip through the CDSN Slow IO register to
+ bypass the internal pipeline. Each of 4 delay cycles (read from the NOP register) is
+ required after writing to CDSN Control register, see Software Requirement 11.4 item 3. */
+
+static inline int DoC_Command(struct DiskOnChip *doc, unsigned char command,
+ unsigned char xtraflags)
+{
+ unsigned long docptr = doc->virtadr;
+
+ if (DoC_is_2000(doc))
+ xtraflags |= CDSN_CTRL_FLASH_IO;
+
+ /* Assert the CLE (Command Latch Enable) line to the flash chip */
+ WriteDOC(xtraflags | CDSN_CTRL_CLE | CDSN_CTRL_CE, docptr, CDSNControl);
+ DoC_Delay(doc, 4); /* Software requirement 11.4.3 for Millennium */
+
+ if (DoC_is_Millennium(doc))
+ WriteDOC(command, docptr, CDSNSlowIO);
+
+ /* Send the command */
+ WriteDOC_(command, docptr, doc->ioreg);
+
+ /* Lower the CLE line */
+ WriteDOC(xtraflags | CDSN_CTRL_CE, docptr, CDSNControl);
+ DoC_Delay(doc, 4); /* Software requirement 11.4.3 for Millennium */
+
+ /* Wait for the chip to respond - Software requirement 11.4.1 (extended for any command) */
+ return DoC_WaitReady(doc);
+}
+
+/* DoC_Address: Set the current address for the flash chip through the CDSN Slow IO register to
+ bypass the internal pipeline. Each of 4 delay cycles (read from the NOP register) is
+ required after writing to CDSN Control register, see Software Requirement 11.4 item 3. */
+
+static int DoC_Address(struct DiskOnChip *doc, int numbytes, unsigned long ofs,
+ unsigned char xtraflags1, unsigned char xtraflags2)
+{
+ unsigned long docptr;
+ int i;
+
+ docptr = doc->virtadr;
+
+ if (DoC_is_2000(doc))
+ xtraflags1 |= CDSN_CTRL_FLASH_IO;
+
+ /* Assert the ALE (Address Latch Enable) line to the flash chip */
+ WriteDOC(xtraflags1 | CDSN_CTRL_ALE | CDSN_CTRL_CE, docptr, CDSNControl);
+
+ DoC_Delay(doc, 4); /* Software requirement 11.4.3 for Millennium */
+
+ /* Send the address */
+ /* Devices with 256-byte page are addressed as:
+ Column (bits 0-7), Page (bits 8-15, 16-23, 24-31)
+ * there is no device on the market with page256
+ and more than 24 bits.
+ Devices with 512-byte page are addressed as:
+ Column (bits 0-7), Page (bits 9-16, 17-24, 25-31)
+ * 25-31 is sent only if the chip support it.
+ * bit 8 changes the read command to be sent
+ (NAND_CMD_READ0 or NAND_CMD_READ1).
+ */
+
+ if (numbytes == ADDR_COLUMN || numbytes == ADDR_COLUMN_PAGE) {
+ if (DoC_is_Millennium(doc))
+ WriteDOC(ofs & 0xff, docptr, CDSNSlowIO);
+ WriteDOC_(ofs & 0xff, docptr, doc->ioreg);
+ }
+
+ if (doc->page256) {
+ ofs = ofs >> 8;
+ } else {
+ ofs = ofs >> 9;
+ }
+
+ if (numbytes == ADDR_PAGE || numbytes == ADDR_COLUMN_PAGE) {
+ for (i = 0; i < doc->pageadrlen; i++, ofs = ofs >> 8) {
+ if (DoC_is_Millennium(doc))
+ WriteDOC(ofs & 0xff, docptr, CDSNSlowIO);
+ WriteDOC_(ofs & 0xff, docptr, doc->ioreg);
+ }
+ }
+
+ DoC_Delay(doc, 2); /* Needed for some slow flash chips. mf. */
+
+ /* FIXME: The SlowIO's for millennium could be replaced by
+ a single WritePipeTerm here. mf. */
+
+ /* Lower the ALE line */
+ WriteDOC(xtraflags1 | xtraflags2 | CDSN_CTRL_CE, docptr,
+ CDSNControl);
+
+ DoC_Delay(doc, 4); /* Software requirement 11.4.3 for Millennium */
+
+ /* Wait for the chip to respond - Software requirement 11.4.1 */
+ return DoC_WaitReady(doc);
+}
+
+/* Read a buffer from DoC, taking care of Millennium odditys */
+static void DoC_ReadBuf(struct DiskOnChip *doc, u_char * buf, int len)
+{
+ volatile int dummy;
+ int modulus = 0xffff;
+ unsigned long docptr;
+ int i;
+
+ docptr = doc->virtadr;
+
+ if (len <= 0)
+ return;
+
+ if (DoC_is_Millennium(doc)) {
+ /* Read the data via the internal pipeline through CDSN IO register,
+ see Pipelined Read Operations 11.3 */
+ dummy = ReadDOC(docptr, ReadPipeInit);
+
+ /* Millennium should use the LastDataRead register - Pipeline Reads */
+ len--;
+
+ /* This is needed for correctly ECC calculation */
+ modulus = 0xff;
+ }
+
+ for (i = 0; i < len; i++)
+ buf[i] = ReadDOC_(docptr, doc->ioreg + (i & modulus));
+
+ if (DoC_is_Millennium(doc)) {
+ buf[i] = ReadDOC(docptr, LastDataRead);
+ }
+}
+
+/* Write a buffer to DoC, taking care of Millennium odditys */
+static void DoC_WriteBuf(struct DiskOnChip *doc, const u_char * buf, int len)
+{
+ unsigned long docptr;
+ int i;
+
+ docptr = doc->virtadr;
+
+ if (len <= 0)
+ return;
+
+ for (i = 0; i < len; i++)
+ WriteDOC_(buf[i], docptr, doc->ioreg + i);
+
+ if (DoC_is_Millennium(doc)) {
+ WriteDOC(0x00, docptr, WritePipeTerm);
+ }
+}
+
+
+/* DoC_SelectChip: Select a given flash chip within the current floor */
+
+static inline int DoC_SelectChip(struct DiskOnChip *doc, int chip)
+{
+ unsigned long docptr = doc->virtadr;
+
+ /* Software requirement 11.4.4 before writing DeviceSelect */
+ /* Deassert the CE line to eliminate glitches on the FCE# outputs */
+ WriteDOC(CDSN_CTRL_WP, docptr, CDSNControl);
+ DoC_Delay(doc, 4); /* Software requirement 11.4.3 for Millennium */
+
+ /* Select the individual flash chip requested */
+ WriteDOC(chip, docptr, CDSNDeviceSelect);
+ DoC_Delay(doc, 4);
+
+ /* Reassert the CE line */
+ WriteDOC(CDSN_CTRL_CE | CDSN_CTRL_FLASH_IO | CDSN_CTRL_WP, docptr,
+ CDSNControl);
+ DoC_Delay(doc, 4); /* Software requirement 11.4.3 for Millennium */
+
+ /* Wait for it to be ready */
+ return DoC_WaitReady(doc);
+}
+
+/* DoC_SelectFloor: Select a given floor (bank of flash chips) */
+
+static inline int DoC_SelectFloor(struct DiskOnChip *doc, int floor)
+{
+ unsigned long docptr = doc->virtadr;
+
+ /* Select the floor (bank) of chips required */
+ WriteDOC(floor, docptr, FloorSelect);
+
+ /* Wait for the chip to be ready */
+ return DoC_WaitReady(doc);
+}
+
+/* DoC_IdentChip: Identify a given NAND chip given {floor,chip} */
+
+static int DoC_IdentChip(struct DiskOnChip *doc, int floor, int chip)
+{
+ int mfr, id, i;
+ volatile char dummy;
+
+ /* Page in the required floor/chip */
+ DoC_SelectFloor(doc, floor);
+ DoC_SelectChip(doc, chip);
+
+ /* Reset the chip */
+ if (DoC_Command(doc, NAND_CMD_RESET, CDSN_CTRL_WP)) {
+#ifdef DOC_DEBUG
+ printf("DoC_Command (reset) for %d,%d returned true\n",
+ floor, chip);
+#endif
+ return 0;
+ }
+
+
+ /* Read the NAND chip ID: 1. Send ReadID command */
+ if (DoC_Command(doc, NAND_CMD_READID, CDSN_CTRL_WP)) {
+#ifdef DOC_DEBUG
+ printf("DoC_Command (ReadID) for %d,%d returned true\n",
+ floor, chip);
+#endif
+ return 0;
+ }
+
+ /* Read the NAND chip ID: 2. Send address byte zero */
+ DoC_Address(doc, ADDR_COLUMN, 0, CDSN_CTRL_WP, 0);
+
+ /* Read the manufacturer and device id codes from the device */
+
+ /* CDSN Slow IO register see Software Requirement 11.4 item 5. */
+ dummy = ReadDOC(doc->virtadr, CDSNSlowIO);
+ DoC_Delay(doc, 2);
+ mfr = ReadDOC_(doc->virtadr, doc->ioreg);
+
+ /* CDSN Slow IO register see Software Requirement 11.4 item 5. */
+ dummy = ReadDOC(doc->virtadr, CDSNSlowIO);
+ DoC_Delay(doc, 2);
+ id = ReadDOC_(doc->virtadr, doc->ioreg);
+
+ /* No response - return failure */
+ if (mfr == 0xff || mfr == 0)
+ return 0;
+
+ /* Check it's the same as the first chip we identified.
+ * M-Systems say that any given DiskOnChip device should only
+ * contain _one_ type of flash part, although that's not a
+ * hardware restriction. */
+ if (doc->mfr) {
+ if (doc->mfr == mfr && doc->id == id)
+ return 1; /* This is another the same the first */
+ else
+ printf("Flash chip at floor %d, chip %d is different:\n",
+ floor, chip);
+ }
+
+ /* Print and store the manufacturer and ID codes. */
+ for (i = 0; nand_flash_ids[i].name != NULL; i++) {
+ if (mfr == nand_flash_ids[i].manufacture_id &&
+ id == nand_flash_ids[i].model_id) {
+#ifdef DOC_DEBUG
+ printf("Flash chip found: Manufacturer ID: %2.2X, "
+ "Chip ID: %2.2X (%s)\n", mfr, id,
+ nand_flash_ids[i].name);
+#endif
+ if (!doc->mfr) {
+ doc->mfr = mfr;
+ doc->id = id;
+ doc->chipshift =
+ nand_flash_ids[i].chipshift;
+ doc->page256 = nand_flash_ids[i].page256;
+ doc->pageadrlen =
+ nand_flash_ids[i].pageadrlen;
+ doc->erasesize =
+ nand_flash_ids[i].erasesize;
+ doc->chips_name =
+ nand_flash_ids[i].name;
+ return 1;
+ }
+ return 0;
+ }
+ }
+
+
+#ifdef DOC_DEBUG
+ /* We haven't fully identified the chip. Print as much as we know. */
+ printf("Unknown flash chip found: %2.2X %2.2X\n",
+ id, mfr);
+#endif
+
+ return 0;
+}
+
+/* DoC_ScanChips: Find all NAND chips present in a DiskOnChip, and identify them */
+
+static void DoC_ScanChips(struct DiskOnChip *this)
+{
+ int floor, chip;
+ int numchips[MAX_FLOORS];
+ int maxchips = MAX_CHIPS;
+ int ret = 1;
+
+ this->numchips = 0;
+ this->mfr = 0;
+ this->id = 0;
+
+ if (DoC_is_Millennium(this))
+ maxchips = MAX_CHIPS_MIL;
+
+ /* For each floor, find the number of valid chips it contains */
+ for (floor = 0; floor < MAX_FLOORS; floor++) {
+ ret = 1;
+ numchips[floor] = 0;
+ for (chip = 0; chip < maxchips && ret != 0; chip++) {
+
+ ret = DoC_IdentChip(this, floor, chip);
+ if (ret) {
+ numchips[floor]++;
+ this->numchips++;
+ }
+ }
+ }
+
+ /* If there are none at all that we recognise, bail */
+ if (!this->numchips) {
+ puts ("No flash chips recognised.\n");
+ return;
+ }
+
+ /* Allocate an array to hold the information for each chip */
+ this->chips = malloc(sizeof(struct Nand) * this->numchips);
+ if (!this->chips) {
+ puts ("No memory for allocating chip info structures\n");
+ return;
+ }
+
+ ret = 0;
+
+ /* Fill out the chip array with {floor, chipno} for each
+ * detected chip in the device. */
+ for (floor = 0; floor < MAX_FLOORS; floor++) {
+ for (chip = 0; chip < numchips[floor]; chip++) {
+ this->chips[ret].floor = floor;
+ this->chips[ret].chip = chip;
+ this->chips[ret].curadr = 0;
+ this->chips[ret].curmode = 0x50;
+ ret++;
+ }
+ }
+
+ /* Calculate and print the total size of the device */
+ this->totlen = this->numchips * (1 << this->chipshift);
+
+#ifdef DOC_DEBUG
+ printf("%d flash chips found. Total DiskOnChip size: %ld MB\n",
+ this->numchips, this->totlen >> 20);
+#endif
+}
+
+/* find_boot_record: Find the NFTL Media Header and its Spare copy which contains the
+ * various device information of the NFTL partition and Bad Unit Table. Update
+ * the ReplUnitTable[] table accroding to the Bad Unit Table. ReplUnitTable[]
+ * is used for management of Erase Unit in other routines in nftl.c and nftlmount.c
+ */
+static int find_boot_record(struct NFTLrecord *nftl)
+{
+ struct nftl_uci1 h1;
+ struct nftl_oob oob;
+ unsigned int block, boot_record_count = 0;
+ int retlen;
+ u8 buf[SECTORSIZE];
+ struct NFTLMediaHeader *mh = &nftl->MediaHdr;
+ unsigned int i;
+
+ nftl->MediaUnit = BLOCK_NIL;
+ nftl->SpareMediaUnit = BLOCK_NIL;
+
+ /* search for a valid boot record */
+ for (block = 0; block < nftl->nb_blocks; block++) {
+ int ret;
+
+ /* Check for ANAND header first. Then can whinge if it's found but later
+ checks fail */
+ if ((ret = doc_read_ecc(nftl->mtd, block * nftl->EraseSize, SECTORSIZE,
+ &retlen, buf, NULL))) {
+ static int warncount = 5;
+
+ if (warncount) {
+ printf("Block read at 0x%x failed\n", block * nftl->EraseSize);
+ if (!--warncount)
+ puts ("Further failures for this block will not be printed\n");
+ }
+ continue;
+ }
+
+ if (retlen < 6 || memcmp(buf, "ANAND", 6)) {
+ /* ANAND\0 not found. Continue */
+#ifdef PSYCHO_DEBUG
+ printf("ANAND header not found at 0x%x\n", block * nftl->EraseSize);
+#endif
+ continue;
+ }
+
+#ifdef NFTL_DEBUG
+ printf("ANAND header found at 0x%x\n", block * nftl->EraseSize);
+#endif
+
+ /* To be safer with BIOS, also use erase mark as discriminant */
+ if ((ret = doc_read_oob(nftl->mtd, block * nftl->EraseSize + SECTORSIZE + 8,
+ 8, &retlen, (char *)&h1) < 0)) {
+#ifdef NFTL_DEBUG
+ printf("ANAND header found at 0x%x, but OOB data read failed\n",
+ block * nftl->EraseSize);
+#endif
+ continue;
+ }
+
+ /* OK, we like it. */
+
+ if (boot_record_count) {
+ /* We've already processed one. So we just check if
+ this one is the same as the first one we found */
+ if (memcmp(mh, buf, sizeof(struct NFTLMediaHeader))) {
+#ifdef NFTL_DEBUG
+ printf("NFTL Media Headers at 0x%x and 0x%x disagree.\n",
+ nftl->MediaUnit * nftl->EraseSize, block * nftl->EraseSize);
+#endif
+ /* if (debug) Print both side by side */
+ return -1;
+ }
+ if (boot_record_count == 1)
+ nftl->SpareMediaUnit = block;
+
+ boot_record_count++;
+ continue;
+ }
+
+ /* This is the first we've seen. Copy the media header structure into place */
+ memcpy(mh, buf, sizeof(struct NFTLMediaHeader));
+
+ /* Do some sanity checks on it */
+ if (mh->UnitSizeFactor != 0xff) {
+ puts ("Sorry, we don't support UnitSizeFactor "
+ "of != 1 yet.\n");
+ return -1;
+ }
+
+ nftl->nb_boot_blocks = le16_to_cpu(mh->FirstPhysicalEUN);
+ if ((nftl->nb_boot_blocks + 2) >= nftl->nb_blocks) {
+ printf ("NFTL Media Header sanity check failed:\n"
+ "nb_boot_blocks (%d) + 2 > nb_blocks (%d)\n",
+ nftl->nb_boot_blocks, nftl->nb_blocks);
+ return -1;
+ }
+
+ nftl->numvunits = le32_to_cpu(mh->FormattedSize) / nftl->EraseSize;
+ if (nftl->numvunits > (nftl->nb_blocks - nftl->nb_boot_blocks - 2)) {
+ printf ("NFTL Media Header sanity check failed:\n"
+ "numvunits (%d) > nb_blocks (%d) - nb_boot_blocks(%d) - 2\n",
+ nftl->numvunits,
+ nftl->nb_blocks,
+ nftl->nb_boot_blocks);
+ return -1;
+ }
+
+ nftl->nr_sects = nftl->numvunits * (nftl->EraseSize / SECTORSIZE);
+
+ /* If we're not using the last sectors in the device for some reason,
+ reduce nb_blocks accordingly so we forget they're there */
+ nftl->nb_blocks = le16_to_cpu(mh->NumEraseUnits) + le16_to_cpu(mh->FirstPhysicalEUN);
+
+ /* read the Bad Erase Unit Table and modify ReplUnitTable[] accordingly */
+ for (i = 0; i < nftl->nb_blocks; i++) {
+ if ((i & (SECTORSIZE - 1)) == 0) {
+ /* read one sector for every SECTORSIZE of blocks */
+ if ((ret = doc_read_ecc(nftl->mtd, block * nftl->EraseSize +
+ i + SECTORSIZE, SECTORSIZE,
+ &retlen, buf, (char *)&oob)) < 0) {
+ puts ("Read of bad sector table failed\n");
+ return -1;
+ }
+ }
+ /* mark the Bad Erase Unit as RESERVED in ReplUnitTable */
+ if (buf[i & (SECTORSIZE - 1)] != 0xff)
+ nftl->ReplUnitTable[i] = BLOCK_RESERVED;
+ }
+
+ nftl->MediaUnit = block;
+ boot_record_count++;
+
+ } /* foreach (block) */
+
+ return boot_record_count?0:-1;
+}
+
+/* This routine is made available to other mtd code via
+ * inter_module_register. It must only be accessed through
+ * inter_module_get which will bump the use count of this module. The
+ * addresses passed back in mtd are valid as long as the use count of
+ * this module is non-zero, i.e. between inter_module_get and
+ * inter_module_put. Keith Owens <kaos@ocs.com.au> 29 Oct 2000.
+ */
+static void DoC2k_init(struct DiskOnChip* this)
+{
+ struct NFTLrecord *nftl;
+
+ switch (this->ChipID) {
+ case DOC_ChipID_Doc2k:
+ this->name = "DiskOnChip 2000";
+ this->ioreg = DoC_2k_CDSN_IO;
+ break;
+ case DOC_ChipID_DocMil:
+ this->name = "DiskOnChip Millennium";
+ this->ioreg = DoC_Mil_CDSN_IO;
+ break;
+ }
+
+#ifdef DOC_DEBUG
+ printf("%s found at address 0x%lX\n", this->name,
+ this->physadr);
+#endif
+
+ this->totlen = 0;
+ this->numchips = 0;
+
+ this->curfloor = -1;
+ this->curchip = -1;
+
+ /* Ident all the chips present. */
+ DoC_ScanChips(this);
+
+ nftl = &this->nftl;
+
+ /* Get physical parameters */
+ nftl->EraseSize = this->erasesize;
+ nftl->nb_blocks = this->totlen / this->erasesize;
+ nftl->mtd = this;
+
+ if (find_boot_record(nftl) != 0)
+ this->nftl_found = 0;
+ else
+ this->nftl_found = 1;
+
+ printf("%s @ 0x%lX, %ld MB\n", this->name, this->physadr, this->totlen >> 20);
+}
+
+int doc_read_ecc(struct DiskOnChip* this, loff_t from, size_t len,
+ size_t * retlen, u_char * buf, u_char * eccbuf)
+{
+ unsigned long docptr;
+ struct Nand *mychip;
+ unsigned char syndrome[6];
+ volatile char dummy;
+ int i, len256 = 0, ret=0;
+
+ docptr = this->virtadr;
+
+ /* Don't allow read past end of device */
+ if (from >= this->totlen) {
+ puts ("Out of flash\n");
+ return DOC_EINVAL;
+ }
+
+ /* Don't allow a single read to cross a 512-byte block boundary */
+ if (from + len > ((from | 0x1ff) + 1))
+ len = ((from | 0x1ff) + 1) - from;
+
+ /* The ECC will not be calculated correctly if less than 512 is read */
+ if (len != 0x200 && eccbuf)
+ printf("ECC needs a full sector read (adr: %lx size %lx)\n",
+ (long) from, (long) len);
+
+#ifdef PHYCH_DEBUG
+ printf("DoC_Read (adr: %lx size %lx)\n", (long) from, (long) len);
+#endif
+
+ /* Find the chip which is to be used and select it */
+ mychip = &this->chips[shr(from, this->chipshift)];
+
+ if (this->curfloor != mychip->floor) {
+ DoC_SelectFloor(this, mychip->floor);
+ DoC_SelectChip(this, mychip->chip);
+ } else if (this->curchip != mychip->chip) {
+ DoC_SelectChip(this, mychip->chip);
+ }
+
+ this->curfloor = mychip->floor;
+ this->curchip = mychip->chip;
+
+ DoC_Command(this,
+ (!this->page256
+ && (from & 0x100)) ? NAND_CMD_READ1 : NAND_CMD_READ0,
+ CDSN_CTRL_WP);
+ DoC_Address(this, ADDR_COLUMN_PAGE, from, CDSN_CTRL_WP,
+ CDSN_CTRL_ECC_IO);
+
+ if (eccbuf) {
+ /* Prime the ECC engine */
+ WriteDOC(DOC_ECC_RESET, docptr, ECCConf);
+ WriteDOC(DOC_ECC_EN, docptr, ECCConf);
+ } else {
+ /* disable the ECC engine */
+ WriteDOC(DOC_ECC_RESET, docptr, ECCConf);
+ WriteDOC(DOC_ECC_DIS, docptr, ECCConf);
+ }
+
+ /* treat crossing 256-byte sector for 2M x 8bits devices */
+ if (this->page256 && from + len > (from | 0xff) + 1) {
+ len256 = (from | 0xff) + 1 - from;
+ DoC_ReadBuf(this, buf, len256);
+
+ DoC_Command(this, NAND_CMD_READ0, CDSN_CTRL_WP);
+ DoC_Address(this, ADDR_COLUMN_PAGE, from + len256,
+ CDSN_CTRL_WP, CDSN_CTRL_ECC_IO);
+ }
+
+ DoC_ReadBuf(this, &buf[len256], len - len256);
+
+ /* Let the caller know we completed it */
+ *retlen = len;
+
+ if (eccbuf) {
+ /* Read the ECC data through the DiskOnChip ECC logic */
+ /* Note: this will work even with 2M x 8bit devices as */
+ /* they have 8 bytes of OOB per 256 page. mf. */
+ DoC_ReadBuf(this, eccbuf, 6);
+
+ /* Flush the pipeline */
+ if (DoC_is_Millennium(this)) {
+ dummy = ReadDOC(docptr, ECCConf);
+ dummy = ReadDOC(docptr, ECCConf);
+ i = ReadDOC(docptr, ECCConf);
+ } else {
+ dummy = ReadDOC(docptr, 2k_ECCStatus);
+ dummy = ReadDOC(docptr, 2k_ECCStatus);
+ i = ReadDOC(docptr, 2k_ECCStatus);
+ }
+
+ /* Check the ECC Status */
+ if (i & 0x80) {
+ int nb_errors;
+ /* There was an ECC error */
+#ifdef ECC_DEBUG
+ printf("DiskOnChip ECC Error: Read at %lx\n", (long)from);
+#endif
+ /* Read the ECC syndrom through the DiskOnChip ECC logic.
+ These syndrome will be all ZERO when there is no error */
+ for (i = 0; i < 6; i++) {
+ syndrome[i] =
+ ReadDOC(docptr, ECCSyndrome0 + i);
+ }
+ nb_errors = doc_decode_ecc(buf, syndrome);
+
+#ifdef ECC_DEBUG
+ printf("Errors corrected: %x\n", nb_errors);
+#endif
+ if (nb_errors < 0) {
+ /* We return error, but have actually done the read. Not that
+ this can be told to user-space, via sys_read(), but at least
+ MTD-aware stuff can know about it by checking *retlen */
+ printf("ECC Errors at %lx\n", (long)from);
+ ret = DOC_EECC;
+ }
+ }
+
+#ifdef PSYCHO_DEBUG
+ printf("ECC DATA at %lxB: %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X\n",
+ (long)from, eccbuf[0], eccbuf[1], eccbuf[2],
+ eccbuf[3], eccbuf[4], eccbuf[5]);
+#endif
+
+ /* disable the ECC engine */
+ WriteDOC(DOC_ECC_DIS, docptr , ECCConf);
+ }
+
+ /* according to 11.4.1, we need to wait for the busy line
+ * drop if we read to the end of the page. */
+ if(0 == ((from + *retlen) & 0x1ff))
+ {
+ DoC_WaitReady(this);
+ }
+
+ return ret;
+}
+
+int doc_write_ecc(struct DiskOnChip* this, loff_t to, size_t len,
+ size_t * retlen, const u_char * buf,
+ u_char * eccbuf)
+{
+ int di; /* Yes, DI is a hangover from when I was disassembling the binary driver */
+ unsigned long docptr;
+ volatile char dummy;
+ int len256 = 0;
+ struct Nand *mychip;
+
+ docptr = this->virtadr;
+
+ /* Don't allow write past end of device */
+ if (to >= this->totlen) {
+ puts ("Out of flash\n");
+ return DOC_EINVAL;
+ }
+
+ /* Don't allow a single write to cross a 512-byte block boundary */
+ if (to + len > ((to | 0x1ff) + 1))
+ len = ((to | 0x1ff) + 1) - to;
+
+ /* The ECC will not be calculated correctly if less than 512 is written */
+ if (len != 0x200 && eccbuf)
+ printf("ECC needs a full sector write (adr: %lx size %lx)\n",
+ (long) to, (long) len);
+
+ /* printf("DoC_Write (adr: %lx size %lx)\n", (long) to, (long) len); */
+
+ /* Find the chip which is to be used and select it */
+ mychip = &this->chips[shr(to, this->chipshift)];
+
+ if (this->curfloor != mychip->floor) {
+ DoC_SelectFloor(this, mychip->floor);
+ DoC_SelectChip(this, mychip->chip);
+ } else if (this->curchip != mychip->chip) {
+ DoC_SelectChip(this, mychip->chip);
+ }
+
+ this->curfloor = mychip->floor;
+ this->curchip = mychip->chip;
+
+ /* Set device to main plane of flash */
+ DoC_Command(this, NAND_CMD_RESET, CDSN_CTRL_WP);
+ DoC_Command(this,
+ (!this->page256
+ && (to & 0x100)) ? NAND_CMD_READ1 : NAND_CMD_READ0,
+ CDSN_CTRL_WP);
+
+ DoC_Command(this, NAND_CMD_SEQIN, 0);
+ DoC_Address(this, ADDR_COLUMN_PAGE, to, 0, CDSN_CTRL_ECC_IO);
+
+ if (eccbuf) {
+ /* Prime the ECC engine */
+ WriteDOC(DOC_ECC_RESET, docptr, ECCConf);
+ WriteDOC(DOC_ECC_EN | DOC_ECC_RW, docptr, ECCConf);
+ } else {
+ /* disable the ECC engine */
+ WriteDOC(DOC_ECC_RESET, docptr, ECCConf);
+ WriteDOC(DOC_ECC_DIS, docptr, ECCConf);
+ }
+
+ /* treat crossing 256-byte sector for 2M x 8bits devices */
+ if (this->page256 && to + len > (to | 0xff) + 1) {
+ len256 = (to | 0xff) + 1 - to;
+ DoC_WriteBuf(this, buf, len256);
+
+ DoC_Command(this, NAND_CMD_PAGEPROG, 0);
+
+ DoC_Command(this, NAND_CMD_STATUS, CDSN_CTRL_WP);
+ /* There's an implicit DoC_WaitReady() in DoC_Command */
+
+ dummy = ReadDOC(docptr, CDSNSlowIO);
+ DoC_Delay(this, 2);
+
+ if (ReadDOC_(docptr, this->ioreg) & 1) {
+ puts ("Error programming flash\n");
+ /* Error in programming */
+ *retlen = 0;
+ return DOC_EIO;
+ }
+
+ DoC_Command(this, NAND_CMD_SEQIN, 0);
+ DoC_Address(this, ADDR_COLUMN_PAGE, to + len256, 0,
+ CDSN_CTRL_ECC_IO);
+ }
+
+ DoC_WriteBuf(this, &buf[len256], len - len256);
+
+ if (eccbuf) {
+ WriteDOC(CDSN_CTRL_ECC_IO | CDSN_CTRL_CE, docptr,
+ CDSNControl);
+
+ if (DoC_is_Millennium(this)) {
+ WriteDOC(0, docptr, NOP);
+ WriteDOC(0, docptr, NOP);
+ WriteDOC(0, docptr, NOP);
+ } else {
+ WriteDOC_(0, docptr, this->ioreg);
+ WriteDOC_(0, docptr, this->ioreg);
+ WriteDOC_(0, docptr, this->ioreg);
+ }
+
+ /* Read the ECC data through the DiskOnChip ECC logic */
+ for (di = 0; di < 6; di++) {
+ eccbuf[di] = ReadDOC(docptr, ECCSyndrome0 + di);
+ }
+
+ /* Reset the ECC engine */
+ WriteDOC(DOC_ECC_DIS, docptr, ECCConf);
+
+#ifdef PSYCHO_DEBUG
+ printf
+ ("OOB data at %lx is %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X\n",
+ (long) to, eccbuf[0], eccbuf[1], eccbuf[2], eccbuf[3],
+ eccbuf[4], eccbuf[5]);
+#endif
+ }
+
+ DoC_Command(this, NAND_CMD_PAGEPROG, 0);
+
+ DoC_Command(this, NAND_CMD_STATUS, CDSN_CTRL_WP);
+ /* There's an implicit DoC_WaitReady() in DoC_Command */
+
+ dummy = ReadDOC(docptr, CDSNSlowIO);
+ DoC_Delay(this, 2);
+
+ if (ReadDOC_(docptr, this->ioreg) & 1) {
+ puts ("Error programming flash\n");
+ /* Error in programming */
+ *retlen = 0;
+ return DOC_EIO;
+ }
+
+ /* Let the caller know we completed it */
+ *retlen = len;
+
+ if (eccbuf) {
+ unsigned char x[8];
+ size_t dummy;
+ int ret;
+
+ /* Write the ECC data to flash */
+ for (di=0; di<6; di++)
+ x[di] = eccbuf[di];
+
+ x[6]=0x55;
+ x[7]=0x55;
+
+ ret = doc_write_oob(this, to, 8, &dummy, x);
+ return ret;
+ }
+ return 0;
+}
+
+int doc_read_oob(struct DiskOnChip* this, loff_t ofs, size_t len,
+ size_t * retlen, u_char * buf)
+{
+ int len256 = 0, ret;
+ unsigned long docptr;
+ struct Nand *mychip;
+
+ docptr = this->virtadr;
+
+ mychip = &this->chips[shr(ofs, this->chipshift)];
+
+ if (this->curfloor != mychip->floor) {
+ DoC_SelectFloor(this, mychip->floor);
+ DoC_SelectChip(this, mychip->chip);
+ } else if (this->curchip != mychip->chip) {
+ DoC_SelectChip(this, mychip->chip);
+ }
+ this->curfloor = mychip->floor;
+ this->curchip = mychip->chip;
+
+ /* update address for 2M x 8bit devices. OOB starts on the second */
+ /* page to maintain compatibility with doc_read_ecc. */
+ if (this->page256) {
+ if (!(ofs & 0x8))
+ ofs += 0x100;
+ else
+ ofs -= 0x8;
+ }
+
+ DoC_Command(this, NAND_CMD_READOOB, CDSN_CTRL_WP);
+ DoC_Address(this, ADDR_COLUMN_PAGE, ofs, CDSN_CTRL_WP, 0);
+
+ /* treat crossing 8-byte OOB data for 2M x 8bit devices */
+ /* Note: datasheet says it should automaticaly wrap to the */
+ /* next OOB block, but it didn't work here. mf. */
+ if (this->page256 && ofs + len > (ofs | 0x7) + 1) {
+ len256 = (ofs | 0x7) + 1 - ofs;
+ DoC_ReadBuf(this, buf, len256);
+
+ DoC_Command(this, NAND_CMD_READOOB, CDSN_CTRL_WP);
+ DoC_Address(this, ADDR_COLUMN_PAGE, ofs & (~0x1ff),
+ CDSN_CTRL_WP, 0);
+ }
+
+ DoC_ReadBuf(this, &buf[len256], len - len256);
+
+ *retlen = len;
+ /* Reading the full OOB data drops us off of the end of the page,
+ * causing the flash device to go into busy mode, so we need
+ * to wait until ready 11.4.1 and Toshiba TC58256FT docs */
+
+ ret = DoC_WaitReady(this);
+
+ return ret;
+
+}
+
+int doc_write_oob(struct DiskOnChip* this, loff_t ofs, size_t len,
+ size_t * retlen, const u_char * buf)
+{
+ int len256 = 0;
+ unsigned long docptr = this->virtadr;
+ struct Nand *mychip = &this->chips[shr(ofs, this->chipshift)];
+ volatile int dummy;
+
+#ifdef PSYCHO_DEBUG
+ printf("doc_write_oob(%lx, %d): %2.2X %2.2X %2.2X %2.2X ... %2.2X %2.2X .. %2.2X %2.2X\n",
+ (long)ofs, len, buf[0], buf[1], buf[2], buf[3],
+ buf[8], buf[9], buf[14],buf[15]);
+#endif
+
+ /* Find the chip which is to be used and select it */
+ if (this->curfloor != mychip->floor) {
+ DoC_SelectFloor(this, mychip->floor);
+ DoC_SelectChip(this, mychip->chip);
+ } else if (this->curchip != mychip->chip) {
+ DoC_SelectChip(this, mychip->chip);
+ }
+ this->curfloor = mychip->floor;
+ this->curchip = mychip->chip;
+
+ /* disable the ECC engine */
+ WriteDOC (DOC_ECC_RESET, docptr, ECCConf);
+ WriteDOC (DOC_ECC_DIS, docptr, ECCConf);
+
+ /* Reset the chip, see Software Requirement 11.4 item 1. */
+ DoC_Command(this, NAND_CMD_RESET, CDSN_CTRL_WP);
+
+ /* issue the Read2 command to set the pointer to the Spare Data Area. */
+ DoC_Command(this, NAND_CMD_READOOB, CDSN_CTRL_WP);
+
+ /* update address for 2M x 8bit devices. OOB starts on the second */
+ /* page to maintain compatibility with doc_read_ecc. */
+ if (this->page256) {
+ if (!(ofs & 0x8))
+ ofs += 0x100;
+ else
+ ofs -= 0x8;
+ }
+
+ /* issue the Serial Data In command to initial the Page Program process */
+ DoC_Command(this, NAND_CMD_SEQIN, 0);
+ DoC_Address(this, ADDR_COLUMN_PAGE, ofs, 0, 0);
+
+ /* treat crossing 8-byte OOB data for 2M x 8bit devices */
+ /* Note: datasheet says it should automaticaly wrap to the */
+ /* next OOB block, but it didn't work here. mf. */
+ if (this->page256 && ofs + len > (ofs | 0x7) + 1) {
+ len256 = (ofs | 0x7) + 1 - ofs;
+ DoC_WriteBuf(this, buf, len256);
+
+ DoC_Command(this, NAND_CMD_PAGEPROG, 0);
+ DoC_Command(this, NAND_CMD_STATUS, 0);
+ /* DoC_WaitReady() is implicit in DoC_Command */
+
+ dummy = ReadDOC(docptr, CDSNSlowIO);
+ DoC_Delay(this, 2);
+
+ if (ReadDOC_(docptr, this->ioreg) & 1) {
+ puts ("Error programming oob data\n");
+ /* There was an error */
+ *retlen = 0;
+ return DOC_EIO;
+ }
+ DoC_Command(this, NAND_CMD_SEQIN, 0);
+ DoC_Address(this, ADDR_COLUMN_PAGE, ofs & (~0x1ff), 0, 0);
+ }
+
+ DoC_WriteBuf(this, &buf[len256], len - len256);
+
+ DoC_Command(this, NAND_CMD_PAGEPROG, 0);
+ DoC_Command(this, NAND_CMD_STATUS, 0);
+ /* DoC_WaitReady() is implicit in DoC_Command */
+
+ dummy = ReadDOC(docptr, CDSNSlowIO);
+ DoC_Delay(this, 2);
+
+ if (ReadDOC_(docptr, this->ioreg) & 1) {
+ puts ("Error programming oob data\n");
+ /* There was an error */
+ *retlen = 0;
+ return DOC_EIO;
+ }
+
+ *retlen = len;
+ return 0;
+
+}
+
+int doc_erase(struct DiskOnChip* this, loff_t ofs, size_t len)
+{
+ volatile int dummy;
+ unsigned long docptr;
+ struct Nand *mychip;
+
+ if (ofs & (this->erasesize-1) || len & (this->erasesize-1)) {
+ puts ("Offset and size must be sector aligned\n");
+ return DOC_EINVAL;
+ }
+
+ docptr = this->virtadr;
+
+ /* FIXME: Do this in the background. Use timers or schedule_task() */
+ while(len) {
+ mychip = &this->chips[shr(ofs, this->chipshift)];
+
+ if (this->curfloor != mychip->floor) {
+ DoC_SelectFloor(this, mychip->floor);
+ DoC_SelectChip(this, mychip->chip);
+ } else if (this->curchip != mychip->chip) {
+ DoC_SelectChip(this, mychip->chip);
+ }
+ this->curfloor = mychip->floor;
+ this->curchip = mychip->chip;
+
+ DoC_Command(this, NAND_CMD_ERASE1, 0);
+ DoC_Address(this, ADDR_PAGE, ofs, 0, 0);
+ DoC_Command(this, NAND_CMD_ERASE2, 0);
+
+ DoC_Command(this, NAND_CMD_STATUS, CDSN_CTRL_WP);
+
+ dummy = ReadDOC(docptr, CDSNSlowIO);
+ DoC_Delay(this, 2);
+
+ if (ReadDOC_(docptr, this->ioreg) & 1) {
+ printf("Error erasing at 0x%lx\n", (long)ofs);
+ /* There was an error */
+ goto callback;
+ }
+ ofs += this->erasesize;
+ len -= this->erasesize;
+ }
+
+ callback:
+ return 0;
+}
+
+static inline int doccheck(unsigned long potential, unsigned long physadr)
+{
+ unsigned long window=potential;
+ unsigned char tmp, ChipID;
+#ifndef DOC_PASSIVE_PROBE
+ unsigned char tmp2;
+#endif
+
+ /* Routine copied from the Linux DOC driver */
+
+#ifdef CFG_DOCPROBE_55AA
+ /* Check for 0x55 0xAA signature at beginning of window,
+ this is no longer true once we remove the IPL (for Millennium */
+ if (ReadDOC(window, Sig1) != 0x55 || ReadDOC(window, Sig2) != 0xaa)
+ return 0;
+#endif /* CFG_DOCPROBE_55AA */
+
+#ifndef DOC_PASSIVE_PROBE
+ /* It's not possible to cleanly detect the DiskOnChip - the
+ * bootup procedure will put the device into reset mode, and
+ * it's not possible to talk to it without actually writing
+ * to the DOCControl register. So we store the current contents
+ * of the DOCControl register's location, in case we later decide
+ * that it's not a DiskOnChip, and want to put it back how we
+ * found it.
+ */
+ tmp2 = ReadDOC(window, DOCControl);
+
+ /* Reset the DiskOnChip ASIC */
+ WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_RESET,
+ window, DOCControl);
+ WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_RESET,
+ window, DOCControl);
+
+ /* Enable the DiskOnChip ASIC */
+ WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_NORMAL,
+ window, DOCControl);
+ WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_NORMAL,
+ window, DOCControl);
+#endif /* !DOC_PASSIVE_PROBE */
+
+ ChipID = ReadDOC(window, ChipID);
+
+ switch (ChipID) {
+ case DOC_ChipID_Doc2k:
+ /* Check the TOGGLE bit in the ECC register */
+ tmp = ReadDOC(window, 2k_ECCStatus) & DOC_TOGGLE_BIT;
+ if ((ReadDOC(window, 2k_ECCStatus) & DOC_TOGGLE_BIT) != tmp)
+ return ChipID;
+ break;
+
+ case DOC_ChipID_DocMil:
+ /* Check the TOGGLE bit in the ECC register */
+ tmp = ReadDOC(window, ECCConf) & DOC_TOGGLE_BIT;
+ if ((ReadDOC(window, ECCConf) & DOC_TOGGLE_BIT) != tmp)
+ return ChipID;
+ break;
+
+ default:
+#ifndef CFG_DOCPROBE_55AA
+/*
+ * if the ID isn't the DoC2000 or DoCMillenium ID, so we can assume
+ * the DOC is missing
+ */
+# if 0
+ printf("Possible DiskOnChip with unknown ChipID %2.2X found at 0x%lx\n",
+ ChipID, physadr);
+# endif
+#endif
+#ifndef DOC_PASSIVE_PROBE
+ /* Put back the contents of the DOCControl register, in case it's not
+ * actually a DiskOnChip.
+ */
+ WriteDOC(tmp2, window, DOCControl);
+#endif
+ return 0;
+ }
+
+ puts ("DiskOnChip failed TOGGLE test, dropping.\n");
+
+#ifndef DOC_PASSIVE_PROBE
+ /* Put back the contents of the DOCControl register: it's not a DiskOnChip */
+ WriteDOC(tmp2, window, DOCControl);
+#endif
+ return 0;
+}
+
+void doc_probe(unsigned long physadr)
+{
+ struct DiskOnChip *this = NULL;
+ int i=0, ChipID;
+
+ if ((ChipID = doccheck(physadr, physadr))) {
+
+ for (i=0; i<CFG_MAX_DOC_DEVICE; i++) {
+ if (doc_dev_desc[i].ChipID == DOC_ChipID_UNKNOWN) {
+ this = doc_dev_desc + i;
+ break;
+ }
+ }
+
+ if (!this) {
+ puts ("Cannot allocate memory for data structures.\n");
+ return;
+ }
+
+ if (curr_device == -1)
+ curr_device = i;
+
+ memset((char *)this, 0, sizeof(struct DiskOnChip));
+
+ this->virtadr = physadr;
+ this->physadr = physadr;
+ this->ChipID = ChipID;
+
+ DoC2k_init(this);
+ } else {
+ puts ("No DiskOnChip found\n");
+ }
+}
+
+#endif /* (CONFIG_COMMANDS & CFG_CMD_DOC) */
--- /dev/null
+/*
+ * (C) Copyright 2000-2002
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ */
+
+/*
+ * IDE support
+ */
+#include <common.h>
+#include <config.h>
+#include <watchdog.h>
+#include <command.h>
+#include <image.h>
+#include <asm/byteorder.h>
+#if defined(CONFIG_IDE_8xx_DIRECT) || defined(CONFIG_IDE_PCMCIA)
+# include <pcmcia.h>
+#endif
+#ifdef CONFIG_8xx
+# include <mpc8xx.h>
+#endif
+#include <ide.h>
+#include <ata.h>
+#include <cmd_ide.h>
+#include <cmd_disk.h>
+#ifdef CONFIG_STATUS_LED
+# include <status_led.h>
+#endif
+
+#ifdef CONFIG_SHOW_BOOT_PROGRESS
+# include <status_led.h>
+# define SHOW_BOOT_PROGRESS(arg) show_boot_progress(arg)
+#else
+# define SHOW_BOOT_PROGRESS(arg)
+#endif
+
+
+#undef IDE_DEBUG
+
+#ifdef IDE_DEBUG
+#define PRINTF(fmt,args...) printf (fmt ,##args)
+#else
+#define PRINTF(fmt,args...)
+#endif
+
+#if (CONFIG_COMMANDS & CFG_CMD_IDE)
+
+/* Timings for IDE Interface
+ *
+ * SETUP / LENGTH / HOLD - cycles valid for 50 MHz clk
+ * 70 165 30 PIO-Mode 0, [ns]
+ * 4 9 2 [Cycles]
+ * 50 125 20 PIO-Mode 1, [ns]
+ * 3 7 2 [Cycles]
+ * 30 100 15 PIO-Mode 2, [ns]
+ * 2 6 1 [Cycles]
+ * 30 80 10 PIO-Mode 3, [ns]
+ * 2 5 1 [Cycles]
+ * 25 70 10 PIO-Mode 4, [ns]
+ * 2 4 1 [Cycles]
+ */
+
+const static pio_config_t pio_config_ns [IDE_MAX_PIO_MODE+1] =
+{
+ /* Setup Length Hold */
+ { 70, 165, 30 }, /* PIO-Mode 0, [ns] */
+ { 50, 125, 20 }, /* PIO-Mode 1, [ns] */
+ { 30, 101, 15 }, /* PIO-Mode 2, [ns] */
+ { 30, 80, 10 }, /* PIO-Mode 3, [ns] */
+ { 25, 70, 10 }, /* PIO-Mode 4, [ns] */
+};
+
+static pio_config_t pio_config_clk [IDE_MAX_PIO_MODE+1];
+
+#ifndef CFG_PIO_MODE
+#define CFG_PIO_MODE 0 /* use a relaxed default */
+#endif
+static int pio_mode = CFG_PIO_MODE;
+
+/* Make clock cycles and always round up */
+
+#define PCMCIA_MK_CLKS( t, T ) (( (t) * (T) + 999U ) / 1000U )
+
+/* ------------------------------------------------------------------------- */
+
+/* Current I/O Device */
+static int curr_device = -1;
+
+/* Current offset for IDE0 / IDE1 bus access */
+ulong ide_bus_offset[CFG_IDE_MAXBUS] = {
+#if defined(CFG_ATA_IDE0_OFFSET)
+ CFG_ATA_IDE0_OFFSET,
+#endif
+#if defined(CFG_ATA_IDE1_OFFSET) && (CFG_IDE_MAXBUS > 1)
+ CFG_ATA_IDE1_OFFSET,
+#endif
+};
+
+#define ATA_CURR_BASE(dev) (CFG_ATA_BASE_ADDR+ide_bus_offset[IDE_BUS(dev)])
+
+static int ide_bus_ok[CFG_IDE_MAXBUS];
+
+static block_dev_desc_t ide_dev_desc[CFG_IDE_MAXDEVICE];
+/* ------------------------------------------------------------------------- */
+
+#ifdef CONFIG_IDE_LED
+static void ide_led (uchar led, uchar status);
+#else
+#define ide_led(a,b) /* dummy */
+#endif
+
+#ifdef CONFIG_IDE_RESET
+static void ide_reset (void);
+#else
+#define ide_reset() /* dummy */
+#endif
+
+static void ide_ident (block_dev_desc_t *dev_desc);
+static uchar ide_wait (int dev, ulong t);
+
+#define IDE_TIME_OUT 2000 /* 2 sec timeout */
+
+#define ATAPI_TIME_OUT 7000 /* 7 sec timeout (5 sec seems to work...) */
+
+#define IDE_SPIN_UP_TIME_OUT 5000 /* 5 sec spin-up timeout */
+
+static void __inline__ outb(int dev, int port, unsigned char val);
+static unsigned char __inline__ inb(int dev, int port);
+static void input_swap_data(int dev, ulong *sect_buf, int words);
+static void input_data(int dev, ulong *sect_buf, int words);
+static void output_data(int dev, ulong *sect_buf, int words);
+static void ident_cpy (unsigned char *dest, unsigned char *src, unsigned int len);
+
+
+#ifdef CONFIG_ATAPI
+static void atapi_inquiry(block_dev_desc_t *dev_desc);
+ulong atapi_read (int device, ulong blknr, ulong blkcnt, ulong *buffer);
+#endif
+
+
+#ifdef CONFIG_IDE_8xx_DIRECT
+static void set_pcmcia_timing (int pmode);
+#else
+#define set_pcmcia_timing(a) /* dummy */
+#endif
+
+/* ------------------------------------------------------------------------- */
+
+int do_ide (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+ int rcode = 0;
+
+ switch (argc) {
+ case 0:
+ case 1:
+ printf ("Usage:\n%s\n", cmdtp->usage);
+ return 1;
+ case 2:
+ if (strncmp(argv[1],"res",3) == 0) {
+ puts ("\nReset IDE"
+#ifdef CONFIG_IDE_8xx_DIRECT
+ " on PCMCIA " PCMCIA_SLOT_MSG
+#endif
+ ": ");
+
+ ide_init ();
+ return 0;
+ } else if (strncmp(argv[1],"inf",3) == 0) {
+ int i;
+
+ putc ('\n');
+
+ for (i=0; i<CFG_IDE_MAXDEVICE; ++i) {
+ if (ide_dev_desc[i].type==DEV_TYPE_UNKNOWN)
+ continue; /* list only known devices */
+ printf ("IDE device %d: ", i);
+ dev_print(&ide_dev_desc[i]);
+ }
+ return 0;
+
+ } else if (strncmp(argv[1],"dev",3) == 0) {
+ if ((curr_device < 0) || (curr_device >= CFG_IDE_MAXDEVICE)) {
+ puts ("\nno IDE devices available\n");
+ return 1;
+ }
+ printf ("\nIDE device %d: ", curr_device);
+ dev_print(&ide_dev_desc[curr_device]);
+ return 0;
+ } else if (strncmp(argv[1],"part",4) == 0) {
+ int dev, ok;
+
+ for (ok=0, dev=0; dev<CFG_IDE_MAXDEVICE; ++dev) {
+ if (ide_dev_desc[dev].part_type!=PART_TYPE_UNKNOWN) {
+ ++ok;
+ if (dev)
+ putc ('\n');
+ print_part(&ide_dev_desc[dev]);
+ }
+ }
+ if (!ok) {
+ puts ("\nno IDE devices available\n");
+ rcode ++;
+ }
+ return rcode;
+ }
+ printf ("Usage:\n%s\n", cmdtp->usage);
+ return 1;
+ case 3:
+ if (strncmp(argv[1],"dev",3) == 0) {
+ int dev = (int)simple_strtoul(argv[2], NULL, 10);
+
+ printf ("\nIDE device %d: ", dev);
+ if (dev >= CFG_IDE_MAXDEVICE) {
+ puts ("unknown device\n");
+ return 1;
+ }
+ dev_print(&ide_dev_desc[dev]);
+ /*ide_print (dev);*/
+
+ if (ide_dev_desc[dev].type == DEV_TYPE_UNKNOWN) {
+ return 1;
+ }
+
+ curr_device = dev;
+
+ puts ("... is now current device\n");
+
+ return 0;
+ } else if (strncmp(argv[1],"part",4) == 0) {
+ int dev = (int)simple_strtoul(argv[2], NULL, 10);
+
+ if (ide_dev_desc[dev].part_type!=PART_TYPE_UNKNOWN) {
+ print_part(&ide_dev_desc[dev]);
+ } else {
+ printf ("\nIDE device %d not available\n", dev);
+ rcode = 1;
+ }
+ return rcode;
+#if 0
+ } else if (strncmp(argv[1],"pio",4) == 0) {
+ int mode = (int)simple_strtoul(argv[2], NULL, 10);
+
+ if ((mode >= 0) && (mode <= IDE_MAX_PIO_MODE)) {
+ puts ("\nSetting ");
+ pio_mode = mode;
+ ide_init ();
+ } else {
+ printf ("\nInvalid PIO mode %d (0 ... %d only)\n",
+ mode, IDE_MAX_PIO_MODE);
+ }
+ return;
+#endif
+ }
+
+ printf ("Usage:\n%s\n", cmdtp->usage);
+ return 1;
+ default:
+ /* at least 4 args */
+
+ if (strcmp(argv[1],"read") == 0) {
+ ulong addr = simple_strtoul(argv[2], NULL, 16);
+ ulong blk = simple_strtoul(argv[3], NULL, 16);
+ ulong cnt = simple_strtoul(argv[4], NULL, 16);
+ ulong n;
+
+ printf ("\nIDE read: device %d block # %ld, count %ld ... ",
+ curr_device, blk, cnt);
+
+ n = ide_dev_desc[curr_device].block_read (curr_device,
+ blk, cnt,
+ (ulong *)addr);
+ /* flush cache after read */
+ flush_cache (addr, cnt*ide_dev_desc[curr_device].blksz);
+
+ printf ("%ld blocks read: %s\n",
+ n, (n==cnt) ? "OK" : "ERROR");
+ if (n==cnt) {
+ return 0;
+ } else {
+ return 1;
+ }
+ } else if (strcmp(argv[1],"write") == 0) {
+ ulong addr = simple_strtoul(argv[2], NULL, 16);
+ ulong blk = simple_strtoul(argv[3], NULL, 16);
+ ulong cnt = simple_strtoul(argv[4], NULL, 16);
+ ulong n;
+
+ printf ("\nIDE write: device %d block # %ld, count %ld ... ",
+ curr_device, blk, cnt);
+
+ n = ide_write (curr_device, blk, cnt, (ulong *)addr);
+
+ printf ("%ld blocks written: %s\n",
+ n, (n==cnt) ? "OK" : "ERROR");
+ if (n==cnt) {
+ return 0;
+ } else {
+ return 1;
+ }
+ } else {
+ printf ("Usage:\n%s\n", cmdtp->usage);
+ rcode = 1;
+ }
+
+ return rcode;
+ }
+}
+
+int do_diskboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+ char *boot_device = NULL;
+ char *ep;
+ int dev, part = 0;
+ ulong cnt;
+ ulong addr;
+ disk_partition_t info;
+ image_header_t *hdr;
+ int rcode = 0;
+
+ switch (argc) {
+ case 1:
+ addr = CFG_LOAD_ADDR;
+ boot_device = getenv ("bootdevice");
+ break;
+ case 2:
+ addr = simple_strtoul(argv[1], NULL, 16);
+ boot_device = getenv ("bootdevice");
+ break;
+ case 3:
+ addr = simple_strtoul(argv[1], NULL, 16);
+ boot_device = argv[2];
+ break;
+ default:
+ printf ("Usage:\n%s\n", cmdtp->usage);
+ SHOW_BOOT_PROGRESS (-1);
+ return 1;
+ }
+
+ if (!boot_device) {
+ puts ("\n** No boot device **\n");
+ SHOW_BOOT_PROGRESS (-1);
+ return 1;
+ }
+
+ dev = simple_strtoul(boot_device, &ep, 16);
+
+ if (ide_dev_desc[dev].type==DEV_TYPE_UNKNOWN) {
+ printf ("\n** Device %d not available\n", dev);
+ SHOW_BOOT_PROGRESS (-1);
+ return 1;
+ }
+
+ if (*ep) {
+ if (*ep != ':') {
+ puts ("\n** Invalid boot device, use `dev[:part]' **\n");
+ SHOW_BOOT_PROGRESS (-1);
+ return 1;
+ }
+ part = simple_strtoul(++ep, NULL, 16);
+ }
+ if (get_partition_info (&ide_dev_desc[dev], part, &info)) {
+ SHOW_BOOT_PROGRESS (-1);
+ return 1;
+ }
+ if (strncmp(info.type, BOOT_PART_TYPE, sizeof(info.type)) != 0) {
+ printf ("\n** Invalid partition type \"%.32s\""
+ " (expect \"" BOOT_PART_TYPE "\")\n",
+ info.type);
+ SHOW_BOOT_PROGRESS (-1);
+ return 1;
+ }
+
+ printf ("\nLoading from IDE device %d, partition %d: "
+ "Name: %.32s Type: %.32s\n",
+ dev, part, info.name, info.type);
+
+ PRINTF ("First Block: %ld, # of blocks: %ld, Block Size: %ld\n",
+ info.start, info.size, info.blksz);
+
+ if (ide_dev_desc[dev].block_read (dev, info.start, 1, (ulong *)addr) != 1) {
+ printf ("** Read error on %d:%d\n", dev, part);
+ SHOW_BOOT_PROGRESS (-1);
+ return 1;
+ }
+
+ hdr = (image_header_t *)addr;
+
+ if (ntohl(hdr->ih_magic) == IH_MAGIC) {
+
+ print_image_hdr (hdr);
+
+ cnt = (ntohl(hdr->ih_size) + sizeof(image_header_t));
+ cnt += info.blksz - 1;
+ cnt /= info.blksz;
+ cnt -= 1;
+ } else {
+ printf("\n** Bad Magic Number **\n");
+ SHOW_BOOT_PROGRESS (-1);
+ return 1;
+ }
+
+ if (ide_dev_desc[dev].block_read (dev, info.start+1, cnt,
+ (ulong *)(addr+info.blksz)) != cnt) {
+ printf ("** Read error on %d:%d\n", dev, part);
+ SHOW_BOOT_PROGRESS (-1);
+ return 1;
+ }
+
+
+ /* Loading ok, update default load address */
+
+ load_addr = addr;
+
+ /* Check if we should attempt an auto-start */
+ if (((ep = getenv("autostart")) != NULL) && (strcmp(ep,"yes") == 0)) {
+ char *local_args[2];
+ extern int do_bootm (cmd_tbl_t *, int, int, char *[]);
+
+ local_args[0] = argv[0];
+ local_args[1] = NULL;
+
+ printf ("Automatic boot of image at addr 0x%08lX ...\n", addr);
+
+ do_bootm (cmdtp, 0, 1, local_args);
+ rcode = 1;
+ }
+ return rcode;
+}
+
+/* ------------------------------------------------------------------------- */
+
+void ide_init (void)
+{
+ DECLARE_GLOBAL_DATA_PTR;
+
+#ifdef CONFIG_IDE_8xx_DIRECT
+ volatile immap_t *immr = (immap_t *)CFG_IMMR;
+ volatile pcmconf8xx_t *pcmp = &(immr->im_pcmcia);
+#endif
+ unsigned char c;
+ int i, bus;
+
+#ifdef CONFIG_IDE_8xx_PCCARD
+ extern int pcmcia_on (void);
+
+ WATCHDOG_RESET();
+
+ /* initialize the PCMCIA IDE adapter card */
+ if (pcmcia_on())
+ return;
+ udelay (1000000); /* 1 s */
+#endif /* CONFIG_IDE_8xx_PCCARD */
+
+ WATCHDOG_RESET();
+
+ /* Initialize PIO timing tables */
+ for (i=0; i <= IDE_MAX_PIO_MODE; ++i) {
+ pio_config_clk[i].t_setup = PCMCIA_MK_CLKS(pio_config_ns[i].t_setup,
+ gd->bus_clk);
+ pio_config_clk[i].t_length = PCMCIA_MK_CLKS(pio_config_ns[i].t_length,
+ gd->bus_clk);
+ pio_config_clk[i].t_hold = PCMCIA_MK_CLKS(pio_config_ns[i].t_hold,
+ gd->bus_clk);
+ PRINTF ("PIO Mode %d: setup=%2d ns/%d clk"
+ " len=%3d ns/%d clk"
+ " hold=%2d ns/%d clk\n",
+ i,
+ pio_config_ns[i].t_setup, pio_config_clk[i].t_setup,
+ pio_config_ns[i].t_length, pio_config_clk[i].t_length,
+ pio_config_ns[i].t_hold, pio_config_clk[i].t_hold);
+ }
+
+ /* Reset the IDE just to be sure.
+ * Light LED's to show
+ */
+ ide_led ((LED_IDE1 | LED_IDE2), 1); /* LED's on */
+ ide_reset (); /* ATAPI Drives seems to need a proper IDE Reset */
+
+#ifdef CONFIG_IDE_8xx_DIRECT
+ /* PCMCIA / IDE initialization for common mem space */
+ pcmp->pcmc_pgcrb = 0;
+#endif
+
+ /* start in PIO mode 0 - most relaxed timings */
+ pio_mode = 0;
+ set_pcmcia_timing (pio_mode);
+
+ /*
+ * Wait for IDE to get ready.
+ * According to spec, this can take up to 31 seconds!
+ */
+ for (bus=0; bus<CFG_IDE_MAXBUS; ++bus) {
+ int dev = bus * (CFG_IDE_MAXDEVICE / CFG_IDE_MAXBUS);
+
+ printf ("Bus %d: ", bus);
+
+ ide_bus_ok[bus] = 0;
+
+ /* Select device
+ */
+ udelay (100000); /* 100 ms */
+ outb (dev, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(dev));
+ udelay (100000); /* 100 ms */
+
+ i = 0;
+ do {
+ udelay (10000); /* 10 ms */
+
+ c = inb (dev, ATA_STATUS);
+ i++;
+ if (i > (ATA_RESET_TIME * 100)) {
+ puts ("** Timeout **\n");
+ ide_led ((LED_IDE1 | LED_IDE2), 0); /* LED's off */
+ return;
+ }
+ if ((i >= 100) && ((i%100)==0)) {
+ putc ('.');
+ }
+ } while (c & ATA_STAT_BUSY);
+
+ if (c & (ATA_STAT_BUSY | ATA_STAT_FAULT)) {
+ puts ("not available ");
+ PRINTF ("Status = 0x%02X ", c);
+#ifndef CONFIG_ATAPI /* ATAPI Devices do not set DRDY */
+ } else if ((c & ATA_STAT_READY) == 0) {
+ puts ("not available ");
+ PRINTF ("Status = 0x%02X ", c);
+#endif
+ } else {
+ puts ("OK ");
+ ide_bus_ok[bus] = 1;
+ }
+ WATCHDOG_RESET();
+ }
+ putc ('\n');
+
+ ide_led ((LED_IDE1 | LED_IDE2), 0); /* LED's off */
+
+ curr_device = -1;
+ for (i=0; i<CFG_IDE_MAXDEVICE; ++i) {
+#ifdef CONFIG_IDE_LED
+ int led = (IDE_BUS(i) == 0) ? LED_IDE1 : LED_IDE2;
+#endif
+ ide_dev_desc[i].if_type=IF_TYPE_IDE;
+ ide_dev_desc[i].dev=i;
+ ide_dev_desc[i].part_type=PART_TYPE_UNKNOWN;
+ ide_dev_desc[i].blksz=0;
+ ide_dev_desc[i].lba=0;
+ ide_dev_desc[i].block_read=ide_read;
+ if (!ide_bus_ok[IDE_BUS(i)])
+ continue;
+ ide_led (led, 1); /* LED on */
+ ide_ident(&ide_dev_desc[i]);
+ ide_led (led, 0); /* LED off */
+ dev_print(&ide_dev_desc[i]);
+/* ide_print (i); */
+ if ((ide_dev_desc[i].lba > 0) && (ide_dev_desc[i].blksz > 0)) {
+ init_part (&ide_dev_desc[i]); /* initialize partition type */
+ if (curr_device < 0)
+ curr_device = i;
+ }
+ }
+ WATCHDOG_RESET();
+}
+
+/* ------------------------------------------------------------------------- */
+
+block_dev_desc_t * ide_get_dev(int dev)
+{
+ return ((block_dev_desc_t *)&ide_dev_desc[dev]);
+}
+
+
+#ifdef CONFIG_IDE_8xx_DIRECT
+
+static void
+set_pcmcia_timing (int pmode)
+{
+ volatile immap_t *immr = (immap_t *)CFG_IMMR;
+ volatile pcmconf8xx_t *pcmp = &(immr->im_pcmcia);
+ ulong timings;
+
+ PRINTF ("Set timing for PIO Mode %d\n", pmode);
+
+ timings = PCMCIA_SHT(pio_config_clk[pmode].t_hold)
+ | PCMCIA_SST(pio_config_clk[pmode].t_setup)
+ | PCMCIA_SL (pio_config_clk[pmode].t_length)
+ ;
+
+ /* IDE 0
+ */
+ pcmp->pcmc_pbr0 = CFG_PCMCIA_PBR0;
+ pcmp->pcmc_por0 = CFG_PCMCIA_POR0
+#if (CFG_PCMCIA_POR0 != 0)
+ | timings
+#endif
+ ;
+ PRINTF ("PBR0: %08x POR0: %08x\n", pcmp->pcmc_pbr0, pcmp->pcmc_por0);
+
+ pcmp->pcmc_pbr1 = CFG_PCMCIA_PBR1;
+ pcmp->pcmc_por1 = CFG_PCMCIA_POR1
+#if (CFG_PCMCIA_POR1 != 0)
+ | timings
+#endif
+ ;
+ PRINTF ("PBR1: %08x POR1: %08x\n", pcmp->pcmc_pbr1, pcmp->pcmc_por1);
+
+ pcmp->pcmc_pbr2 = CFG_PCMCIA_PBR2;
+ pcmp->pcmc_por2 = CFG_PCMCIA_POR2
+#if (CFG_PCMCIA_POR2 != 0)
+ | timings
+#endif
+ ;
+ PRINTF ("PBR2: %08x POR2: %08x\n", pcmp->pcmc_pbr2, pcmp->pcmc_por2);
+
+ pcmp->pcmc_pbr3 = CFG_PCMCIA_PBR3;
+ pcmp->pcmc_por3 = CFG_PCMCIA_POR3
+#if (CFG_PCMCIA_POR3 != 0)
+ | timings
+#endif
+ ;
+ PRINTF ("PBR3: %08x POR3: %08x\n", pcmp->pcmc_pbr3, pcmp->pcmc_por3);
+
+ /* IDE 1
+ */
+ pcmp->pcmc_pbr4 = CFG_PCMCIA_PBR4;
+ pcmp->pcmc_por4 = CFG_PCMCIA_POR4
+#if (CFG_PCMCIA_POR4 != 0)
+ | timings
+#endif
+ ;
+ PRINTF ("PBR4: %08x POR4: %08x\n", pcmp->pcmc_pbr4, pcmp->pcmc_por4);
+
+ pcmp->pcmc_pbr5 = CFG_PCMCIA_PBR5;
+ pcmp->pcmc_por5 = CFG_PCMCIA_POR5
+#if (CFG_PCMCIA_POR5 != 0)
+ | timings
+#endif
+ ;
+ PRINTF ("PBR5: %08x POR5: %08x\n", pcmp->pcmc_pbr5, pcmp->pcmc_por5);
+
+ pcmp->pcmc_pbr6 = CFG_PCMCIA_PBR6;
+ pcmp->pcmc_por6 = CFG_PCMCIA_POR6
+#if (CFG_PCMCIA_POR6 != 0)
+ | timings
+#endif
+ ;
+ PRINTF ("PBR6: %08x POR6: %08x\n", pcmp->pcmc_pbr6, pcmp->pcmc_por6);
+
+ pcmp->pcmc_pbr7 = CFG_PCMCIA_PBR7;
+ pcmp->pcmc_por7 = CFG_PCMCIA_POR7
+#if (CFG_PCMCIA_POR7 != 0)
+ | timings
+#endif
+ ;
+ PRINTF ("PBR7: %08x POR7: %08x\n", pcmp->pcmc_pbr7, pcmp->pcmc_por7);
+
+}
+
+#endif /* CONFIG_IDE_8xx_DIRECT */
+
+/* ------------------------------------------------------------------------- */
+
+static void __inline__
+outb(int dev, int port, unsigned char val)
+{
+ /* Ensure I/O operations complete */
+ __asm__ volatile("eieio");
+ *((uchar *)(ATA_CURR_BASE(dev)+port)) = val;
+#if 0
+ printf ("OUTB: 0x%08lx <== 0x%02x\n", ATA_CURR_BASE(dev)+port, val);
+#endif
+}
+
+static unsigned char __inline__
+inb(int dev, int port)
+{
+ uchar val;
+ /* Ensure I/O operations complete */
+ __asm__ volatile("eieio");
+ val = *((uchar *)(ATA_CURR_BASE(dev)+port));
+#if 0
+ printf ("INB: 0x%08lx ==> 0x%02x\n", ATA_CURR_BASE(dev)+port, val);
+#endif
+ return (val);
+}
+
+__inline__ unsigned ld_le16(const volatile unsigned short *addr)
+{
+ unsigned val;
+
+ __asm__ __volatile__ ("lhbrx %0,0,%1" : "=r"(val) : "r"(addr), "m"(*addr));
+ return val;
+}
+
+static void
+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;
+
+ while (words--) {
+ *dbuf++ = ld_le16(pbuf);
+ *dbuf++ = ld_le16(pbuf);
+ }
+}
+
+static void
+output_data(int dev, ulong *sect_buf, int words)
+{
+ ushort *dbuf;
+ volatile ushort *pbuf;
+
+ pbuf = (ushort *)(ATA_CURR_BASE(dev)+ATA_DATA_REG);
+ dbuf = (ushort *)sect_buf;
+ while (words--) {
+ __asm__ volatile ("eieio");
+ *pbuf = *dbuf++;
+ __asm__ volatile ("eieio");
+ *pbuf = *dbuf++;
+ }
+}
+
+static void
+input_data(int dev, ulong *sect_buf, int words)
+{
+ ushort *dbuf;
+ volatile ushort *pbuf;
+
+ pbuf = (ushort *)(ATA_CURR_BASE(dev)+ATA_DATA_REG);
+ dbuf = (ushort *)sect_buf;
+ while (words--) {
+ __asm__ volatile ("eieio");
+ *dbuf++ = *pbuf;
+ __asm__ volatile ("eieio");
+ *dbuf++ = *pbuf;
+ }
+}
+
+/* -------------------------------------------------------------------------
+ */
+static void ide_ident (block_dev_desc_t *dev_desc)
+{
+ ulong iobuf[ATA_SECTORWORDS];
+ unsigned char c;
+ hd_driveid_t *iop = (hd_driveid_t *)iobuf;
+
+#if 0
+ int mode, cycle_time;
+#endif
+ int device;
+ device=dev_desc->dev;
+ printf (" Device %d: ", device);
+
+ ide_led (DEVICE_LED(device), 1); /* LED on */
+ /* Select device
+ */
+ outb (device, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(device));
+ dev_desc->if_type=IF_TYPE_IDE;
+#ifdef CONFIG_ATAPI
+ /* check signature */
+ if ((inb(device,ATA_SECT_CNT)==0x01) &&
+ (inb(device,ATA_SECT_NUM)==0x01) &&
+ (inb(device,ATA_CYL_LOW)==0x14) &&
+ (inb(device,ATA_CYL_HIGH)==0xEB)) {
+ /* ATAPI Signature found */
+ dev_desc->if_type=IF_TYPE_ATAPI;
+ /* Start Ident Command
+ */
+ outb (device, ATA_COMMAND, ATAPI_CMD_IDENT);
+ /*
+ * Wait for completion - ATAPI devices need more time
+ * to become ready
+ */
+ c = ide_wait (device, ATAPI_TIME_OUT);
+ }
+ else
+#endif
+ {
+ /* Start Ident Command
+ */
+ outb (device, ATA_COMMAND, ATA_CMD_IDENT);
+
+ /* Wait for completion
+ */
+ c = ide_wait (device, IDE_TIME_OUT);
+ }
+ ide_led (DEVICE_LED(device), 0); /* LED off */
+
+ if (((c & ATA_STAT_DRQ) == 0) ||
+ ((c & (ATA_STAT_FAULT|ATA_STAT_ERR)) != 0) ) {
+ dev_desc->type=DEV_TYPE_UNKNOWN;
+ return;
+ }
+
+ input_swap_data (device, iobuf, ATA_SECTORWORDS);
+
+ ident_cpy (dev_desc->revision, iop->fw_rev, sizeof(dev_desc->revision));
+ ident_cpy (dev_desc->vendor, iop->model, sizeof(dev_desc->vendor));
+ ident_cpy (dev_desc->product, iop->serial_no, sizeof(dev_desc->product));
+
+ if ((iop->config & 0x0080)==0x0080)
+ dev_desc->removable = 1;
+ else
+ dev_desc->removable = 0;
+
+#if 0
+ /*
+ * Drive PIO mode autoselection
+ */
+ mode = iop->tPIO;
+
+ printf ("tPIO = 0x%02x = %d\n",mode, mode);
+ if (mode > 2) { /* 2 is maximum allowed tPIO value */
+ mode = 2;
+ PRINTF ("Override tPIO -> 2\n");
+ }
+ if (iop->field_valid & 2) { /* drive implements ATA2? */
+ PRINTF ("Drive implements ATA2\n");
+ if (iop->capability & 8) { /* drive supports use_iordy? */
+ cycle_time = iop->eide_pio_iordy;
+ } else {
+ cycle_time = iop->eide_pio;
+ }
+ PRINTF ("cycle time = %d\n", cycle_time);
+ mode = 4;
+ if (cycle_time > 120) mode = 3; /* 120 ns for PIO mode 4 */
+ if (cycle_time > 180) mode = 2; /* 180 ns for PIO mode 3 */
+ if (cycle_time > 240) mode = 1; /* 240 ns for PIO mode 4 */
+ if (cycle_time > 383) mode = 0; /* 383 ns for PIO mode 4 */
+ }
+ printf ("PIO mode to use: PIO %d\n", mode);
+#endif /* 0 */
+
+#ifdef CONFIG_ATAPI
+ if (dev_desc->if_type==IF_TYPE_ATAPI) {
+ atapi_inquiry(dev_desc);
+ return;
+ }
+#endif /* CONFIG_ATAPI */
+
+ /* swap shorts */
+ dev_desc->lba = (iop->lba_capacity << 16) | (iop->lba_capacity >> 16);
+ /* assuming HD */
+ dev_desc->type=DEV_TYPE_HARDDISK;
+ dev_desc->blksz=ATA_BLOCKSIZE;
+ dev_desc->lun=0; /* just to fill something in... */
+
+#if 0 /* only used to test the powersaving mode,
+ * if enabled, the drive goes after 5 sec
+ * in standby mode */
+ outb (device, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(device));
+ c = ide_wait (device, IDE_TIME_OUT);
+ outb (device, ATA_SECT_CNT, 1);
+ outb (device, ATA_LBA_LOW, 0);
+ outb (device, ATA_LBA_MID, 0);
+ outb (device, ATA_LBA_HIGH, 0);
+ outb (device, ATA_DEV_HD, ATA_LBA |
+ ATA_DEVICE(device));
+ outb (device, ATA_COMMAND, 0xe3);
+ udelay (50);
+ c = ide_wait (device, IDE_TIME_OUT); /* can't take over 500 ms */
+#endif
+}
+
+
+/* ------------------------------------------------------------------------- */
+
+ulong ide_read (int device, ulong blknr, ulong blkcnt, ulong *buffer)
+{
+ ulong n = 0;
+ unsigned char c;
+ unsigned char pwrsave=0; /* power save */
+
+ PRINTF ("ide_read dev %d start %lX, blocks %lX buffer at %lX\n",
+ device, blknr, blkcnt, (ulong)buffer);
+
+ ide_led (DEVICE_LED(device), 1); /* LED on */
+
+ /* Select device
+ */
+ outb (device, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(device));
+ c = ide_wait (device, IDE_TIME_OUT);
+
+ if (c & ATA_STAT_BUSY) {
+ printf ("IDE read: device %d not ready\n", device);
+ goto IDE_READ_E;
+ }
+
+ /* first check if the drive is in Powersaving mode, if yes,
+ * increase the timeout value */
+ outb (device, ATA_COMMAND, ATA_CMD_CHK_PWR);
+ udelay (50);
+
+ c = ide_wait (device, IDE_TIME_OUT); /* can't take over 500 ms */
+
+ if (c & ATA_STAT_BUSY) {
+ printf ("IDE read: device %d not ready\n", device);
+ goto IDE_READ_E;
+ }
+ if ((c & ATA_STAT_ERR) == ATA_STAT_ERR) {
+ printf ("No Powersaving mode %X\n", c);
+ } else {
+ c = inb(device,ATA_SECT_CNT);
+ PRINTF("Powersaving %02X\n",c);
+ if(c==0)
+ pwrsave=1;
+ }
+
+
+ while (blkcnt-- > 0) {
+
+ c = ide_wait (device, IDE_TIME_OUT);
+
+ if (c & ATA_STAT_BUSY) {
+ printf ("IDE read: device %d not ready\n", device);
+ break;
+ }
+
+ outb (device, ATA_SECT_CNT, 1);
+ outb (device, ATA_LBA_LOW, (blknr >> 0) & 0xFF);
+ outb (device, ATA_LBA_MID, (blknr >> 8) & 0xFF);
+ outb (device, ATA_LBA_HIGH, (blknr >> 16) & 0xFF);
+ outb (device, ATA_DEV_HD, ATA_LBA |
+ ATA_DEVICE(device) |
+ ((blknr >> 24) & 0xF) );
+ outb (device, ATA_COMMAND, ATA_CMD_READ);
+
+ udelay (50);
+
+ if(pwrsave) {
+ c = ide_wait (device, IDE_SPIN_UP_TIME_OUT); /* may take up to 4 sec */
+ pwrsave=0;
+ } else {
+ c = ide_wait (device, IDE_TIME_OUT); /* can't take over 500 ms */
+ }
+
+ if ((c&(ATA_STAT_DRQ|ATA_STAT_BUSY|ATA_STAT_ERR)) != ATA_STAT_DRQ) {
+ printf ("Error (no IRQ) dev %d blk %ld: status 0x%02x\n",
+ device, blknr, c);
+ break;
+ }
+
+ input_data (device, buffer, ATA_SECTORWORDS);
+ (void) inb (device, ATA_STATUS); /* clear IRQ */
+
+ ++n;
+ ++blknr;
+ buffer += ATA_SECTORWORDS;
+ }
+IDE_READ_E:
+ ide_led (DEVICE_LED(device), 0); /* LED off */
+ return (n);
+}
+
+/* ------------------------------------------------------------------------- */
+
+
+ulong ide_write (int device, ulong blknr, ulong blkcnt, ulong *buffer)
+{
+ ulong n = 0;
+ unsigned char c;
+
+ ide_led (DEVICE_LED(device), 1); /* LED on */
+
+ /* Select device
+ */
+ outb (device, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(device));
+
+ while (blkcnt-- > 0) {
+
+ c = ide_wait (device, IDE_TIME_OUT);
+
+ if (c & ATA_STAT_BUSY) {
+ printf ("IDE read: device %d not ready\n", device);
+ goto WR_OUT;
+ }
+
+ outb (device, ATA_SECT_CNT, 1);
+ outb (device, ATA_LBA_LOW, (blknr >> 0) & 0xFF);
+ outb (device, ATA_LBA_MID, (blknr >> 8) & 0xFF);
+ outb (device, ATA_LBA_HIGH, (blknr >> 16) & 0xFF);
+ outb (device, ATA_DEV_HD, ATA_LBA |
+ ATA_DEVICE(device) |
+ ((blknr >> 24) & 0xF) );
+ outb (device, ATA_COMMAND, ATA_CMD_WRITE);
+
+ udelay (50);
+
+ c = ide_wait (device, IDE_TIME_OUT); /* can't take over 500 ms */
+
+ if ((c&(ATA_STAT_DRQ|ATA_STAT_BUSY|ATA_STAT_ERR)) != ATA_STAT_DRQ) {
+ printf ("Error (no IRQ) dev %d blk %ld: status 0x%02x\n",
+ device, blknr, c);
+ goto WR_OUT;
+ }
+
+ output_data (device, buffer, ATA_SECTORWORDS);
+ c = inb (device, ATA_STATUS); /* clear IRQ */
+ ++n;
+ ++blknr;
+ buffer += ATA_SECTORWORDS;
+ }
+WR_OUT:
+ ide_led (DEVICE_LED(device), 0); /* LED off */
+ return (n);
+}
+
+/* ------------------------------------------------------------------------- */
+
+/*
+ * copy src to dest, skipping leading and trailing blanks and null
+ * terminate the string
+ */
+static void ident_cpy (unsigned char *dest, unsigned char *src, unsigned int len)
+{
+ int start,end;
+
+ start=0;
+ while (start<len) {
+ if (src[start]!=' ')
+ break;
+ start++;
+ }
+ end=len-1;
+ while (end>start) {
+ if (src[end]!=' ')
+ break;
+ end--;
+ }
+ for ( ; start<=end; start++) {
+ *dest++=src[start];
+ }
+ *dest='\0';
+}
+
+/* ------------------------------------------------------------------------- */
+
+/*
+ * Wait until Busy bit is off, or timeout (in ms)
+ * Return last status
+ */
+static uchar ide_wait (int dev, ulong t)
+{
+ ulong delay = 10 * t; /* poll every 100 us */
+ uchar c;
+
+ while ((c = inb(dev, ATA_STATUS)) & ATA_STAT_BUSY) {
+ udelay (100);
+ if (delay-- == 0) {
+ break;
+ }
+ }
+ return (c);
+}
+
+/* ------------------------------------------------------------------------- */
+
+#ifdef CONFIG_IDE_RESET
+extern void ide_set_reset(int idereset);
+
+static void ide_reset (void)
+{
+#if defined(CFG_PB_12V_ENABLE) || defined(CFG_PB_IDE_MOTOR)
+ volatile immap_t *immr = (immap_t *)CFG_IMMR;
+#endif
+ int i;
+
+ curr_device = -1;
+ for (i=0; i<CFG_IDE_MAXBUS; ++i)
+ ide_bus_ok[i] = 0;
+ for (i=0; i<CFG_IDE_MAXDEVICE; ++i)
+ ide_dev_desc[i].type = DEV_TYPE_UNKNOWN;
+
+ ide_set_reset (1); /* assert reset */
+
+ WATCHDOG_RESET();
+
+#ifdef CFG_PB_12V_ENABLE
+ immr->im_cpm.cp_pbdat &= ~(CFG_PB_12V_ENABLE); /* 12V Enable output OFF */
+ immr->im_cpm.cp_pbpar &= ~(CFG_PB_12V_ENABLE);
+ immr->im_cpm.cp_pbodr &= ~(CFG_PB_12V_ENABLE);
+ immr->im_cpm.cp_pbdir |= CFG_PB_12V_ENABLE;
+
+ /* wait 500 ms for the voltage to stabilize
+ */
+ for (i=0; i<500; ++i) {
+ udelay (1000);
+ }
+
+ immr->im_cpm.cp_pbdat |= CFG_PB_12V_ENABLE; /* 12V Enable output ON */
+#endif /* CFG_PB_12V_ENABLE */
+
+#ifdef CFG_PB_IDE_MOTOR
+ /* configure IDE Motor voltage monitor pin as input */
+ immr->im_cpm.cp_pbpar &= ~(CFG_PB_IDE_MOTOR);
+ immr->im_cpm.cp_pbodr &= ~(CFG_PB_IDE_MOTOR);
+ immr->im_cpm.cp_pbdir &= ~(CFG_PB_IDE_MOTOR);
+
+ /* wait up to 1 s for the motor voltage to stabilize
+ */
+ for (i=0; i<1000; ++i) {
+ if ((immr->im_cpm.cp_pbdat & CFG_PB_IDE_MOTOR) != 0) {
+ break;
+ }
+ udelay (1000);
+ }
+
+ if (i == 1000) { /* Timeout */
+ printf ("\nWarning: 5V for IDE Motor missing\n");
+# ifdef CONFIG_STATUS_LED
+# ifdef STATUS_LED_YELLOW
+ status_led_set (STATUS_LED_YELLOW, STATUS_LED_ON );
+# endif
+# ifdef STATUS_LED_GREEN
+ status_led_set (STATUS_LED_GREEN, STATUS_LED_OFF);
+# endif
+# endif /* CONFIG_STATUS_LED */
+ }
+#endif /* CFG_PB_IDE_MOTOR */
+
+ WATCHDOG_RESET();
+
+ /* de-assert RESET signal */
+ ide_set_reset(0);
+
+ /* wait 250 ms */
+ for (i=0; i<250; ++i) {
+ udelay (1000);
+ }
+}
+
+#endif /* CONFIG_IDE_RESET */
+
+/* ------------------------------------------------------------------------- */
+
+#ifdef CONFIG_IDE_LED
+
+static uchar led_buffer = 0; /* Buffer for current LED status */
+
+static void ide_led (uchar led, uchar status)
+{
+ uchar *led_port = LED_PORT;
+
+ if (status) { /* switch LED on */
+ led_buffer |= led;
+ } else { /* switch LED off */
+ led_buffer &= ~led;
+ }
+
+ *led_port = led_buffer;
+}
+
+#endif /* CONFIG_IDE_LED */
+
+/* ------------------------------------------------------------------------- */
+
+#ifdef CONFIG_ATAPI
+/****************************************************************************
+ * ATAPI Support
+ */
+
+
+
+#undef ATAPI_DEBUG
+
+#ifdef ATAPI_DEBUG
+#define AT_PRINTF(fmt,args...) printf (fmt ,##args)
+#else
+#define AT_PRINTF(fmt,args...)
+#endif
+
+/* since ATAPI may use commands with not 4 bytes alligned length
+ * we have our own transfer functions, 2 bytes alligned */
+static void
+output_data_shorts(int dev, ushort *sect_buf, int shorts)
+{
+ ushort *dbuf;
+ volatile ushort *pbuf;
+
+ pbuf = (ushort *)(ATA_CURR_BASE(dev)+ATA_DATA_REG);
+ dbuf = (ushort *)sect_buf;
+ while (shorts--) {
+ __asm__ volatile ("eieio");
+ *pbuf = *dbuf++;
+ }
+}
+
+static void
+input_data_shorts(int dev, ushort *sect_buf, int shorts)
+{
+ ushort *dbuf;
+ volatile ushort *pbuf;
+
+ pbuf = (ushort *)(ATA_CURR_BASE(dev)+ATA_DATA_REG);
+ dbuf = (ushort *)sect_buf;
+ while (shorts--) {
+ __asm__ volatile ("eieio");
+ *dbuf++ = *pbuf;
+ }
+}
+
+/*
+ * Wait until (Status & mask) == res, or timeout (in ms)
+ * Return last status
+ * This is used since some ATAPI CD ROMs clears their Busy Bit first
+ * and then they set their DRQ Bit
+ */
+static uchar atapi_wait_mask (int dev, ulong t,uchar mask, uchar res)
+{
+ ulong delay = 10 * t; /* poll every 100 us */
+ uchar c;
+
+ c = inb(dev,ATA_DEV_CTL); /* prevents to read the status before valid */
+ while (((c = inb(dev, ATA_STATUS)) & mask)
+ != res) {
+ /* break if error occurs (doesn't make sense to wait more) */
+ if((c & ATA_STAT_ERR)==ATA_STAT_ERR)
+ break;
+ udelay (100);
+ if (delay-- == 0) {
+ break;
+ }
+ }
+ return (c);
+}
+
+/*
+ * issue an atapi command
+ */
+unsigned char atapi_issue(int device,unsigned char* ccb,int ccblen, unsigned char * buffer,int buflen)
+{
+ unsigned char c,err,mask,res;
+ int n;
+ ide_led (DEVICE_LED(device), 1); /* LED on */
+
+ /* Select device
+ */
+ mask = ATA_STAT_BUSY|ATA_STAT_DRQ;
+ res = 0;
+ outb (device, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(device));
+ c = atapi_wait_mask(device,ATAPI_TIME_OUT,mask,res);
+ if ((c & mask) != res) {
+ printf ("ATAPI_ISSUE: device %d not ready status %X\n", device,c);
+ err=0xFF;
+ goto AI_OUT;
+ }
+ /* write taskfile */
+ outb (device, ATA_ERROR_REG, 0); /* no DMA, no overlaped */
+ outb (device, ATA_CYL_LOW, (unsigned char)(buflen & 0xFF));
+ outb (device, ATA_CYL_HIGH, (unsigned char)((buflen<<8) & 0xFF));
+ outb (device, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(device));
+
+ outb (device, ATA_COMMAND, ATAPI_CMD_PACKET);
+ udelay (50);
+
+ mask = ATA_STAT_DRQ|ATA_STAT_BUSY|ATA_STAT_ERR;
+ res = ATA_STAT_DRQ;
+ c = atapi_wait_mask(device,ATAPI_TIME_OUT,mask,res);
+
+ if ((c & mask) != res) { /* DRQ must be 1, BSY 0 */
+ printf ("ATTAPI_ISSUE: Error (no IRQ) before sending ccb dev %d status 0x%02x\n",device,c);
+ err=0xFF;
+ goto AI_OUT;
+ }
+
+ output_data_shorts (device, (unsigned short *)ccb,ccblen/2); /* write command block */
+ /* ATAPI Command written wait for completition */
+ udelay (5000); /* device must set bsy */
+
+ mask = ATA_STAT_DRQ|ATA_STAT_BUSY|ATA_STAT_ERR;
+ /* if no data wait for DRQ = 0 BSY = 0
+ * if data wait for DRQ = 1 BSY = 0 */
+ res=0;
+ if(buflen)
+ res = ATA_STAT_DRQ;
+ c = atapi_wait_mask(device,ATAPI_TIME_OUT,mask,res);
+ if ((c & mask) != res ) {
+ if (c & ATA_STAT_ERR) {
+ err=(inb(device,ATA_ERROR_REG))>>4;
+ AT_PRINTF("atapi_issue 1 returned sense key %X status %02X\n",err,c);
+ } else {
+ printf ("ATTAPI_ISSUE: (no DRQ) after sending ccb (%x) status 0x%02x\n", ccb[0],c);
+ err=0xFF;
+ }
+ goto AI_OUT;
+ }
+ n=inb(device, ATA_CYL_HIGH);
+ n<<=8;
+ n+=inb(device, ATA_CYL_LOW);
+ if(n>buflen) {
+ printf("ERROR, transfer bytes %d requested only %d\n",n,buflen);
+ err=0xff;
+ goto AI_OUT;
+ }
+ if((n==0)&&(buflen<0)) {
+ printf("ERROR, transfer bytes %d requested %d\n",n,buflen);
+ err=0xff;
+ goto AI_OUT;
+ }
+ if(n!=buflen) {
+ AT_PRINTF("WARNING, transfer bytes %d not equal with requested %d\n",n,buflen);
+ }
+ if(n!=0) { /* data transfer */
+ AT_PRINTF("ATAPI_ISSUE: %d Bytes to transfer\n",n);
+ /* we transfer shorts */
+ n>>=1;
+ /* ok now decide if it is an in or output */
+ if ((inb(device, ATA_SECT_CNT)&0x02)==0) {
+ AT_PRINTF("Write to device\n");
+ output_data_shorts(device,(unsigned short *)buffer,n);
+ } else {
+ AT_PRINTF("Read from device @ %p shorts %d\n",buffer,n);
+ input_data_shorts(device,(unsigned short *)buffer,n);
+ }
+ }
+ udelay(5000); /* seems that some CD ROMs need this... */
+ mask = ATA_STAT_BUSY|ATA_STAT_ERR;
+ res=0;
+ c = atapi_wait_mask(device,ATAPI_TIME_OUT,mask,res);
+ if ((c & ATA_STAT_ERR) == ATA_STAT_ERR) {
+ err=(inb(device,ATA_ERROR_REG) >> 4);
+ AT_PRINTF("atapi_issue 2 returned sense key %X status %X\n",err,c);
+ } else {
+ err = 0;
+ }
+AI_OUT:
+ ide_led (DEVICE_LED(device), 0); /* LED off */
+ return (err);
+}
+
+/*
+ * sending the command to atapi_issue. If an status other than good
+ * returns, an request_sense will be issued
+ */
+
+#define ATAPI_DRIVE_NOT_READY 100
+#define ATAPI_UNIT_ATTN 10
+
+unsigned char atapi_issue_autoreq (int device,
+ unsigned char* ccb,
+ int ccblen,
+ unsigned char *buffer,
+ int buflen)
+{
+ unsigned char sense_data[18],sense_ccb[12];
+ unsigned char res,key,asc,ascq;
+ int notready,unitattn;
+
+ unitattn=ATAPI_UNIT_ATTN;
+ notready=ATAPI_DRIVE_NOT_READY;
+
+retry:
+ res= atapi_issue(device,ccb,ccblen,buffer,buflen);
+ if (res==0)
+ return (0); /* Ok */
+
+ if (res==0xFF)
+ return (0xFF); /* error */
+
+ AT_PRINTF("(auto_req)atapi_issue returned sense key %X\n",res);
+
+ memset(sense_ccb,0,sizeof(sense_ccb));
+ memset(sense_data,0,sizeof(sense_data));
+ sense_ccb[0]=ATAPI_CMD_REQ_SENSE;
+ sense_ccb[4]=18; /* allocation Legnth */
+
+ res=atapi_issue(device,sense_ccb,12,sense_data,18);
+ key=(sense_data[2]&0xF);
+ asc=(sense_data[12]);
+ ascq=(sense_data[13]);
+
+ AT_PRINTF("ATAPI_CMD_REQ_SENSE returned %x\n",res);
+ AT_PRINTF(" Sense page: %02X key %02X ASC %02X ASCQ %02X\n",
+ sense_data[0],
+ key,
+ asc,
+ ascq);
+
+ if((key==0))
+ return 0; /* ok device ready */
+
+ if((key==6)|| (asc==0x29) || (asc==0x28)) { /* Unit Attention */
+ if(unitattn-->0) {
+ udelay(200*1000);
+ goto retry;
+ }
+ printf("Unit Attention, tried %d\n",ATAPI_UNIT_ATTN);
+ goto error;
+ }
+ if((asc==0x4) && (ascq==0x1)) { /* not ready, but will be ready soon */
+ if (notready-->0) {
+ udelay(200*1000);
+ goto retry;
+ }
+ printf("Drive not ready, tried %d times\n",ATAPI_DRIVE_NOT_READY);
+ goto error;
+ }
+ if(asc==0x3a) {
+ AT_PRINTF("Media not present\n");
+ goto error;
+ }
+ printf ("ERROR: Unknown Sense key %02X ASC %02X ASCQ %02X\n",key,asc,ascq);
+error:
+ AT_PRINTF ("ERROR Sense key %02X ASC %02X ASCQ %02X\n",key,asc,ascq);
+ return (0xFF);
+}
+
+
+
+static void atapi_inquiry(block_dev_desc_t * dev_desc)
+{
+ unsigned char ccb[12]; /* Command descriptor block */
+ unsigned char iobuf[64]; /* temp buf */
+ unsigned char c;
+ int device;
+
+ device=dev_desc->dev;
+ dev_desc->type=DEV_TYPE_UNKNOWN; /* not yet valid */
+ dev_desc->block_read=atapi_read;
+
+ memset(ccb,0,sizeof(ccb));
+ memset(iobuf,0,sizeof(iobuf));
+
+ ccb[0]=ATAPI_CMD_INQUIRY;
+ ccb[4]=40; /* allocation Legnth */
+ c=atapi_issue_autoreq(device,ccb,12,(unsigned char *)iobuf,40);
+
+ AT_PRINTF("ATAPI_CMD_INQUIRY returned %x\n",c);
+ if (c!=0)
+ return;
+
+ /* copy device ident strings */
+ ident_cpy(dev_desc->vendor,&iobuf[8],8);
+ ident_cpy(dev_desc->product,&iobuf[16],16);
+ ident_cpy(dev_desc->revision,&iobuf[32],5);
+
+ dev_desc->lun=0;
+ dev_desc->lba=0;
+ dev_desc->blksz=0;
+ dev_desc->type=iobuf[0] & 0x1f;
+
+ if ((iobuf[1]&0x80)==0x80)
+ dev_desc->removable = 1;
+ else
+ dev_desc->removable = 0;
+
+ memset(ccb,0,sizeof(ccb));
+ memset(iobuf,0,sizeof(iobuf));
+ ccb[0]=ATAPI_CMD_START_STOP;
+ ccb[4]=0x03; /* start */
+
+ c=atapi_issue_autoreq(device,ccb,12,(unsigned char *)iobuf,0);
+
+ AT_PRINTF("ATAPI_CMD_START_STOP returned %x\n",c);
+ if (c!=0)
+ return;
+
+ memset(ccb,0,sizeof(ccb));
+ memset(iobuf,0,sizeof(iobuf));
+ c=atapi_issue_autoreq(device,ccb,12,(unsigned char *)iobuf,0);
+
+ AT_PRINTF("ATAPI_CMD_UNIT_TEST_READY returned %x\n",c);
+ if (c!=0)
+ return;
+
+ memset(ccb,0,sizeof(ccb));
+ memset(iobuf,0,sizeof(iobuf));
+ ccb[0]=ATAPI_CMD_READ_CAP;
+ c=atapi_issue_autoreq(device,ccb,12,(unsigned char *)iobuf,8);
+ AT_PRINTF("ATAPI_CMD_READ_CAP returned %x\n",c);
+ if (c!=0)
+ return;
+
+ AT_PRINTF("Read Cap: LBA %02X%02X%02X%02X blksize %02X%02X%02X%02X\n",
+ iobuf[0],iobuf[1],iobuf[2],iobuf[3],
+ iobuf[4],iobuf[5],iobuf[6],iobuf[7]);
+
+ dev_desc->lba =((unsigned long)iobuf[0]<<24) +
+ ((unsigned long)iobuf[1]<<16) +
+ ((unsigned long)iobuf[2]<< 8) +
+ ((unsigned long)iobuf[3]);
+ dev_desc->blksz=((unsigned long)iobuf[4]<<24) +
+ ((unsigned long)iobuf[5]<<16) +
+ ((unsigned long)iobuf[6]<< 8) +
+ ((unsigned long)iobuf[7]);
+ return;
+}
+
+
+/*
+ * atapi_read:
+ * we transfer only one block per command, since the multiple DRQ per
+ * command is not yet implemented
+ */
+#define ATAPI_READ_MAX_BYTES 2048 /* we read max 2kbytes */
+#define ATAPI_READ_BLOCK_SIZE 2048 /* assuming CD part */
+#define ATAPI_READ_MAX_BLOCK ATAPI_READ_MAX_BYTES/ATAPI_READ_BLOCK_SIZE /* max blocks */
+
+ulong atapi_read (int device, ulong blknr, ulong blkcnt, ulong *buffer)
+{
+ ulong n = 0;
+ unsigned char ccb[12]; /* Command descriptor block */
+ ulong cnt;
+
+ AT_PRINTF("atapi_read dev %d start %lX, blocks %lX buffer at %lX\n",
+ device, blknr, blkcnt, (ulong)buffer);
+
+ do {
+ if (blkcnt>ATAPI_READ_MAX_BLOCK) {
+ cnt=ATAPI_READ_MAX_BLOCK;
+ } else {
+ cnt=blkcnt;
+ }
+ ccb[0]=ATAPI_CMD_READ_12;
+ ccb[1]=0; /* reserved */
+ ccb[2]=(unsigned char) (blknr>>24) & 0xFF; /* MSB Block */
+ ccb[3]=(unsigned char) (blknr>>16) & 0xFF; /* */
+ ccb[4]=(unsigned char) (blknr>> 8) & 0xFF;
+ ccb[5]=(unsigned char) blknr & 0xFF; /* LSB Block */
+ ccb[6]=(unsigned char) (cnt >>24) & 0xFF; /* MSB Block count */
+ ccb[7]=(unsigned char) (cnt >>16) & 0xFF;
+ ccb[8]=(unsigned char) (cnt >> 8) & 0xFF;
+ ccb[9]=(unsigned char) cnt & 0xFF; /* LSB Block */
+ ccb[10]=0; /* reserved */
+ ccb[11]=0; /* reserved */
+
+ if (atapi_issue_autoreq(device,ccb,12,
+ (unsigned char *)buffer,
+ cnt*ATAPI_READ_BLOCK_SIZE) == 0xFF) {
+ return (n);
+ }
+ n+=cnt;
+ blkcnt-=cnt;
+ blknr+=cnt;
+ buffer+=cnt*(ATAPI_READ_BLOCK_SIZE/4); /* ulong blocksize in ulong */
+ } while (blkcnt > 0);
+ return (n);
+}
+
+/* ------------------------------------------------------------------------- */
+
+#endif /* CONFIG_ATAPI */
+
+#endif /* CONFIG_COMMANDS & CFG_CMD_IDE */
--- /dev/null
+/*
+ * (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
+ */
+
+/*
+ * MPC8xx/MPC8260 Internal Memory Map Functions
+ */
+
+#include <common.h>
+#include <command.h>
+#include <cmd_immap.h>
+
+#if (CONFIG_COMMANDS & CFG_CMD_IMMAP) && \
+ (defined(CONFIG_8xx) || defined(CONFIG_8260))
+
+#if defined(CONFIG_8xx)
+#include <asm/8xx_immap.h>
+#include <commproc.h>
+#elif defined(CONFIG_8260)
+#include <asm/immap_8260.h>
+#include <asm/cpm_8260.h>
+#include <asm/iopin_8260.h>
+#endif
+
+static void
+unimplemented ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+ printf ("Sorry, but the '%s' command has not been implemented\n",
+ cmdtp->name);
+}
+
+int
+do_siuinfo (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+ volatile immap_t *immap = (immap_t *) CFG_IMMR;
+
+#if defined(CONFIG_8xx)
+ volatile sysconf8xx_t *sc = &immap->im_siu_conf;
+#elif defined(CONFIG_8260)
+ volatile sysconf8260_t *sc = &immap->im_siu_conf;
+#endif
+
+ printf ("SIUMCR= %08x SYPCR = %08x\n", sc->sc_siumcr, sc->sc_sypcr);
+#if defined(CONFIG_8xx)
+ printf ("SWT = %08x\n", sc->sc_swt);
+ printf ("SIPEND= %08x SIMASK= %08x\n", sc->sc_sipend, sc->sc_simask);
+ printf ("SIEL = %08x SIVEC = %08x\n", sc->sc_siel, sc->sc_sivec);
+ printf ("TESR = %08x SDCR = %08x\n", sc->sc_tesr, sc->sc_sdcr);
+#elif defined(CONFIG_8260)
+ printf ("BCR = %08x\n", sc->sc_bcr);
+ printf ("P_ACR = %02x P_ALRH= %08x P_ALRL= %08x\n",
+ sc->sc_ppc_acr, sc->sc_ppc_alrh, sc->sc_ppc_alrl);
+ printf ("L_ACR = %02x L_ALRH= %08x L_ALRL= %08x\n",
+ sc->sc_lcl_acr, sc->sc_lcl_alrh, sc->sc_lcl_alrl);
+ printf ("PTESR1= %08x PTESR2= %08x\n", sc->sc_tescr1, sc->sc_tescr2);
+ printf ("LTESR1= %08x LTESR2= %08x\n", sc->sc_ltescr1, sc->sc_ltescr2);
+ printf ("PDTEA = %08x PDTEM = %02x\n", sc->sc_pdtea, sc->sc_pdtem);
+ printf ("LDTEA = %08x LDTEM = %02x\n", sc->sc_ldtea, sc->sc_ldtem);
+#endif
+ return 0;
+}
+
+int
+do_memcinfo (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+ volatile immap_t *immap = (immap_t *) CFG_IMMR;
+
+#if defined(CONFIG_8xx)
+ volatile memctl8xx_t *memctl = &immap->im_memctl;
+ int nbanks = 8;
+#elif defined(CONFIG_8260)
+ volatile memctl8260_t *memctl = &immap->im_memctl;
+ int nbanks = 12;
+#endif
+ volatile uint *p = &memctl->memc_br0;
+ int i;
+
+ for (i = 0; i < nbanks; i++, p += 2) {
+ if (i < 10) {
+ printf ("BR%d = %08x OR%d = %08x\n",
+ i, p[0], i, p[1]);
+ } else {
+ printf ("BR%d = %08x OR%d = %08x\n",
+ i, p[0], i, p[1]);
+ }
+ }
+
+ printf ("MAR = %08x", memctl->memc_mar);
+#if defined(CONFIG_8xx)
+ printf (" MCR = %08x\n", memctl->memc_mcr);
+#elif defined(CONFIG_8260)
+ printf ("\n");
+#endif
+ printf ("MAMR = %08x MBMR = %08x",
+ memctl->memc_mamr, memctl->memc_mbmr);
+#if defined(CONFIG_8xx)
+ printf ("\nMSTAT = %04x\n", memctl->memc_mstat);
+#elif defined(CONFIG_8260)
+ printf (" MCMR = %08x\n", memctl->memc_mcmr);
+#endif
+ printf ("MPTPR = %04x MDR = %08x\n",
+ memctl->memc_mptpr, memctl->memc_mdr);
+#if defined(CONFIG_8260)
+ printf ("PSDMR = %08x LSDMR = %08x\n",
+ memctl->memc_psdmr, memctl->memc_lsdmr);
+ printf ("PURT = %02x PSRT = %02x\n",
+ memctl->memc_purt, memctl->memc_psrt);
+ printf ("LURT = %02x LSRT = %02x\n",
+ memctl->memc_lurt, memctl->memc_lsrt);
+ printf ("IMMR = %08x\n", memctl->memc_immr);
+#endif
+ return 0;
+}
+
+int
+do_sitinfo (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+ unimplemented (cmdtp, flag, argc, argv);
+ return 0;
+}
+
+#ifdef CONFIG_8260
+int
+do_icinfo (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+ unimplemented (cmdtp, flag, argc, argv);
+ return 0;
+}
+#endif
+
+int
+do_carinfo (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+ unimplemented (cmdtp, flag, argc, argv);
+ return 0;
+}
+
+static int counter;
+
+static void
+header(void)
+{
+ char *data = "\
+ -------------------------------- --------------------------------\
+ 00000000001111111111222222222233 00000000001111111111222222222233\
+ 01234567890123456789012345678901 01234567890123456789012345678901\
+ -------------------------------- --------------------------------\
+ ";
+ int i;
+
+ if (counter % 2)
+ putc('\n');
+ counter = 0;
+
+ for (i = 0; i < 4; i++, data += 79)
+ printf("%.79s\n", data);
+}
+
+static void binary (char *label, uint value, int nbits)
+{
+ uint mask = 1 << (nbits - 1);
+ int i, second = (counter++ % 2);
+
+ if (second)
+ putc (' ');
+ puts (label);
+ for (i = 32 + 1; i != nbits; i--)
+ putc (' ');
+
+ while (mask != 0) {
+ if (value & mask)
+ putc ('1');
+ else
+ putc ('0');
+ mask >>= 1;
+ }
+
+ if (second)
+ putc ('\n');
+}
+
+#if defined(CONFIG_8xx)
+#define PA_NBITS 16
+#define PA_NB_ODR 8
+#define PB_NBITS 18
+#define PB_NB_ODR 16
+#define PC_NBITS 12
+#define PD_NBITS 13
+#elif defined(CONFIG_8260)
+#define PA_NBITS 32
+#define PA_NB_ODR 32
+#define PB_NBITS 28
+#define PB_NB_ODR 28
+#define PC_NBITS 32
+#define PD_NBITS 28
+#endif
+
+int
+do_iopinfo (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+ volatile immap_t *immap = (immap_t *) CFG_IMMR;
+
+#if defined(CONFIG_8xx)
+ volatile iop8xx_t *iop = &immap->im_ioport;
+ volatile ushort *l, *r;
+#elif defined(CONFIG_8260)
+ volatile iop8260_t *iop = &immap->im_ioport;
+ volatile uint *l, *r;
+#endif
+ volatile uint *R;
+
+ counter = 0;
+ header ();
+
+ /*
+ * Ports A & B
+ */
+
+#if defined(CONFIG_8xx)
+ l = &iop->iop_padir;
+ R = &immap->im_cpm.cp_pbdir;
+#elif defined(CONFIG_8260)
+ l = &iop->iop_pdira;
+ R = &iop->iop_pdirb;
+#endif
+ binary ("PA_DIR", *l++, PA_NBITS);
+ binary ("PB_DIR", *R++, PB_NBITS);
+ binary ("PA_PAR", *l++, PA_NBITS);
+ binary ("PB_PAR", *R++, PB_NBITS);
+#if defined(CONFIG_8260)
+ binary ("PA_SOR", *l++, PA_NBITS);
+ binary ("PB_SOR", *R++, PB_NBITS);
+#endif
+ binary ("PA_ODR", *l++, PA_NB_ODR);
+ binary ("PB_ODR", *R++, PB_NB_ODR);
+ binary ("PA_DAT", *l++, PA_NBITS);
+ binary ("PB_DAT", *R++, PB_NBITS);
+
+ header ();
+
+ /*
+ * Ports C & D
+ */
+
+#if defined(CONFIG_8xx)
+ l = &iop->iop_pcdir;
+ r = &iop->iop_pddir;
+#elif defined(CONFIG_8260)
+ l = &iop->iop_pdirc;
+ r = &iop->iop_pdird;
+#endif
+ binary ("PC_DIR", *l++, PC_NBITS);
+ binary ("PD_DIR", *r++, PD_NBITS);
+ binary ("PC_PAR", *l++, PC_NBITS);
+ binary ("PD_PAR", *r++, PD_NBITS);
+#if defined(CONFIG_8xx)
+ binary ("PC_SO ", *l++, PC_NBITS);
+ binary (" ", 0, 0);
+ r++;
+#elif defined(CONFIG_8260)
+ binary ("PC_SOR", *l++, PC_NBITS);
+ binary ("PD_SOR", *r++, PD_NBITS);
+ binary ("PC_ODR", *l++, PC_NBITS);
+ binary ("PD_ODR", *r++, PD_NBITS);
+#endif
+ binary ("PC_DAT", *l++, PC_NBITS);
+ binary ("PD_DAT", *r++, PD_NBITS);
+#if defined(CONFIG_8xx)
+ binary ("PC_INT", *l++, PC_NBITS);
+#endif
+
+ header ();
+ return 0;
+}
+
+/*
+ * set the io pins
+ * this needs a clean up for smaller tighter code
+ * use *uint and set the address based on cmd + port
+ */
+int
+do_iopset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+#if defined(CONFIG_8260)
+ uint rcode = 0;
+ static uint port = 0;
+ static uint pin = 0;
+ static uint value = 0;
+ static enum { DIR, PAR, SOR, ODR, DAT } cmd = DAT;
+ iopin_t iopin;
+
+ if (argc != 5) {
+ printf ("iopset PORT PIN CMD VALUE\n");
+ return 1;
+ }
+ port = argv[1][0] - 'A';
+ if (port > 3)
+ port -= 0x20;
+ if (port > 3)
+ rcode = 1;
+ pin = simple_strtol (argv[2], NULL, 10);
+ if (pin > 31)
+ rcode = 1;
+
+
+ switch (argv[3][0]) {
+ case 'd':
+ if (argv[3][1] == 'a')
+ cmd = DAT;
+ else if (argv[3][1] == 'i')
+ cmd = DIR;
+ else
+ rcode = 1;
+ break;
+ case 'p':
+ cmd = PAR;
+ break;
+ case 'o':
+ cmd = ODR;
+ break;
+ case 's':
+ cmd = SOR;
+ break;
+ default:
+ printf ("iopset: unknown command %s\n", argv[3]);
+ rcode = 1;
+ }
+ if (argv[4][0] == '1')
+ value = 1;
+ else if (argv[4][0] == '0')
+ value = 0;
+ else
+ rcode = 1;
+ if (rcode == 0) {
+ iopin.port = port;
+ iopin.pin = pin;
+ switch (cmd) {
+ case DIR:
+ if (value)
+ iopin_set_out (&iopin);
+ else
+ iopin_set_in (&iopin);
+ break;
+ case PAR:
+ if (value)
+ iopin_set_ded (&iopin);
+ else
+ iopin_set_gen (&iopin);
+ break;
+ case SOR:
+ if (value)
+ iopin_set_opt2 (&iopin);
+ else
+ iopin_set_opt1 (&iopin);
+ break;
+ case ODR:
+ if (value)
+ iopin_set_odr (&iopin);
+ else
+ iopin_set_act (&iopin);
+ break;
+ case DAT:
+ if (value)
+ iopin_set_high (&iopin);
+ else
+ iopin_set_low (&iopin);
+ break;
+ }
+
+ }
+ return rcode;
+#else
+ unimplemented (cmdtp, flag, argc, argv);
+ return 0;
+#endif
+}
+
+int
+do_dmainfo (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+ unimplemented (cmdtp, flag, argc, argv);
+ return 0;
+}
+
+int
+do_fccinfo (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+ unimplemented (cmdtp, flag, argc, argv);
+ return 0;
+}
+
+static void prbrg (int n, uint val)
+{
+ uint extc = (val >> 14) & 3;
+ uint cd = (val & CPM_BRG_CD_MASK) >> 1;
+ uint div16 = (val & CPM_BRG_DIV16) != 0;
+
+#if defined(CONFIG_8xx)
+ DECLARE_GLOBAL_DATA_PTR;
+ ulong clock = gd->cpu_clk;
+#elif defined(CONFIG_8260)
+ DECLARE_GLOBAL_DATA_PTR;
+ ulong clock = gd->brg_clk;
+#endif
+
+ printf ("BRG%d:", n);
+
+ if (val & CPM_BRG_RST)
+ puts (" RESET");
+ else
+ puts (" ");
+
+ if (val & CPM_BRG_EN)
+ puts (" ENABLED");
+ else
+ puts (" DISABLED");
+
+ printf (" EXTC=%d", extc);
+
+ if (val & CPM_BRG_ATB)
+ puts (" ATB");
+ else
+ puts (" ");
+
+ printf (" DIVIDER=%4d", cd);
+ if (extc == 0 && cd != 0) {
+ uint baudrate;
+
+ if (div16)
+ baudrate = (clock / 16) / (cd + 1);
+ else
+ baudrate = clock / (cd + 1);
+
+ printf ("=%6d bps", baudrate);
+ } else {
+ puts (" ");
+ }
+
+ if (val & CPM_BRG_DIV16)
+ puts (" DIV16");
+ else
+ puts (" ");
+
+ putc ('\n');
+}
+
+int
+do_brginfo (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+ volatile immap_t *immap = (immap_t *) CFG_IMMR;
+
+#if defined(CONFIG_8xx)
+ volatile cpm8xx_t *cp = &immap->im_cpm;
+ volatile uint *p = &cp->cp_brgc1;
+#elif defined(CONFIG_8260)
+ volatile uint *p = &immap->im_brgc1;
+#endif
+ int i = 1;
+
+ while (i <= 4)
+ prbrg (i++, *p++);
+
+#if defined(CONFIG_8260)
+ p = &immap->im_brgc5;
+ while (i <= 8)
+ prbrg (i++, *p++);
+#endif
+ return 0;
+}
+
+int
+do_i2cinfo (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+ volatile immap_t *immap = (immap_t *) CFG_IMMR;
+
+#if defined(CONFIG_8xx)
+ volatile i2c8xx_t *i2c = &immap->im_i2c;
+ volatile cpm8xx_t *cp = &immap->im_cpm;
+ volatile iic_t *iip = (iic_t *) & cp->cp_dparam[PROFF_IIC];
+#elif defined(CONFIG_8260)
+ volatile i2c8260_t *i2c = &immap->im_i2c;
+ volatile iic_t *iip;
+ uint dpaddr;
+
+ dpaddr = *((unsigned short *) (&immap->im_dprambase[PROFF_I2C_BASE]));
+ if (dpaddr == 0)
+ iip = NULL;
+ else
+ iip = (iic_t *) & immap->im_dprambase[dpaddr];
+#endif
+
+ printf ("I2MOD = %02x I2ADD = %02x\n", i2c->i2c_i2mod, i2c->i2c_i2add);
+ printf ("I2BRG = %02x I2COM = %02x\n", i2c->i2c_i2brg, i2c->i2c_i2com);
+ printf ("I2CER = %02x I2CMR = %02x\n", i2c->i2c_i2cer, i2c->i2c_i2cmr);
+
+ if (iip == NULL)
+ printf ("i2c parameter ram not allocated\n");
+ else {
+ printf ("RBASE = %08x TBASE = %08x\n",
+ iip->iic_rbase, iip->iic_tbase);
+ printf ("RFCR = %02x TFCR = %02x\n",
+ iip->iic_rfcr, iip->iic_tfcr);
+ printf ("MRBLR = %04x\n", iip->iic_mrblr);
+ printf ("RSTATE= %08x RDP = %08x\n",
+ iip->iic_rstate, iip->iic_rdp);
+ printf ("RBPTR = %04x RBC = %04x\n",
+ iip->iic_rbptr, iip->iic_rbc);
+ printf ("RXTMP = %08x\n", iip->iic_rxtmp);
+ printf ("TSTATE= %08x TDP = %08x\n",
+ iip->iic_tstate, iip->iic_tdp);
+ printf ("TBPTR = %04x TBC = %04x\n",
+ iip->iic_tbptr, iip->iic_tbc);
+ printf ("TXTMP = %08x\n", iip->iic_txtmp);
+ }
+ return 0;
+}
+
+int
+do_sccinfo (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+ unimplemented (cmdtp, flag, argc, argv);
+ return 0;
+}
+
+int
+do_smcinfo (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+ unimplemented (cmdtp, flag, argc, argv);
+ return 0;
+}
+
+int
+do_spiinfo (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+ unimplemented (cmdtp, flag, argc, argv);
+ return 0;
+}
+
+int
+do_muxinfo (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+ unimplemented (cmdtp, flag, argc, argv);
+ return 0;
+}
+
+int
+do_siinfo (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+ unimplemented (cmdtp, flag, argc, argv);
+ return 0;
+}
+
+int
+do_mccinfo (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+ unimplemented (cmdtp, flag, argc, argv);
+ return 0;
+}
+#endif /* CFG_CMD_IMMAP && (CONFIG_8xx || CONFIG_8260) */
--- /dev/null
+/*
+ * (C) Copyright 2002
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/*
+ * Boot support
+ */
+#include <common.h>
+#include <command.h>
+#include <cmd_boot.h>
+#include <cmd_autoscript.h>
+#include <s_record.h>
+#include <net.h>
+
+#if (CONFIG_COMMANDS & CFG_CMD_JFFS2)
+
+#include <jffs2/jffs2.h>
+static int part_num=0;
+
+#ifndef CFG_JFFS_CUSTOM_PART
+
+static struct part_info part;
+
+struct part_info*
+jffs2_part_info(int part_num)
+{
+ extern flash_info_t flash_info[]; /* info for FLASH chips */
+ int i;
+
+ if(part_num==0){
+
+ if(part.usr_priv==(void*)1)
+ return ∂
+
+ memset(&part, 0, sizeof(part));
+
+#if defined(CFG_JFFS2_FIRST_SECTOR)
+ part.offset = (unsigned char *) flash_info[CFG_JFFS2_FIRST_BANK].start[CFG_JFFS2_FIRST_SECTOR];
+#else
+ part.offset = (unsigned char *) flash_info[CFG_JFFS2_FIRST_BANK].start[0];
+#endif
+
+ /* Figure out flash partition size */
+ for (i = CFG_JFFS2_FIRST_BANK; i < CFG_JFFS2_NUM_BANKS+CFG_JFFS2_FIRST_BANK; i++)
+ part.size += flash_info[i].size;
+
+#if defined(CFG_JFFS2_FIRST_SECTOR) && (CFG_JFFS2_FIRST_SECTOR > 0)
+ part.size -=
+ flash_info[CFG_JFFS2_FIRST_BANK].start[CFG_JFFS2_FIRST_SECTOR] -
+ flash_info[CFG_JFFS2_FIRST_BANK].start[0];
+#endif
+
+ /* unused in current jffs2 loader */
+ part.erasesize = 0;
+
+ /* Mark the struct as ready */
+ part.usr_priv=(void*)1;
+
+ return ∂
+ }
+ return 0;
+}
+#endif /* ifndef CFG_JFFS_CUSTOM_PART */
+int
+do_jffs2_fsload(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+ char *filename = "pImage";
+ ulong offset = CFG_LOAD_ADDR;
+ int size;
+ struct part_info *part;
+
+ if (argc == 2) {
+ filename = argv[1];
+ }
+ if (argc == 3) {
+ offset = simple_strtoul(argv[1], NULL, 16);
+ filename = argv[2];
+ }
+
+ if (0 != (part=jffs2_part_info(part_num))){
+
+ printf("### JFFS2 loading '%s' to 0x%lx\n", filename, offset);
+ size = jffs2_1pass_load((char *)offset, part, filename);
+
+ if (size > 0) {
+ char buf[10];
+ printf("### JFFS2 load complete: %d bytes loaded to 0x%lx\n",
+ size, offset);
+ sprintf(buf, "%x", size);
+ setenv("filesize", buf);
+ } else {
+ printf("### JFFS2 LOAD ERROR<%x> for %s!\n", size, filename);
+ }
+
+ return !(size > 0);
+ }
+ printf("Active partition not valid\n");
+ return 0;
+}
+
+int
+do_jffs2_ls(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+ char *filename = "/";
+ int ret;
+ struct part_info *part;
+
+ if (argc == 2)
+ filename = argv[1];
+
+ if (0 != (part=jffs2_part_info(part_num))){
+
+ ret = jffs2_1pass_ls(jffs2_part_info(part_num), filename);
+
+ return (ret == 1);
+ }
+ printf("Active partition not valid\n");
+ return 0;
+}
+
+int
+do_jffs2_fsinfo(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+ int ret;
+ struct part_info *part;
+
+ if (0 != (part=jffs2_part_info(part_num))){
+
+ ret = jffs2_1pass_info(jffs2_part_info(part_num));
+
+ return (ret == 1);
+ }
+ printf("Active partition not valid\n");
+ return 0;
+}
+
+int
+do_jffs2_chpart(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+ int tmp_part;
+
+ if (argc >= 2) {
+ tmp_part = simple_strtoul(argv[1], NULL, 16);
+ }else{
+ printf("Need partition number in argument list\n");
+ return 0;
+
+ }
+
+ if (jffs2_part_info(tmp_part)){
+ printf("Partiton changed to %d\n",tmp_part);
+ part_num=tmp_part;
+ return 0;
+ }
+
+ printf("Partition %d is not valid partiton\n",tmp_part);
+ return 0;
+
+}
+#endif /* CFG_CMD_JFFS2 */
--- /dev/null
+/*
+ * (C) Copyright 2001 Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Andreas Heppel <aheppel@sysgo.de>
+ *
+ * (C) Copyright 2002
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ * Wolfgang Grandegger, DENX Software Engineering, wg@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
+ */
+
+/*
+ * PCI routines
+ */
+
+#include <common.h>
+
+#ifdef CONFIG_PCI
+
+#include <command.h>
+#include <cmd_boot.h>
+#include <asm/processor.h>
+#include <asm/io.h>
+#include <cmd_pci.h>
+#include <pci.h>
+
+#if (CONFIG_COMMANDS & CFG_CMD_PCI)
+
+extern int cmd_get_data_size(char* arg, int default_size);
+
+unsigned char ShortPCIListing = 1;
+
+/*
+ * Follows routines for the output of infos about devices on PCI bus.
+ */
+
+void pci_header_show(pci_dev_t dev);
+void pci_header_show_brief(pci_dev_t dev);
+
+/*
+ * Subroutine: pciinfo
+ *
+ * Description: Show information about devices on PCI bus.
+ * Depending on the define CFG_SHORT_PCI_LISTING
+ * the output will be more or less exhaustive.
+ *
+ * Inputs: bus_no the number of the bus to be scanned.
+ *
+ * Return: None
+ *
+ */
+void pciinfo(int BusNum, int ShortPCIListing)
+{
+ int Device;
+ int Function;
+ unsigned char HeaderType;
+ unsigned short VendorID;
+ pci_dev_t dev;
+
+ printf("Scanning PCI devices on bus %d\n", BusNum);
+
+ if (ShortPCIListing) {
+ printf("BusDevFun VendorId DeviceId Device Class Sub-Class\n");
+ printf("_____________________________________________________________\n");
+ }
+
+ for (Device = 0; Device < PCI_MAX_PCI_DEVICES; Device++) {
+ HeaderType = 0;
+ VendorID = 0;
+ for (Function = 0; Function < PCI_MAX_PCI_FUNCTIONS; Function++) {
+ /*
+ * If this is not a multi-function device, we skip the rest.
+ */
+ if (Function && !(HeaderType & 0x80))
+ break;
+
+ dev = PCI_BDF(BusNum, Device, Function);
+
+ pci_read_config_word(dev, PCI_VENDOR_ID, &VendorID);
+ if ((VendorID == 0xFFFF) || (VendorID == 0x0000))
+ continue;
+
+ pci_read_config_byte(dev, PCI_HEADER_TYPE, &HeaderType);
+
+ if (ShortPCIListing)
+ {
+ printf("%02x.%02x.%02x ", BusNum, Device, Function);
+ pci_header_show_brief(dev);
+ }
+ else
+ {
+ printf("\nFound PCI device %02x.%02x.%02x:\n",
+ BusNum, Device, Function);
+ pci_header_show(dev);
+ }
+ }
+ }
+}
+
+char* pci_classes_str(u8 class)
+{
+ static char *pci_classes[] = {
+ "Build before PCI Rev2.0",
+ "Mass storage controller",
+ "Network controller ",
+ "Display controller ",
+ "Multimedia device ",
+ "Memory controller ",
+ "Bridge device ",
+ "Simple comm. controller",
+ "Base system peripheral ",
+ "Input device ",
+ "Docking station ",
+ "Processor ",
+ "Serial bus controller ",
+ "Reserved entry ",
+ "Does not fit any class "
+ };
+
+ if (class < (sizeof pci_classes / sizeof *pci_classes))
+ return pci_classes[(int) class];
+
+ return "??? ";
+}
+
+/*
+ * Subroutine: pci_header_show_brief
+ *
+ * Description: Reads and prints the header of the
+ * specified PCI device in short form.
+ *
+ * Inputs: dev Bus+Device+Function number
+ *
+ * Return: None
+ *
+ */
+void pci_header_show_brief(pci_dev_t dev)
+{
+ u16 vendor, device;
+ u8 class, subclass;
+
+ pci_read_config_word(dev, PCI_VENDOR_ID, &vendor);
+ pci_read_config_word(dev, PCI_DEVICE_ID, &device);
+ pci_read_config_byte(dev, PCI_CLASS_CODE, &class);
+ pci_read_config_byte(dev, PCI_CLASS_SUB_CODE, &subclass);
+
+ printf("0x%.4x 0x%.4x %s 0x%.2x\n",
+ vendor, device,
+ pci_classes_str(class), subclass);
+}
+
+/*
+ * Subroutine: PCI_Header_Show
+ *
+ * Description: Reads the header of the specified PCI device.
+ *
+ * Inputs: BusDevFunc Bus+Device+Function number
+ *
+ * Return: None
+ *
+ */
+void pci_header_show(pci_dev_t dev)
+{
+ u8 _byte, header_type;
+ u16 _word;
+ u32 _dword;
+
+#define PRINT(msg, type, reg) \
+ pci_read_config_##type(dev, reg, &_##type); \
+ printf(msg, _##type)
+
+#define PRINT2(msg, type, reg, func) \
+ pci_read_config_##type(dev, reg, &_##type); \
+ printf(msg, _##type, func(_##type))
+
+ pci_read_config_byte(dev, PCI_HEADER_TYPE, &header_type);
+
+ PRINT (" vendor ID = 0x%.4x\n", word, PCI_VENDOR_ID);
+ PRINT (" device ID = 0x%.4x\n", word, PCI_DEVICE_ID);
+ PRINT (" command register = 0x%.4x\n", word, PCI_COMMAND);
+ PRINT (" status register = 0x%.4x\n", word, PCI_STATUS);
+ PRINT (" revision ID = 0x%.2x\n", byte, PCI_REVISION_ID);
+ PRINT2(" class code = 0x%.2x (%s)\n", byte, PCI_CLASS_CODE,
+ pci_classes_str);
+ PRINT (" sub class code = 0x%.2x\n", byte, PCI_CLASS_SUB_CODE);
+ PRINT (" programming interface = 0x%.2x\n", byte, PCI_CLASS_PROG);
+ PRINT (" cache line = 0x%.2x\n", byte, PCI_CACHE_LINE_SIZE);
+ PRINT (" latency time = 0x%.2x\n", byte, PCI_LATENCY_TIMER);
+ PRINT (" header type = 0x%.2x\n", byte, PCI_HEADER_TYPE);
+ PRINT (" BIST = 0x%.2x\n", byte, PCI_BIST);
+ PRINT (" base address 0 = 0x%.8x\n", dword, PCI_BASE_ADDRESS_0);
+ PRINT (" base address 1 = 0x%.8x\n", dword, PCI_BASE_ADDRESS_1);
+
+ if (header_type & 0x01) { /* PCI-to-PCI bridge */
+ PRINT (" primary bus number = 0x%.2x\n", byte, PCI_PRIMARY_BUS);
+ PRINT (" secondary bus number = 0x%.2x\n", byte, PCI_SECONDARY_BUS);
+ PRINT (" subordinate bus number = 0x%.2x\n", byte, PCI_SUBORDINATE_BUS);
+ PRINT (" secondary latency timer = 0x%.2x\n", byte, PCI_SEC_LATENCY_TIMER);
+ PRINT (" IO base = 0x%.2x\n", byte, PCI_IO_BASE);
+ PRINT (" IO limit = 0x%.2x\n", byte, PCI_IO_LIMIT);
+ PRINT (" secondary status = 0x%.4x\n", word, PCI_SEC_STATUS);
+ PRINT (" memory base = 0x%.4x\n", word, PCI_MEMORY_BASE);
+ PRINT (" memory limit = 0x%.4x\n", word, PCI_MEMORY_LIMIT);
+ PRINT (" prefetch memory base = 0x%.4x\n", word, PCI_PREF_MEMORY_BASE);
+ PRINT (" prefetch memory limit = 0x%.4x\n", word, PCI_PREF_MEMORY_LIMIT);
+ PRINT (" prefetch memory base upper = 0x%.8x\n", dword, PCI_PREF_BASE_UPPER32);
+ PRINT (" prefetch memory limit upper = 0x%.8x\n", dword, PCI_PREF_LIMIT_UPPER32);
+ PRINT (" IO base upper 16 bits = 0x%.4x\n", word, PCI_IO_BASE_UPPER16);
+ PRINT (" IO limit upper 16 bits = 0x%.4x\n", word, PCI_IO_LIMIT_UPPER16);
+ PRINT (" expansion ROM base address = 0x%.8x\n", dword, PCI_ROM_ADDRESS1);
+ PRINT (" interrupt line = 0x%.2x\n", byte, PCI_INTERRUPT_LINE);
+ PRINT (" interrupt pin = 0x%.2x\n", byte, PCI_INTERRUPT_PIN);
+ PRINT (" bridge control = 0x%.4x\n", word, PCI_BRIDGE_CONTROL);
+ } else { /* PCI device */
+ PRINT(" base address 2 = 0x%.8x\n", dword, PCI_BASE_ADDRESS_2);
+ PRINT(" base address 3 = 0x%.8x\n", dword, PCI_BASE_ADDRESS_3);
+ PRINT(" base address 4 = 0x%.8x\n", dword, PCI_BASE_ADDRESS_4);
+ PRINT(" base address 5 = 0x%.8x\n", dword, PCI_BASE_ADDRESS_5);
+ PRINT(" cardBus CIS pointer = 0x%.8x\n", dword, PCI_CARDBUS_CIS);
+ PRINT(" sub system vendor ID = 0x%.4x\n", word, PCI_SUBSYSTEM_VENDOR_ID);
+ PRINT(" sub system ID = 0x%.4x\n", word, PCI_SUBSYSTEM_ID);
+ PRINT(" expansion ROM base address = 0x%.8x\n", dword, PCI_ROM_ADDRESS);
+ PRINT(" interrupt line = 0x%.2x\n", byte, PCI_INTERRUPT_LINE);
+ PRINT(" interrupt pin = 0x%.2x\n", byte, PCI_INTERRUPT_PIN);
+ PRINT(" min Grant = 0x%.2x\n", byte, PCI_MIN_GNT);
+ PRINT(" max Latency = 0x%.2x\n", byte, PCI_MAX_LAT);
+ }
+
+#undef PRINT
+#undef PRINT2
+}
+
+/* Convert the "bus.device.function" identifier into a number.
+ */
+static pci_dev_t get_pci_dev(char* name)
+{
+ char cnum[12];
+ int len, i, iold, n;
+ int bdfs[3] = {0,0,0};
+
+ len = strlen(name);
+ if (len > 8)
+ return -1;
+ for (i = 0, iold = 0, n = 0; i < len; i++) {
+ if (name[i] == '.') {
+ memcpy(cnum, &name[iold], i - iold);
+ cnum[i - iold] = '\0';
+ bdfs[n++] = simple_strtoul(cnum, NULL, 16);
+ iold = i + 1;
+ }
+ }
+ strcpy(cnum, &name[iold]);
+ if (n == 0)
+ n = 1;
+ bdfs[n] = simple_strtoul(cnum, NULL, 16);
+ return PCI_BDF(bdfs[0], bdfs[1], bdfs[2]);
+}
+
+static int pci_cfg_display(pci_dev_t bdf, ulong addr, ulong size, ulong length)
+{
+#define DISP_LINE_LEN 16
+ ulong i, nbytes, linebytes;
+ int rc = 0;
+
+ if (length == 0)
+ length = 0x40 / size; /* Standard PCI configuration space */
+
+ /* Print the lines.
+ * once, and all accesses are with the specified bus width.
+ */
+ nbytes = length * size;
+ do {
+ uint val4;
+ ushort val2;
+ u_char val1;
+
+ printf("%08lx:", addr);
+ linebytes = (nbytes>DISP_LINE_LEN)?DISP_LINE_LEN:nbytes;
+ for (i=0; i<linebytes; i+= size) {
+ if (size == 4) {
+ pci_read_config_dword(bdf, addr, &val4);
+ printf(" %08x", val4);
+ } else if (size == 2) {
+ pci_read_config_word(bdf, addr, &val2);
+ printf(" %04x", val2);
+ } else {
+ pci_read_config_byte(bdf, addr, &val1);
+ printf(" %02x", val1);
+ }
+ addr += size;
+ }
+ printf("\n");
+ nbytes -= linebytes;
+ if (ctrlc()) {
+ rc = 1;
+ break;
+ }
+ } while (nbytes > 0);
+
+ return (rc);
+}
+
+static int pci_cfg_write (pci_dev_t bdf, ulong addr, ulong size, ulong value)
+{
+ if (size == 4) {
+ pci_write_config_dword(bdf, addr, value);
+ }
+ else if (size == 2) {
+ ushort val = value & 0xffff;
+ pci_write_config_word(bdf, addr, val);
+ }
+ else {
+ u_char val = value & 0xff;
+ pci_write_config_byte(bdf, addr, val);
+ }
+ return 0;
+}
+
+static int
+pci_cfg_modify (pci_dev_t bdf, ulong addr, ulong size, ulong value, int incrflag)
+{
+ ulong i;
+ int nbytes;
+ extern char console_buffer[];
+ uint val4;
+ ushort val2;
+ u_char val1;
+
+ /* Print the address, followed by value. Then accept input for
+ * the next value. A non-converted value exits.
+ */
+ do {
+ printf("%08lx:", addr);
+ if (size == 4) {
+ pci_read_config_dword(bdf, addr, &val4);
+ printf(" %08x", val4);
+ }
+ else if (size == 2) {
+ pci_read_config_word(bdf, addr, &val2);
+ printf(" %04x", val2);
+ }
+ else {
+ pci_read_config_byte(bdf, addr, &val1);
+ printf(" %02x", val1);
+ }
+
+ nbytes = readline (" ? ");
+ if (nbytes == 0 || (nbytes == 1 && console_buffer[0] == '-')) {
+ /* <CR> pressed as only input, don't modify current
+ * location and move to next. "-" pressed will go back.
+ */
+ if (incrflag)
+ addr += nbytes ? -size : size;
+ nbytes = 1;
+#ifdef CONFIG_BOOT_RETRY_TIME
+ reset_cmd_timeout(); /* good enough to not time out */
+#endif
+ }
+#ifdef CONFIG_BOOT_RETRY_TIME
+ else if (nbytes == -2) {
+ break; /* timed out, exit the command */
+ }
+#endif
+ else {
+ char *endp;
+ i = simple_strtoul(console_buffer, &endp, 16);
+ nbytes = endp - console_buffer;
+ if (nbytes) {
+#ifdef CONFIG_BOOT_RETRY_TIME
+ /* good enough to not time out
+ */
+ reset_cmd_timeout();
+#endif
+ pci_cfg_write (bdf, addr, size, i);
+ if (incrflag)
+ addr += size;
+ }
+ }
+ } while (nbytes);
+
+ return 0;
+}
+
+/* PCI Configuration Space access commands
+ *
+ * Syntax:
+ * pci display[.b, .w, .l] bus.device.function} [addr] [len]
+ * pci next[.b, .w, .l] bus.device.function [addr]
+ * pci modify[.b, .w, .l] bus.device.function [addr]
+ * pci write[.b, .w, .l] bus.device.function addr value
+ */
+int do_pci (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+ ulong addr = 0, value = 0, size = 0;
+ pci_dev_t bdf = 0;
+ char cmd = 's';
+
+ if (argc > 1)
+ cmd = argv[1][0];
+
+ switch (cmd) {
+ case 'd': /* display */
+ case 'n': /* next */
+ case 'm': /* modify */
+ case 'w': /* write */
+ /* Check for a size specification. */
+ size = cmd_get_data_size(argv[1], 4);
+ if (argc > 3)
+ addr = simple_strtoul(argv[3], NULL, 16);
+ if (argc > 4)
+ value = simple_strtoul(argv[4], NULL, 16);
+ case 'h': /* header */
+ if (argc < 3)
+ goto usage;
+ if ((bdf = get_pci_dev(argv[2])) == -1)
+ return 1;
+ break;
+ default: /* scan bus */
+ value = 1; /* short listing */
+ bdf = 0; /* bus number */
+ if (argc > 1) {
+ if (argv[argc-1][0] == 'l') {
+ value = 0;
+ argc--;
+ }
+ if (argc > 1)
+ bdf = simple_strtoul(argv[1], NULL, 16);
+ }
+ pciinfo(bdf, value);
+ return 0;
+ }
+
+ switch (argv[1][0]) {
+ case 'h': /* header */
+ pci_header_show(bdf);
+ return 0;
+ case 'd': /* display */
+ return pci_cfg_display(bdf, addr, size, value);
+ case 'n': /* next */
+ if (argc < 4)
+ goto usage;
+ return pci_cfg_modify(bdf, addr, size, value, 0);
+ case 'm': /* modify */
+ if (argc < 4)
+ goto usage;
+ return pci_cfg_modify(bdf, addr, size, value, 1);
+ case 'w': /* write */
+ if (argc < 5)
+ goto usage;
+ return pci_cfg_write(bdf, addr, size, value);
+ }
+
+ return 1;
+ usage:
+ printf ("Usage:\n%s\n", cmdtp->usage);
+ return 1;
+}
+
+#endif /* (CONFIG_COMMANDS & CFG_CMD_PCI) */
+
+#endif /* CONFIG_PCI */
--- /dev/null
+/*
+ * (C) Copyright 2000-2002
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ********************************************************************
+ *
+ * Lots of code copied from:
+ *
+ * m8xx_pcmcia.c - Linux PCMCIA socket driver for the mpc8xx series.
+ * (C) 1999-2000 Magnus Damm <damm@bitsmart.com>
+ *
+ * "The ExCA standard specifies that socket controllers should provide
+ * two IO and five memory windows per socket, which can be independently
+ * configured and positioned in the host address space and mapped to
+ * arbitrary segments of card address space. " - David A Hinds. 1999
+ *
+ * This controller does _not_ meet the ExCA standard.
+ *
+ * m8xx pcmcia controller brief info:
+ * + 8 windows (attrib, mem, i/o)
+ * + up to two slots (SLOT_A and SLOT_B)
+ * + inputpins, outputpins, event and mask registers.
+ * - no offset register. sigh.
+ *
+ * Because of the lacking offset register we must map the whole card.
+ * We assign each memory window PCMCIA_MEM_WIN_SIZE address space.
+ * Make sure there is (PCMCIA_MEM_WIN_SIZE * PCMCIA_MEM_WIN_NO
+ * * PCMCIA_SOCKETS_NO) bytes at PCMCIA_MEM_WIN_BASE.
+ * The i/o windows are dynamically allocated at PCMCIA_IO_WIN_BASE.
+ * They are maximum 64KByte each...
+ */
+
+/* #define DEBUG 1 */
+
+/*
+ * PCMCIA support
+ */
+#include <common.h>
+#include <command.h>
+#include <config.h>
+#include <pcmcia.h>
+#include <cmd_pcmcia.h>
+#if defined(CONFIG_IDE_8xx_PCCARD) && defined(CONFIG_8xx)
+#include <mpc8xx.h>
+#endif
+#if defined(CONFIG_LWMON)
+#include <i2c.h>
+#endif
+
+#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA) || \
+ ((CONFIG_COMMANDS & CFG_CMD_IDE) && defined(CONFIG_IDE_8xx_PCCARD))
+
+int pcmcia_on (void);
+
+#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
+static int pcmcia_off (void);
+static int hardware_disable(int slot);
+#endif
+static int hardware_enable (int slot);
+static int voltage_set(int slot, int vcc, int vpp);
+#ifdef CONFIG_IDE_8xx_PCCARD
+static void print_funcid (int func);
+static void print_fixed (volatile uchar *p);
+static int identify (volatile uchar *p);
+static int check_ide_device (void);
+#endif /* CONFIG_IDE_8xx_PCCARD */
+
+static u_int m8xx_get_graycode(u_int size);
+#if 0
+static u_int m8xx_get_speed(u_int ns, u_int is_io);
+#endif
+
+/* ------------------------------------------------------------------------- */
+
+/* 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])
+
+const char *indent = "\t ";
+
+/* ------------------------------------------------------------------------- */
+
+#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
+
+int do_pinit (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+ int rcode = 0;
+
+ if (argc != 2) {
+ printf ("Usage: pinit {on | off}\n");
+ return 1;
+ }
+ if (strcmp(argv[1],"on") == 0) {
+ rcode = pcmcia_on ();
+ } else if (strcmp(argv[1],"off") == 0) {
+ rcode = pcmcia_off ();
+ } else {
+ printf ("Usage: pinit {on | off}\n");
+ return 1;
+ }
+
+ return rcode;
+}
+#endif /* CFG_CMD_PCMCIA */
+
+/* ------------------------------------------------------------------------- */
+
+#if defined(CONFIG_LWMON)
+# define CFG_PCMCIA_TIMING (PCMCIA_SHT(9) | PCMCIA_SST(3) | PCMCIA_SL(12))
+#else
+# define CFG_PCMCIA_TIMING (PCMCIA_SHT(2) | PCMCIA_SST(4) | PCMCIA_SL(9))
+#endif
+
+int pcmcia_on (void)
+{
+ int i;
+ u_long reg, base;
+ pcmcia_win_t *win;
+
+ debug ("Enable PCMCIA " PCMCIA_SLOT_MSG "\n");
+
+ /* intialize the fixed memory windows */
+ win = (pcmcia_win_t *)(&((immap_t *)CFG_IMMR)->im_pcmcia.pcmc_pbr0);
+ base = CFG_PCMCIA_MEM_ADDR;
+
+ if((reg = m8xx_get_graycode(CFG_PCMCIA_MEM_SIZE)) == -1) {
+ printf ("Cannot set window size to 0x%08x\n",
+ CFG_PCMCIA_MEM_SIZE);
+ return (1);
+ }
+
+ for (i=0; i<PCMCIA_MEM_WIN_NO; ++i) {
+ win->br = base;
+
+ switch (i) {
+#ifdef CONFIG_IDE_8xx_PCCARD
+ case 0: { /* map attribute memory */
+ win->or = ( PCMCIA_BSIZE_64M
+ | PCMCIA_PPS_8
+ | PCMCIA_PRS_ATTR
+ | PCMCIA_SLOT_x
+ | PCMCIA_PV
+ | CFG_PCMCIA_TIMING );
+ break;
+ }
+
+ case 1: { /* map I/O window for data reg */
+ win->or = ( PCMCIA_BSIZE_1K
+ | PCMCIA_PPS_16
+ | PCMCIA_PRS_IO
+ | PCMCIA_SLOT_x
+ | PCMCIA_PV
+ | CFG_PCMCIA_TIMING );
+ break;
+ }
+
+ case 2: { /* map I/O window for command/ctrl reg block */
+ win->or = ( PCMCIA_BSIZE_1K
+ | PCMCIA_PPS_8
+ | PCMCIA_PRS_IO
+ | PCMCIA_SLOT_x
+ | PCMCIA_PV
+ | CFG_PCMCIA_TIMING );
+ break;
+ }
+#endif /* CONFIG_IDE_8xx_PCCARD */
+ default: /* set to not valid */
+ win->or = 0;
+ break;
+ }
+
+ debug ("MemWin %d: PBR 0x%08lX POR %08lX\n",
+ i, win->br, win->or);
+ base += CFG_PCMCIA_MEM_SIZE;
+ ++win;
+ }
+
+ /* turn off voltage */
+ if (voltage_set(_slot_, 0, 0))
+ return (1);
+
+ /* Enable external hardware */
+ if (hardware_enable(_slot_))
+ return (1);
+
+#ifdef CONFIG_IDE_8xx_PCCARD
+ if (check_ide_device())
+ return (1);
+#endif
+ return (0);
+}
+
+/* ------------------------------------------------------------------------- */
+
+#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
+
+static int pcmcia_off (void)
+{
+ int i;
+ pcmcia_win_t *win;
+
+ printf ("Disable PCMCIA " PCMCIA_SLOT_MSG "\n");
+
+ /* clear interrupt state, and disable interrupts */
+ ((immap_t *)CFG_IMMR)->im_pcmcia.pcmc_pscr = PCMCIA_MASK(_slot_);
+ ((immap_t *)CFG_IMMR)->im_pcmcia.pcmc_per &= ~PCMCIA_MASK(_slot_);
+
+ /* turn off interrupt and disable CxOE */
+ PCMCIA_PGCRX(_slot_) = __MY_PCMCIA_GCRX_CXOE;
+
+ /* turn off memory windows */
+ win = (pcmcia_win_t *)(&((immap_t *)CFG_IMMR)->im_pcmcia.pcmc_pbr0);
+
+ for (i=0; i<PCMCIA_MEM_WIN_NO; ++i) {
+ /* disable memory window */
+ win->or = 0;
+ ++win;
+ }
+
+ /* turn off voltage */
+ voltage_set(_slot_, 0, 0);
+
+ /* disable external hardware */
+ printf ("Shutdown and Poweroff " PCMCIA_SLOT_MSG "\n");
+ hardware_disable(_slot_);
+ return 0;
+}
+
+#endif /* CFG_CMD_PCMCIA */
+
+/* ------------------------------------------------------------------------- */
+
+#ifdef CONFIG_IDE_8xx_PCCARD
+
+#define MAX_TUPEL_SZ 512
+#define MAX_FEATURES 4
+
+static int check_ide_device (void)
+{
+ volatile uchar *ident = NULL;
+ volatile uchar *feature_p[MAX_FEATURES];
+ volatile uchar *p, *start;
+ int n_features = 0;
+ uchar func_id = ~0;
+ uchar code, len;
+ ushort config_base = 0;
+ int found = 0;
+ int i;
+
+ debug ("PCMCIA MEM: %08X\n", CFG_PCMCIA_MEM_ADDR);
+
+ start = p = (volatile uchar *) CFG_PCMCIA_MEM_ADDR;
+
+ while ((p - start) < MAX_TUPEL_SZ) {
+
+ code = *p; p += 2;
+
+ if (code == 0xFF) { /* End of chain */
+ break;
+ }
+
+ len = *p; p += 2;
+#if defined(DEBUG) && (DEBUG > 1)
+ { volatile uchar *q = p;
+ printf ("\nTuple code %02x length %d\n\tData:",
+ code, len);
+
+ for (i = 0; i < len; ++i) {
+ printf (" %02x", *q);
+ q+= 2;
+ }
+ }
+#endif /* DEBUG */
+ switch (code) {
+ case CISTPL_VERS_1:
+ ident = p + 4;
+ break;
+ case CISTPL_FUNCID:
+ /* Fix for broken SanDisk which may have 0x80 bit set */
+ func_id = *p & 0x7F;
+ break;
+ case CISTPL_FUNCE:
+ if (n_features < MAX_FEATURES)
+ feature_p[n_features++] = p;
+ break;
+ case CISTPL_CONFIG:
+ config_base = (*(p+6) << 8) + (*(p+4));
+ debug ("\n## Config_base = %04x ###\n", config_base);
+ default:
+ break;
+ }
+ p += 2 * len;
+ }
+
+ found = identify (ident);
+
+ if (func_id != ((uchar)~0)) {
+ print_funcid (func_id);
+
+ if (func_id == CISTPL_FUNCID_FIXED)
+ found = 1;
+ else
+ return (1); /* no disk drive */
+ }
+
+ for (i=0; i<n_features; ++i) {
+ print_fixed (feature_p[i]);
+ }
+
+ if (!found) {
+ printf ("unknown card type\n");
+ return (1);
+ }
+
+ /* set I/O area in config reg -> only valid for ARGOSY D5!!! */
+ *((uchar *)(CFG_PCMCIA_MEM_ADDR + config_base)) = 1;
+
+ return (0);
+}
+#endif /* CONFIG_IDE_8xx_PCCARD */
+
+/* ------------------------------------------------------------------------- */
+
+
+/* ---------------------------------------------------------------------------- */
+/* board specific stuff: */
+/* voltage_set(), hardware_enable() and hardware_disable() */
+/* ---------------------------------------------------------------------------- */
+
+/* ---------------------------------------------------------------------------- */
+/* RPX Boards from Embedded Planet */
+/* ---------------------------------------------------------------------------- */
+
+#if defined(CONFIG_RPXCLASSIC) || defined(CONFIG_RPXLITE)
+
+/* The RPX boards seems to have it's bus monitor timeout set to 6*8 clocks.
+ * SYPCR is write once only, therefore must the slowest memory be faster
+ * than the bus monitor or we will get a machine check due to the bus timeout.
+ */
+
+#define PCMCIA_BOARD_MSG "RPX CLASSIC or RPX LITE"
+
+#undef PCMCIA_BMT_LIMIT
+#define PCMCIA_BMT_LIMIT (6*8)
+
+static int voltage_set(int slot, int vcc, int vpp)
+{
+ u_long reg = 0;
+
+ switch(vcc) {
+ case 0: break;
+ case 33: reg |= BCSR1_PCVCTL4; break;
+ case 50: reg |= BCSR1_PCVCTL5; break;
+ default: return 1;
+ }
+
+ switch(vpp) {
+ case 0: break;
+ case 33:
+ case 50:
+ if(vcc == vpp)
+ reg |= BCSR1_PCVCTL6;
+ else
+ return 1;
+ break;
+ case 120:
+ reg |= BCSR1_PCVCTL7;
+ default: return 1;
+ }
+
+ if(vcc == 120)
+ return 1;
+
+ /* first, turn off all power */
+
+ *((uint *)RPX_CSR_ADDR) &= ~(BCSR1_PCVCTL4 | BCSR1_PCVCTL5
+ | BCSR1_PCVCTL6 | BCSR1_PCVCTL7);
+
+ /* enable new powersettings */
+
+ *((uint *)RPX_CSR_ADDR) |= reg;
+
+ return 0;
+}
+
+#define socket_get(_slot_) PCMCIA_SOCKET_KEY_5V
+static int hardware_enable (int slot)
+{
+ return 0; /* No hardware to enable */
+}
+#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
+static int hardware_disable(int slot)
+{
+ return 0; /* No hardware to disable */
+}
+#endif /* CFG_CMD_PCMCIA */
+#endif /* CONFIG_RPXCLASSIC */
+
+/* ---------------------------------------------------------------------------- */
+/* (F)ADS Boards from Motorola */
+/* ---------------------------------------------------------------------------- */
+
+#if defined(CONFIG_ADS) || defined(CONFIG_FADS)
+
+#ifdef CONFIG_ADS
+#define PCMCIA_BOARD_MSG "ADS"
+#define PCMCIA_GLITCHY_CD /* My ADS board needs this */
+#else
+#define PCMCIA_BOARD_MSG "FADS"
+#endif
+
+static int voltage_set(int slot, int vcc, int vpp)
+{
+ u_long reg = 0;
+
+ switch(vpp) {
+ case 0: reg = 0; break;
+ case 50: reg = 1; break;
+ case 120: reg = 2; break;
+ default: return 1;
+ }
+
+ switch(vcc) {
+ case 0: reg = 0; break;
+#ifdef CONFIG_ADS
+ case 50: reg = BCSR1_PCCVCCON; break;
+#endif
+#ifdef CONFIG_FADS
+ case 33: reg = BCSR1_PCCVCC0 | BCSR1_PCCVCC1; break;
+ case 50: reg = BCSR1_PCCVCC1; break;
+#endif
+ default: return 1;
+ }
+
+ /* first, turn off all power */
+
+#ifdef CONFIG_ADS
+ *((uint *)BCSR1) |= BCSR1_PCCVCCON;
+#endif
+#ifdef CONFIG_FADS
+ *((uint *)BCSR1) &= ~(BCSR1_PCCVCC0 | BCSR1_PCCVCC1);
+#endif
+ *((uint *)BCSR1) &= ~BCSR1_PCCVPP_MASK;
+
+ /* enable new powersettings */
+
+#ifdef CONFIG_ADS
+ *((uint *)BCSR1) &= ~reg;
+#endif
+#ifdef CONFIG_FADS
+ *((uint *)BCSR1) |= reg;
+#endif
+
+ *((uint *)BCSR1) |= reg << 20;
+
+ return 0;
+}
+
+#define socket_get(_slot_) PCMCIA_SOCKET_KEY_5V
+
+static int hardware_enable(int slot)
+{
+ *((uint *)BCSR1) &= ~BCSR1_PCCEN;
+ return 0;
+}
+
+#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
+static int hardware_disable(int slot)
+{
+ *((uint *)BCSR1) &= ~BCSR1_PCCEN;
+ return 0;
+}
+#endif /* CFG_CMD_PCMCIA */
+
+#endif /* (F)ADS */
+
+/* ---------------------------------------------------------------------------- */
+/* TQM8xxL Boards by TQ Components */
+/* ---------------------------------------------------------------------------- */
+
+#if defined(CONFIG_TQM8xxL)
+
+#define PCMCIA_BOARD_MSG "TQM8xxL"
+
+
+static int hardware_enable(int slot)
+{
+ volatile immap_t *immap;
+ volatile cpm8xx_t *cp;
+ volatile pcmconf8xx_t *pcmp;
+ volatile sysconf8xx_t *sysp;
+ uint reg, mask;
+
+ 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 SIUMCR to enable PCMCIA port B
+ * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
+ */
+ sysp->sc_siumcr &= ~SIUMCR_DBGC11; /* set DBGC to 00 */
+
+ /* clear interrupt state, and disable interrupts */
+ pcmp->pcmc_pscr = PCMCIA_MASK(_slot_);
+ pcmp->pcmc_per &= ~PCMCIA_MASK(_slot_);
+
+ /* disable interrupts & DMA */
+ PCMCIA_PGCRX(_slot_) = 0;
+
+ /*
+ * 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
+ */
+ immap->im_ioport.iop_pcpar &= ~(0x0002 | 0x0004);
+ immap->im_ioport.iop_pcso &= ~(0x0002 | 0x0004);
+ /* remove all power */
+
+ immap->im_ioport.iop_pcdat &= ~(0x0002 | 0x0004);
+
+ /*
+ * 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 & 0x00001800) {
+ printf (" No Card found\n");
+ return (1);
+ }
+
+ /*
+ * Power On.
+ */
+ mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
+ reg = pcmp->pcmc_pipr;
+ debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
+ reg,
+ (reg&PCMCIA_VS1(slot))?"n":"ff",
+ (reg&PCMCIA_VS2(slot))?"n":"ff");
+ if ((reg & mask) == mask) {
+ immap->im_ioport.iop_pcdat |= 0x0004;
+ puts (" 5.0V card found: ");
+ } else {
+ immap->im_ioport.iop_pcdat |= 0x0002;
+ puts (" 3.3V card found: ");
+ }
+ immap->im_ioport.iop_pcdir |= (0x0002 | 0x0004);
+#if 0
+ /* VCC switch error flag, PCMCIA slot INPACK_ pin */
+ cp->cp_pbdir &= ~(0x0020 | 0x0010);
+ cp->cp_pbpar &= ~(0x0020 | 0x0010);
+ udelay(500000);
+#endif
+ udelay(1000);
+ 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));
+
+ /* remove all power */
+ immap->im_ioport.iop_pcdat &= ~(0x0002 | 0x0004);
+
+ /* Configure PCMCIA General Control Register */
+ PCMCIA_PGCRX(_slot_) = 0;
+
+ 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(10000);
+
+ return (0);
+}
+#endif /* CFG_CMD_PCMCIA */
+
+
+
+static int voltage_set(int slot, int vcc, int vpp)
+{
+ volatile immap_t *immap;
+ volatile pcmconf8xx_t *pcmp;
+ u_long reg;
+
+ 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;
+ 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 off all power
+ */
+ debug ("PCMCIA power OFF\n");
+ immap->im_ioport.iop_pcpar &= ~(0x0002 | 0x0004);
+ immap->im_ioport.iop_pcso &= ~(0x0002 | 0x0004);
+ immap->im_ioport.iop_pcdat &= ~(0x0002 | 0x0004);
+
+ reg = 0;
+ switch(vcc) {
+ case 0: break;
+ case 33: reg |= 0x0002; break;
+ case 50: reg |= 0x0004; 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");
+
+ immap->im_ioport.iop_pcdat |= reg;
+ immap->im_ioport.iop_pcdir |= (0x0002 | 0x0004);
+ if (reg) {
+ debug ("PCMCIA powered at %sV\n",
+ (reg&0x0004) ? "5.0" : "3.3");
+ } else {
+ debug ("PCMCIA powered down\n");
+ }
+
+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);
+}
+
+#endif /* TQM8xxL */
+
+
+/* ---------------------------------------------------------------------------- */
+/* LWMON Board */
+/* ---------------------------------------------------------------------------- */
+
+#if defined(CONFIG_LWMON)
+
+#define PCMCIA_BOARD_MSG "LWMON"
+
+/* #define's for MAX1604 Power Switch */
+#define MAX1604_OP_SUS 0x80
+#define MAX1604_VCCBON 0x40
+#define MAX1604_VCC_35 0x20
+#define MAX1604_VCCBHIZ 0x10
+#define MAX1604_VPPBON 0x08
+#define MAX1604_VPPBPBPGM 0x04
+#define MAX1604_VPPBHIZ 0x02
+/* reserved 0x01 */
+
+static int hardware_enable(int slot)
+{
+ volatile immap_t *immap;
+ volatile cpm8xx_t *cp;
+ volatile pcmconf8xx_t *pcmp;
+ volatile sysconf8xx_t *sysp;
+ uint reg, mask;
+ uchar val;
+
+
+ debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
+
+ /* Switch on PCMCIA port in PIC register 0x60 */
+ reg = pic_read (0x60);
+ debug ("[%d] PIC read: reg_60 = 0x%02x\n", __LINE__, reg);
+ reg &= ~0x10;
+ /* reg |= 0x08; Vpp not needed */
+ pic_write (0x60, reg);
+#ifdef DEBUG
+ reg = pic_read (0x60);
+ printf ("[%d] PIC read: reg_60 = 0x%02x\n", __LINE__, reg);
+#endif
+ 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 SIUMCR to enable PCMCIA port B
+ * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
+ */
+ sysp->sc_siumcr &= ~SIUMCR_DBGC11; /* set DBGC to 00 */
+
+ /* clear interrupt state, and disable interrupts */
+ pcmp->pcmc_pscr = PCMCIA_MASK(_slot_);
+ pcmp->pcmc_per &= ~PCMCIA_MASK(_slot_);
+
+ /* disable interrupts & DMA */
+ PCMCIA_PGCRX(_slot_) = 0;
+
+ /*
+ * 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);
+
+ /*
+ * 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 & 0x00001800) {
+ printf (" No Card found\n");
+ return (1);
+ }
+
+ /*
+ * Power On.
+ */
+ mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
+ reg = pcmp->pcmc_pipr;
+ debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
+ reg,
+ (reg&PCMCIA_VS1(slot))?"n":"ff",
+ (reg&PCMCIA_VS2(slot))?"n":"ff");
+ if ((reg & mask) == mask) {
+ val = 0; /* VCCB3/5 = 0 ==> use Vx = 5.0 V */
+ puts (" 5.0V card found: ");
+ } else {
+ val = MAX1604_VCC_35; /* VCCB3/5 = 1 ==> use Vy = 3.3 V */
+ puts (" 3.3V card found: ");
+ }
+
+ /* switch VCC on */
+ val |= MAX1604_OP_SUS | MAX1604_VCCBON;
+ i2c_init (CFG_I2C_SPEED, CFG_I2C_SLAVE);
+ i2c_write (CFG_I2C_POWER_A_ADDR, 0, 0, &val, 1);
+
+ udelay(500000);
+
+ 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;
+ uchar val;
+
+ 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));
+
+ /* remove all power, put output in high impedance state */
+ val = MAX1604_VCCBHIZ | MAX1604_VPPBHIZ;
+ i2c_init (CFG_I2C_SPEED, CFG_I2C_SLAVE);
+ i2c_write (CFG_I2C_POWER_A_ADDR, 0, 0, &val, 1);
+
+ /* Configure PCMCIA General Control Register */
+ PCMCIA_PGCRX(_slot_) = 0;
+
+ 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;
+
+ /* Switch off PCMCIA port in PIC register 0x60 */
+ reg = pic_read (0x60);
+ debug ("[%d] PIC read: reg_60 = 0x%02x\n", __LINE__, reg);
+ reg |= 0x10;
+ reg &= ~0x08;
+ pic_write (0x60, reg);
+#ifdef DEBUG
+ reg = pic_read (0x60);
+ printf ("[%d] PIC read: reg_60 = 0x%02x\n", __LINE__, reg);
+#endif
+ udelay(10000);
+
+ return (0);
+}
+#endif /* CFG_CMD_PCMCIA */
+
+
+
+static int voltage_set(int slot, int vcc, int vpp)
+{
+ volatile immap_t *immap;
+ volatile pcmconf8xx_t *pcmp;
+ u_long reg;
+ uchar val;
+
+ 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;
+ 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);
+
+ /*
+ * Turn off all power (switch to high impedance)
+ */
+ debug ("PCMCIA power OFF\n");
+ val = MAX1604_VCCBHIZ | MAX1604_VPPBHIZ;
+ i2c_init (CFG_I2C_SPEED, CFG_I2C_SLAVE);
+ i2c_write (CFG_I2C_POWER_A_ADDR, 0, 0, &val, 1);
+
+ val = 0;
+ switch(vcc) {
+ case 0: break;
+ case 33: val = MAX1604_VCC_35; break;
+ case 50: 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");
+
+ i2c_write (CFG_I2C_POWER_A_ADDR, 0, 0, &val, 1);
+ if (val) {
+ debug ("PCMCIA powered at %sV\n",
+ (val & MAX1604_VCC_35) ? "3.3" : "5.0");
+ } else {
+ debug ("PCMCIA powered down\n");
+ }
+
+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);
+}
+
+#endif /* LWMON */
+
+/* ---------------------------------------------------------------------------- */
+/* GTH board by Corelatus AB */
+/* ---------------------------------------------------------------------------- */
+#if defined(CONFIG_GTH)
+
+#define PCMCIA_BOARD_MSG "GTH COMPACT FLASH"
+
+static int voltage_set(int slot, int vcc, int vpp)
+{ /* Do nothing */
+ return 0;
+}
+
+static int hardware_enable (int slot)
+{
+ volatile immap_t *immap;
+ volatile cpm8xx_t *cp;
+ volatile pcmconf8xx_t *pcmp;
+ volatile sysconf8xx_t *sysp;
+ uint reg, mask;
+
+ debug ("hardware_enable: GTH Slot %c\n", 'A'+slot);
+
+ 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));
+
+ /* clear interrupt state, and disable interrupts */
+ pcmp->pcmc_pscr = PCMCIA_MASK(_slot_);
+ pcmp->pcmc_per &= ~PCMCIA_MASK(_slot_);
+
+ /* disable interrupts & DMA */
+ PCMCIA_PGCRX(_slot_) = 0;
+
+ /*
+ * 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);
+
+ /*
+ * 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 & 0x98000000) {
+ printf (" No Card found\n");
+ return (1);
+ }
+
+ mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
+ reg = pcmp->pcmc_pipr;
+ debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
+ reg,
+ (reg&PCMCIA_VS1(slot))?"n":"ff",
+ (reg&PCMCIA_VS2(slot))?"n":"ff");
+
+ 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)
+{
+ return 0; /* No hardware to disable */
+}
+#endif /* CFG_CMD_PCMCIA */
+#endif /* CONFIG_GTH */
+
+/* ---------------------------------------------------------------------------- */
+/* ICU862 Boards by Cambridge Broadband Ltd. */
+/* ---------------------------------------------------------------------------- */
+
+#if defined(CONFIG_ICU862)
+
+#define PCMCIA_BOARD_MSG "ICU862"
+
+static void cfg_port_B (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 Port B for TPS2205 PC-Card Power-Interface Switch */
+ cfg_port_B ();
+
+ /*
+ * Configure SIUMCR to enable PCMCIA port B
+ * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
+ */
+ sysp->sc_siumcr &= ~SIUMCR_DBGC11; /* set DBGC to 00 */
+
+ /* clear interrupt state, and disable interrupts */
+ pcmp->pcmc_pscr = PCMCIA_MASK(_slot_);
+ pcmp->pcmc_per &= ~PCMCIA_MASK(_slot_);
+
+ /* disable interrupts & DMA */
+ PCMCIA_PGCRX(_slot_) = 0;
+
+ /*
+ * 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);
+
+ /*
+ * 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 & 0x00001800) {
+ 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");
+
+ reg = cp->cp_pbdat;
+ if ((pipr & mask) == mask) {
+ reg |= (TPS2205_VPP_PGM | TPS2205_VPP_VCC | /* VAVPP => Hi-Z */
+ TPS2205_VCC3); /* 3V off */
+ reg &= ~(TPS2205_VCC5); /* 5V on */
+ puts (" 5.0V card found: ");
+ } else {
+ reg |= (TPS2205_VPP_PGM | TPS2205_VPP_VCC | /* VAVPP => Hi-Z */
+ TPS2205_VCC5); /* 5V off */
+ reg &= ~(TPS2205_VCC3); /* 3V on */
+ puts (" 3.3V card found: ");
+ }
+
+ debug ("\nPB DAT: %08x -> 3.3V %s 5.0V %s VPP_PGM %s VPP_VCC %s\n",
+ reg,
+ (reg & TPS2205_VCC3) ? "off" : "on",
+ (reg & TPS2205_VCC5) ? "off" : "on",
+ (reg & TPS2205_VPP_PGM) ? "off" : "on",
+ (reg & TPS2205_VPP_VCC) ? "off" : "on" );
+
+ cp->cp_pbdat = reg;
+
+ /* Wait 500 ms; use this to check for over-current */
+ for (i=0; i<5000; ++i) {
+ if ((cp->cp_pbdat & TPS2205_OC) == 0) {
+ printf (" *** Overcurrent - Safety shutdown ***\n");
+ cp->cp_pbdat &= ~(TPS2205_SHDN);
+ 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 cpm8xx_t *cp;
+ volatile pcmconf8xx_t *pcmp;
+ u_long reg;
+
+ debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
+
+ immap = (immap_t *)CFG_IMMR;
+ cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
+ pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
+
+ /* Shut down */
+ cp->cp_pbdat &= ~(TPS2205_SHDN);
+
+ /* Configure PCMCIA General Control Register */
+ PCMCIA_PGCRX(_slot_) = 0;
+
+ 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(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;
+
+ 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_port_B (); /* Enables switch, but all in Hi-Z */
+
+ reg = cp->cp_pbdat;
+
+ switch(vcc) {
+ case 0: break; /* Switch off */
+ case 33: reg &= ~TPS2205_VCC3; break; /* Switch on 3.3V */
+ case 50: reg &= ~TPS2205_VCC5; break; /* Switch on 5.0V */
+ 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");
+
+ cp->cp_pbdat = reg;
+
+#ifdef DEBUG
+ {
+ char *s;
+
+ if ((reg & TPS2205_VCC3) == 0) {
+ s = "at 3.3V";
+ } else if ((reg & TPS2205_VCC5) == 0) {
+ s = "at 5.0V";
+ } else {
+ s = "down";
+ }
+ printf ("PCMCIA powered %s\n", s);
+ }
+#endif
+
+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_port_B (void)
+{
+ volatile immap_t *immap;
+ volatile cpm8xx_t *cp;
+ uint reg;
+
+ immap = (immap_t *)CFG_IMMR;
+ cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
+
+ /*
+ * Configure Port B for TPS2205 PC-Card Power-Interface Switch
+ *
+ * Switch off all voltages, assert shutdown
+ */
+ reg = cp->cp_pbdat;
+ reg |= (TPS2205_VPP_PGM | TPS2205_VPP_VCC | /* VAVPP => Hi-Z */
+ TPS2205_VCC3 | TPS2205_VCC5 | /* VAVCC => Hi-Z */
+ TPS2205_SHDN); /* enable switch */
+ cp->cp_pbdat = reg;
+
+ cp->cp_pbpar &= ~(TPS2205_INPUTS | TPS2205_OUTPUTS);
+
+ reg = cp->cp_pbdir & ~(TPS2205_INPUTS);
+ cp->cp_pbdir = reg | TPS2205_OUTPUTS;
+
+ debug ("Set Port B: PAR: %08x DIR: %08x DAT: %08x\n",
+ cp->cp_pbpar, cp->cp_pbdir, cp->cp_pbdat);
+}
+
+#endif /* ICU862 */
+
+
+/* ---------------------------------------------------------------------------- */
+/* C2MON Boards by TTTech Computertechnik AG */
+/* ---------------------------------------------------------------------------- */
+
+#if defined(CONFIG_C2MON)
+
+#define PCMCIA_BOARD_MSG "C2MON"
+
+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;
+ ushort sreg;
+ 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 ();
+
+ /*
+ * Configure SIUMCR to enable PCMCIA port B
+ * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
+ */
+ sysp->sc_siumcr &= ~SIUMCR_DBGC11; /* set DBGC to 00 */
+
+ /* clear interrupt state, and disable interrupts */
+ pcmp->pcmc_pscr = PCMCIA_MASK(_slot_);
+ pcmp->pcmc_per &= ~PCMCIA_MASK(_slot_);
+
+ /* disable interrupts & DMA */
+ PCMCIA_PGCRX(_slot_) = 0;
+
+ /*
+ * 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);
+
+ /*
+ * 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 & 0x00001800) {
+ 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");
+
+ sreg = immap->im_ioport.iop_pcdat;
+ if ((pipr & mask) == mask) {
+ sreg |= (TPS2211_VPPD0 | TPS2211_VPPD1 | /* VAVPP => Hi-Z */
+ TPS2211_VCCD1); /* 5V on */
+ sreg &= ~(TPS2211_VCCD0); /* 3V off */
+ puts (" 5.0V card found: ");
+ } else {
+ sreg |= (TPS2211_VPPD0 | TPS2211_VPPD1 | /* VAVPP => Hi-Z */
+ TPS2211_VCCD0); /* 3V on */
+ sreg &= ~(TPS2211_VCCD1); /* 5V off */
+ puts (" 3.3V card found: ");
+ }
+
+ debug ("\nPC DAT: %04x -> 3.3V %s 5.0V %s\n",
+ sreg,
+ ( (sreg & TPS2211_VCCD0) && !(sreg & TPS2211_VCCD1)) ? "on" : "off",
+ (!(sreg & TPS2211_VCCD0) && (sreg & TPS2211_VCCD1)) ? "on" : "off"
+ );
+
+ immap->im_ioport.iop_pcdat = sreg;
+
+ /* Wait 500 ms; use this to check for over-current */
+ for (i=0; i<5000; ++i) {
+ if ((cp->cp_pbdat & TPS2211_OC) == 0) {
+ printf (" *** Overcurrent - Safety shutdown ***\n");
+ immap->im_ioport.iop_pcdat &= ~(TPS2211_VCCD0|TPS2211_VCCD1);
+ 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 cpm8xx_t *cp;
+ 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 */
+ PCMCIA_PGCRX(_slot_) = 0;
+
+ 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;
+
+ /* ALl voltages off / Hi-Z */
+ immap->im_ioport.iop_pcdat |= (TPS2211_VPPD0 | TPS2211_VPPD1 |
+ TPS2211_VCCD0 | TPS2211_VCCD1 );
+
+ 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;
+ sreg |= TPS2211_VPPD0 | TPS2211_VPPD1; /* VAVPP always Hi-Z */
+
+ switch(vcc) {
+ case 0: break; /* Switch off */
+ case 33: sreg |= TPS2211_VCCD0; /* Switch on 3.3V */
+ sreg &= ~TPS2211_VCCD1;
+ break;
+ case 50: sreg &= ~TPS2211_VCCD0; /* Switch on 5.0V */
+ sreg |= TPS2211_VCCD1;
+ 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");
+
+ immap->im_ioport.iop_pcdat = sreg;
+
+#ifdef DEBUG
+ {
+ char *s;
+
+ if ((sreg & TPS2211_VCCD0) && !(sreg & TPS2211_VCCD1)) {
+ s = "at 3.3V";
+ } else if (!(sreg & TPS2211_VCCD0) && (sreg & TPS2211_VCCD1)) {
+ s = "at 5.0V";
+ } else {
+ s = "down";
+ }
+ printf ("PCMCIA powered %s\n", s);
+ }
+#endif
+
+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;
+ ushort sreg;
+
+ immap = (immap_t *)CFG_IMMR;
+ cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
+
+ /*
+ * Configure Port C for TPS2211 PC-Card Power-Interface Switch
+ *
+ * Switch off all voltages, assert shutdown
+ */
+ sreg = immap->im_ioport.iop_pcdat;
+ sreg |= (TPS2211_VPPD0 | TPS2211_VPPD1); /* VAVPP => Hi-Z */
+ sreg &= ~(TPS2211_VCCD0 | TPS2211_VCCD1); /* 3V and 5V off */
+ immap->im_ioport.iop_pcdat = sreg;
+
+ immap->im_ioport.iop_pcpar &= ~(TPS2211_OUTPUTS);
+ immap->im_ioport.iop_pcdir |= TPS2211_OUTPUTS;
+
+ debug ("Set Port C: PAR: %04x DIR: %04x DAT: %04x\n",
+ immap->im_ioport.iop_pcpar,
+ immap->im_ioport.iop_pcdir,
+ immap->im_ioport.iop_pcdat);
+
+ /*
+ * Configure Port B for TPS2211 PC-Card Power-Interface Switch
+ *
+ * Over-Current Input only
+ */
+ cp->cp_pbpar &= ~(TPS2211_INPUTS);
+ cp->cp_pbdir &= ~(TPS2211_INPUTS);
+
+ debug ("Set Port B: PAR: %08x DIR: %08x DAT: %08x\n",
+ cp->cp_pbpar, cp->cp_pbdir, cp->cp_pbdat);
+}
+
+#endif /* C2MON */
+
+/* ----------------------------------------------------------------------------
+ MBX board from Morotola
+ ---------------------------------------------------------------------------- */
+
+#if defined( CONFIG_MBX )
+#include <../board/mbx8xx/csr.h>
+
+/* A lot of this has been taken from the RPX code in this file it works from me.
+ I have added the voltage selection for the MBX board. */
+
+/* MBX voltage bit in control register #2 */
+#define CR2_VPP12 ((uchar)0x10)
+#define CR2_VPPVDD ((uchar)0x20)
+#define CR2_VDD5 ((uchar)0x40)
+#define CR2_VDD3 ((uchar)0x80)
+
+#define PCMCIA_BOARD_MSG "MBX860"
+
+static int voltage_set (int slot, int vcc, int vpp)
+{
+ uchar reg = 0;
+
+ 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);
+
+ switch (vcc) {
+ case 0:
+ break;
+ case 33:
+ reg |= CR2_VDD3;
+ break;
+ case 50:
+ reg |= CR2_VDD5;
+ break;
+ default:
+ return 1;
+ }
+
+ switch (vpp) {
+ case 0:
+ break;
+ case 33:
+ case 50:
+ if (vcc == vpp) {
+ reg |= CR2_VPPVDD;
+ } else {
+ return 1;
+ }
+ break;
+ case 120:
+ reg |= CR2_VPP12;
+ break;
+ default:
+ return 1;
+ }
+
+ /* first, turn off all power */
+ MBX_CSR2 &= ~(CR2_VDDSEL | CR2_VPPSEL);
+
+ /* enable new powersettings */
+ MBX_CSR2 |= reg;
+ debug ("MBX_CSR2 read = 0x%02x\n", MBX_CSR2);
+
+ return (0);
+}
+
+static int hardware_enable (int slot)
+{
+ volatile immap_t *immap;
+ volatile cpm8xx_t *cp;
+ volatile pcmconf8xx_t *pcmp;
+ volatile sysconf8xx_t *sysp;
+ uint reg, mask;
+
+ 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));
+
+ /* clear interrupt state, and disable interrupts */
+ pcmp->pcmc_pscr = PCMCIA_MASK (_slot_);
+ pcmp->pcmc_per &= ~PCMCIA_MASK (_slot_);
+
+ /* disable interrupts & DMA */
+ PCMCIA_PGCRX (_slot_) = 0;
+
+ /*
+ * 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);
+
+ /* remove all power */
+ voltage_set (slot, 0, 0);
+ /*
+ * 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 & 0x00001800) {
+ printf (" No Card found\n");
+ return (1);
+ }
+
+ /*
+ * Power On.
+ */
+ mask = PCMCIA_VS1 (_slot_) | PCMCIA_VS2 (_slot_);
+ reg = pcmp->pcmc_pipr;
+ debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n", reg,
+ (reg & PCMCIA_VS1 (slot)) ? "n" : "ff",
+ (reg & PCMCIA_VS2 (slot)) ? "n" : "ff");
+
+ if ((reg & mask) == mask) {
+ voltage_set (_slot_, 50, 0);
+ printf (" 5.0V card found: ");
+ } else {
+ voltage_set (_slot_, 33, 0);
+ printf (" 3.3V card found: ");
+ }
+
+ 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)
+{
+ return 0; /* No hardware to disable */
+}
+#endif /* CFG_CMD_PCMCIA */
+#endif /* CONFIG_MBX */
+/* ---------------------------------------------------------------------------- */
+/* R360MPI Board */
+/* ---------------------------------------------------------------------------- */
+
+#if defined(CONFIG_R360MPI)
+
+#define PCMCIA_BOARD_MSG "R360MPI"
+
+
+static int hardware_enable(int slot)
+{
+ volatile immap_t *immap;
+ volatile cpm8xx_t *cp;
+ volatile pcmconf8xx_t *pcmp;
+ volatile sysconf8xx_t *sysp;
+ uint reg, mask;
+
+ 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 SIUMCR to enable PCMCIA port B
+ * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
+ */
+ sysp->sc_siumcr &= ~SIUMCR_DBGC11; /* set DBGC to 00 */
+
+ /* clear interrupt state, and disable interrupts */
+ pcmp->pcmc_pscr = PCMCIA_MASK(_slot_);
+ pcmp->pcmc_per &= ~PCMCIA_MASK(_slot_);
+
+ /* disable interrupts & DMA */
+ PCMCIA_PGCRX(_slot_) = 0;
+
+ /*
+ * 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 Ports A, B & C pins for
+ * 5 Volts Enable and 3 Volts enable
+ */
+ immap->im_ioport.iop_pcpar &= ~(0x0400);
+ immap->im_ioport.iop_pcso &= ~(0x0400);/*
+ immap->im_ioport.iop_pcdir |= 0x0400;*/
+
+ immap->im_ioport.iop_papar &= ~(0x0200);/*
+ immap->im_ioport.iop_padir |= 0x0200;*/
+#if 0
+ immap->im_ioport.iop_pbpar &= ~(0xC000);
+ immap->im_ioport.iop_pbdir &= ~(0xC000);
+#endif
+ /* remove all power */
+
+ immap->im_ioport.iop_pcdat |= 0x0400;
+ immap->im_ioport.iop_padat |= 0x0200;
+
+ /*
+ * 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 & 0x00001800) {
+ printf (" No Card found\n");
+ return (1);
+ }
+
+ /*
+ * Power On.
+ */
+ mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
+ reg = pcmp->pcmc_pipr;
+ debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
+ reg,
+ (reg&PCMCIA_VS1(slot))?"n":"ff",
+ (reg&PCMCIA_VS2(slot))?"n":"ff");
+ if ((reg & mask) == mask) {
+ immap->im_ioport.iop_pcdat &= ~(0x4000);
+ puts (" 5.0V card found: ");
+ } else {
+ immap->im_ioport.iop_padat &= ~(0x0002);
+ puts (" 3.3V card found: ");
+ }
+ immap->im_ioport.iop_pcdir |= 0x0400;
+ immap->im_ioport.iop_padir |= 0x0200;
+#if 0
+ /* VCC switch error flag, PCMCIA slot INPACK_ pin */
+ cp->cp_pbdir &= ~(0x0020 | 0x0010);
+ cp->cp_pbpar &= ~(0x0020 | 0x0010);
+ udelay(500000);
+#endif
+ 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));
+
+ /* remove all power */
+ immap->im_ioport.iop_pcdat |= 0x0400;
+ immap->im_ioport.iop_padat |= 0x0200;
+
+ /* Configure PCMCIA General Control Register */
+ PCMCIA_PGCRX(_slot_) = 0;
+
+ 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(10000);
+
+ return (0);
+}
+#endif /* CFG_CMD_PCMCIA */
+
+
+
+static int voltage_set(int slot, int vcc, int vpp)
+{
+ volatile immap_t *immap;
+ volatile pcmconf8xx_t *pcmp;
+ u_long reg;
+
+ 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;
+ 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 Ports A & C pins for
+ * 5 Volts Enable and 3 Volts enable,
+ * Turn off all power
+ */
+ debug ("PCMCIA power OFF\n");
+ immap->im_ioport.iop_pcpar &= ~(0x0400);
+ immap->im_ioport.iop_pcso &= ~(0x0400);/*
+ immap->im_ioport.iop_pcdir |= 0x0400;*/
+
+ immap->im_ioport.iop_papar &= ~(0x0200);/*
+ immap->im_ioport.iop_padir |= 0x0200;*/
+
+ immap->im_ioport.iop_pcdat |= 0x0400;
+ immap->im_ioport.iop_padat |= 0x0200;
+
+ reg = 0;
+ switch(vcc) {
+ case 0: break;
+ case 33: reg |= 0x0200; break;
+ case 50: reg |= 0x0400; 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");
+
+ if (reg & 0x0200)
+ immap->im_ioport.iop_pcdat &= !reg;
+ if (reg & 0x0400)
+ immap->im_ioport.iop_padat &= !reg;
+ immap->im_ioport.iop_pcdir |= 0x0200;
+ immap->im_ioport.iop_padir |= 0x0400;
+ if (reg) {
+ debug ("PCMCIA powered at %sV\n",
+ (reg&0x0400) ? "5.0" : "3.3");
+ } else {
+ debug ("PCMCIA powered down\n");
+ }
+
+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);
+}
+
+#endif /* R360MPI */
+
+
+/* ---------------------------------------------------------------------------- */
+/* End of Board Specific Stuff */
+/* ---------------------------------------------------------------------------- */
+
+
+/* ---------------------------------------------------------------------------- */
+/* MPC8xx Specific Stuff - should go to MPC8xx directory */
+/* ---------------------------------------------------------------------------- */
+
+/*
+ * Search this table to see if the windowsize is
+ * supported...
+ */
+
+#define M8XX_SIZES_NO 32
+
+static const u_int m8xx_size_to_gray[M8XX_SIZES_NO] =
+{ 0x00000001, 0x00000002, 0x00000008, 0x00000004,
+ 0x00000080, 0x00000040, 0x00000010, 0x00000020,
+ 0x00008000, 0x00004000, 0x00001000, 0x00002000,
+ 0x00000100, 0x00000200, 0x00000800, 0x00000400,
+
+ 0x0fffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0x01000000, 0x02000000, 0xffffffff, 0x04000000,
+ 0x00010000, 0x00020000, 0x00080000, 0x00040000,
+ 0x00800000, 0x00400000, 0x00100000, 0x00200000 };
+
+
+/* ---------------------------------------------------------------------------- */
+
+static u_int m8xx_get_graycode(u_int size)
+{
+ u_int k;
+
+ for (k = 0; k < M8XX_SIZES_NO; k++) {
+ if(m8xx_size_to_gray[k] == size)
+ break;
+ }
+
+ if((k == M8XX_SIZES_NO) || (m8xx_size_to_gray[k] == -1))
+ k = -1;
+
+ return k;
+}
+
+/* ------------------------------------------------------------------------- */
+
+#if 0
+static u_int m8xx_get_speed(u_int ns, u_int is_io)
+{
+ u_int reg, clocks, psst, psl, psht;
+
+ if(!ns) {
+
+ /*
+ * We get called with IO maps setup to 0ns
+ * if not specified by the user.
+ * They should be 255ns.
+ */
+
+ if(is_io)
+ ns = 255;
+ else
+ ns = 100; /* fast memory if 0 */
+ }
+
+ /*
+ * In PSST, PSL, PSHT fields we tell the controller
+ * timing parameters in CLKOUT clock cycles.
+ * CLKOUT is the same as GCLK2_50.
+ */
+
+/* how we want to adjust the timing - in percent */
+
+#define ADJ 180 /* 80 % longer accesstime - to be sure */
+
+ clocks = ((M8XX_BUSFREQ / 1000) * ns) / 1000;
+ clocks = (clocks * ADJ) / (100*1000);
+
+ if(clocks >= PCMCIA_BMT_LIMIT) {
+ DEBUG(0, "Max access time limit reached\n");
+ clocks = PCMCIA_BMT_LIMIT-1;
+ }
+
+ psst = clocks / 7; /* setup time */
+ psht = clocks / 7; /* hold time */
+ psl = (clocks * 5) / 7; /* strobe length */
+
+ psst += clocks - (psst + psht + psl);
+
+ reg = psst << 12;
+ reg |= psl << 7;
+ reg |= psht << 16;
+
+ return reg;
+}
+#endif
+
+/* ------------------------------------------------------------------------- */
+
+#ifdef CONFIG_IDE_8xx_PCCARD
+static void print_funcid (int func)
+{
+ puts (indent);
+ switch (func) {
+ case CISTPL_FUNCID_MULTI:
+ puts (" Multi-Function");
+ break;
+ case CISTPL_FUNCID_MEMORY:
+ puts (" Memory");
+ break;
+ case CISTPL_FUNCID_SERIAL:
+ puts (" Serial Port");
+ break;
+ case CISTPL_FUNCID_PARALLEL:
+ puts (" Parallel Port");
+ break;
+ case CISTPL_FUNCID_FIXED:
+ puts (" Fixed Disk");
+ break;
+ case CISTPL_FUNCID_VIDEO:
+ puts (" Video Adapter");
+ break;
+ case CISTPL_FUNCID_NETWORK:
+ puts (" Network Adapter");
+ break;
+ case CISTPL_FUNCID_AIMS:
+ puts (" AIMS Card");
+ break;
+ case CISTPL_FUNCID_SCSI:
+ puts (" SCSI Adapter");
+ break;
+ default:
+ puts (" Unknown");
+ break;
+ }
+ puts (" Card\n");
+}
+#endif /* CONFIG_IDE_8xx_PCCARD */
+
+/* ------------------------------------------------------------------------- */
+
+#ifdef CONFIG_IDE_8xx_PCCARD
+static void print_fixed (volatile uchar *p)
+{
+ if (p == NULL)
+ return;
+
+ puts(indent);
+
+ switch (*p) {
+ case CISTPL_FUNCE_IDE_IFACE:
+ { uchar iface = *(p+2);
+
+ puts ((iface == CISTPL_IDE_INTERFACE) ? " IDE" : " unknown");
+ puts (" interface ");
+ break;
+ }
+ case CISTPL_FUNCE_IDE_MASTER:
+ case CISTPL_FUNCE_IDE_SLAVE:
+ { uchar f1 = *(p+2);
+ uchar f2 = *(p+4);
+
+ puts ((f1 & CISTPL_IDE_SILICON) ? " [silicon]" : " [rotating]");
+
+ if (f1 & CISTPL_IDE_UNIQUE)
+ puts (" [unique]");
+
+ puts ((f1 & CISTPL_IDE_DUAL) ? " [dual]" : " [single]");
+
+ if (f2 & CISTPL_IDE_HAS_SLEEP)
+ puts (" [sleep]");
+
+ if (f2 & CISTPL_IDE_HAS_STANDBY)
+ puts (" [standby]");
+
+ if (f2 & CISTPL_IDE_HAS_IDLE)
+ puts (" [idle]");
+
+ if (f2 & CISTPL_IDE_LOW_POWER)
+ puts (" [low power]");
+
+ if (f2 & CISTPL_IDE_REG_INHIBIT)
+ puts (" [reg inhibit]");
+
+ if (f2 & CISTPL_IDE_HAS_INDEX)
+ puts (" [index]");
+
+ if (f2 & CISTPL_IDE_IOIS16)
+ puts (" [IOis16]");
+
+ break;
+ }
+ }
+ putc ('\n');
+}
+#endif /* CONFIG_IDE_8xx_PCCARD */
+
+/* ------------------------------------------------------------------------- */
+
+#ifdef CONFIG_IDE_8xx_PCCARD
+
+#define MAX_IDENT_CHARS 64
+#define MAX_IDENT_FIELDS 4
+
+static uchar *known_cards[] = {
+ "ARGOSY PnPIDE D5",
+ NULL
+};
+
+static int identify (volatile uchar *p)
+{
+ uchar id_str[MAX_IDENT_CHARS];
+ uchar data;
+ uchar *t;
+ uchar **card;
+ int i, done;
+
+ if (p == NULL)
+ return (0); /* Don't know */
+
+ t = id_str;
+ done =0;
+
+ for (i=0; i<=4 && !done; ++i, p+=2) {
+ while ((data = *p) != '\0') {
+ if (data == 0xFF) {
+ done = 1;
+ break;
+ }
+ *t++ = data;
+ if (t == &id_str[MAX_IDENT_CHARS-1]) {
+ done = 1;
+ break;
+ }
+ p += 2;
+ }
+ if (!done)
+ *t++ = ' ';
+ }
+ *t = '\0';
+ while (--t > id_str) {
+ if (*t == ' ')
+ *t = '\0';
+ else
+ break;
+ }
+ puts (id_str);
+ putc ('\n');
+
+ for (card=known_cards; *card; ++card) {
+ debug ("## Compare against \"%s\"\n", *card);
+ if (strcmp(*card, id_str) == 0) { /* found! */
+ debug ("## CARD FOUND ##\n");
+ return (1);
+ }
+ }
+
+ return (0); /* don't know */
+}
+#endif /* CONFIG_IDE_8xx_PCCARD */
+
+/* ------------------------------------------------------------------------- */
+
+#endif /* CFG_CMD_PCMCIA || (CFG_CMD_IDE && CONFIG_IDE_8xx_PCCARD) */
--- /dev/null
+/*
+ * (C) Copyright 2000-2002
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * (C) Copyright 2001 Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Andreas Heppel <aheppel@sysgo.de>
+
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/* #define DEBUG */
+
+#include <common.h>
+
+#if defined(CFG_ENV_IS_IN_FLASH) /* Environment is in Flash */
+
+#include <command.h>
+#include <environment.h>
+#include <cmd_nvedit.h>
+#include <linux/stddef.h>
+
+#if ((CONFIG_COMMANDS&(CFG_CMD_ENV|CFG_CMD_FLASH)) == (CFG_CMD_ENV|CFG_CMD_FLASH))
+#define CMD_SAVEENV
+#elif defined(CFG_ENV_ADDR_REDUND)
+#error Cannot use CFG_ENV_ADDR_REDUND without CFG_CMD_ENV & CFG_CMD_FLASH
+#endif
+
+#if defined(CFG_ENV_SECT_SIZE) && (CFG_ENV_SECT_SIZE > CFG_ENV_SIZE) && \
+ defined(CFG_ENV_ADDR_REDUND)
+#error CFG_ENV_ADDR_REDUND should not be used when CFG_ENV_SECT_SIZE > CFG_ENV_SIZE
+#endif
+
+#if defined(CFG_ENV_SIZE_REDUND) && (CFG_ENV_SIZE_REDUND < CFG_ENV_SIZE)
+#error CFG_ENV_SIZE_REDUND should not be less then CFG_ENV_SIZE
+#endif
+
+#ifdef CONFIG_INFERNO
+# ifdef CFG_ENV_ADDR_REDUND
+#error CFG_ENV_ADDR_REDUND is not implemented for CONFIG_INFERNO
+# endif
+#endif
+
+char * env_name_spec = "Flash";
+
+#ifdef ENV_IS_EMBEDDED
+
+extern uchar environment[];
+env_t *env_ptr = (env_t *)(&environment[0]);
+
+#ifdef CMD_SAVEENV
+/* static env_t *flash_addr = (env_t *)(&environment[0]);-broken on ARM-wd-*/
+static env_t *flash_addr = (env_t *)CFG_ENV_ADDR;
+#endif
+
+#else /* ! ENV_IS_EMBEDDED */
+
+env_t *env_ptr = (env_t *)CFG_ENV_ADDR;
+#ifdef CMD_SAVEENV
+static env_t *flash_addr = (env_t *)CFG_ENV_ADDR;
+#endif
+
+#endif /* ENV_IS_EMBEDDED */
+
+#ifdef CFG_ENV_ADDR_REDUND
+static env_t *flash_addr_new = (env_t *)CFG_ENV_ADDR_REDUND;
+
+static ulong end_addr = CFG_ENV_ADDR + CFG_ENV_SIZE - 1;
+static ulong end_addr_new = CFG_ENV_ADDR_REDUND + CFG_ENV_SIZE_REDUND - 1;
+
+static uchar active_flag = 1;
+static uchar obsolete_flag = 0;
+#endif
+
+extern uchar default_environment[];
+extern int default_environment_size;
+
+
+uchar env_get_char_spec (int index)
+{
+ DECLARE_GLOBAL_DATA_PTR;
+
+ return ( *((uchar *)(gd->env_addr + index)) );
+}
+
+#ifdef CFG_ENV_ADDR_REDUND
+
+int env_init(void)
+{
+ DECLARE_GLOBAL_DATA_PTR;
+
+ int crc1_ok =
+ (crc32(0, flash_addr->data, ENV_SIZE) == flash_addr->crc);
+ int crc2_ok =
+ (crc32(0, flash_addr_new->data, ENV_SIZE) == flash_addr_new->crc);
+
+ uchar flag1 = flash_addr->flags;
+ uchar flag2 = flash_addr_new->flags;
+
+ ulong addr_default = (ulong)&default_environment[0];
+ ulong addr1 = (ulong)&(flash_addr->data);
+ ulong addr2 = (ulong)&(flash_addr_new->data);
+
+ if (crc1_ok && ! crc2_ok)
+ {
+ gd->env_addr = addr1;
+ gd->env_valid = 1;
+ }
+ else if (! crc1_ok && crc2_ok)
+ {
+ gd->env_addr = addr2;
+ gd->env_valid = 1;
+ }
+ else if (! crc1_ok && ! crc2_ok)
+ {
+ gd->env_addr = addr_default;
+ gd->env_valid = 0;
+ }
+ else if (flag1 == active_flag && flag2 == obsolete_flag)
+ {
+ gd->env_addr = addr1;
+ gd->env_valid = 1;
+ }
+ else if (flag1 == obsolete_flag && flag2 == active_flag)
+ {
+ gd->env_addr = addr2;
+ gd->env_valid = 1;
+ }
+ else if (flag1 == flag2)
+ {
+ gd->env_addr = addr1;
+ gd->env_valid = 2;
+ }
+ else if (flag1 == 0xFF)
+ {
+ gd->env_addr = addr1;
+ gd->env_valid = 2;
+ }
+ else if (flag2 == 0xFF)
+ {
+ gd->env_addr = addr2;
+ gd->env_valid = 2;
+ }
+
+ return (0);
+}
+
+#ifdef CMD_SAVEENV
+int saveenv(void)
+{
+ int rc = 1;
+
+ debug ("Protect off %08lX ... %08lX\n",
+ (ulong)flash_addr, end_addr);
+
+ if (flash_sect_protect (0, (ulong)flash_addr, end_addr)) {
+ goto Done;
+ }
+
+ debug ("Protect off %08lX ... %08lX\n",
+ (ulong)flash_addr_new, end_addr_new);
+
+ if (flash_sect_protect (0, (ulong)flash_addr_new, end_addr_new)) {
+ goto Done;
+ }
+
+ puts ("Erasing Flash...");
+ debug (" %08lX ... %08lX ...",
+ (ulong)flash_addr_new, end_addr_new);
+
+ if (flash_sect_erase ((ulong)flash_addr_new, end_addr_new)) {
+ goto Done;
+ }
+
+ puts ("Writing to Flash... ");
+ debug (" %08lX ... %08lX ...",
+ (ulong)&(flash_addr_new->data),
+ sizeof(env_ptr->data)+(ulong)&(flash_addr_new->data));
+ if (flash_write(env_ptr->data,
+ (ulong)&(flash_addr_new->data),
+ sizeof(env_ptr->data)) ||
+
+ flash_write((char *)&(env_ptr->crc),
+ (ulong)&(flash_addr_new->crc),
+ sizeof(env_ptr->crc)) ||
+
+ flash_write((char *)&obsolete_flag,
+ (ulong)&(flash_addr->flags),
+ sizeof(flash_addr->flags)) ||
+
+ flash_write((char *)&active_flag,
+ (ulong)&(flash_addr_new->flags),
+ sizeof(flash_addr_new->flags)))
+ {
+ flash_perror (rc);
+ goto Done;
+ }
+ puts ("done\n");
+
+ {
+ env_t * etmp = flash_addr;
+ ulong ltmp = end_addr;
+
+ flash_addr = flash_addr_new;
+ flash_addr_new = etmp;
+
+ end_addr = end_addr_new;
+ end_addr_new = ltmp;
+ }
+
+ rc = 0;
+Done:
+
+ /* try to re-protect */
+ (void) flash_sect_protect (1, (ulong)flash_addr, end_addr);
+ (void) flash_sect_protect (1, (ulong)flash_addr_new, end_addr_new);
+
+ return rc;
+}
+#endif /* CMD_SAVEENV */
+
+#else /* ! CFG_ENV_ADDR_REDUND */
+
+int env_init(void)
+{
+ DECLARE_GLOBAL_DATA_PTR;
+
+ if (crc32(0, env_ptr->data, ENV_SIZE) == env_ptr->crc) {
+ gd->env_addr = (ulong)&(env_ptr->data);
+ gd->env_valid = 1;
+ } else {
+ gd->env_addr = (ulong)&default_environment[0];
+ gd->env_valid = 0;
+ }
+
+ return (0);
+}
+
+#ifdef CMD_SAVEENV
+
+int saveenv(void)
+{
+ int len, rc;
+ ulong end_addr;
+ ulong flash_sect_addr;
+#if defined(CFG_ENV_SECT_SIZE) && (CFG_ENV_SECT_SIZE > CFG_ENV_SIZE)
+ ulong flash_offset;
+ uchar env_buffer[CFG_ENV_SECT_SIZE];
+#else
+ uchar *env_buffer = (char *)env_ptr;
+#endif /* CFG_ENV_SECT_SIZE */
+ int rcode = 0;
+
+#if defined(CFG_ENV_SECT_SIZE) && (CFG_ENV_SECT_SIZE > CFG_ENV_SIZE)
+
+ flash_offset = ((ulong)flash_addr) & (CFG_ENV_SECT_SIZE-1);
+ flash_sect_addr = ((ulong)flash_addr) & ~(CFG_ENV_SECT_SIZE-1);
+
+ debug ( "copy old content: "
+ "sect_addr: %08lX env_addr: %08lX offset: %08lX\n",
+ flash_sect_addr, (ulong)flash_addr, flash_offset);
+
+ /* copy old contents to temporary buffer */
+ memcpy (env_buffer, (void *)flash_sect_addr, CFG_ENV_SECT_SIZE);
+
+ /* copy current environment to temporary buffer */
+ memcpy ((uchar *)((unsigned long)env_buffer + flash_offset),
+ env_ptr,
+ CFG_ENV_SIZE);
+
+ len = CFG_ENV_SECT_SIZE;
+#else
+ flash_sect_addr = (ulong)flash_addr;
+ len = CFG_ENV_SIZE;
+#endif /* CFG_ENV_SECT_SIZE */
+
+#ifndef CONFIG_INFERNO
+ end_addr = flash_sect_addr + len - 1;
+#else
+ /* this is the last sector, and the size is hardcoded here */
+ /* otherwise we will get stack problems on loading 128 KB environment */
+ end_addr = flash_sect_addr + 0x20000 - 1;
+#endif
+
+ debug ("Protect off %08lX ... %08lX\n",
+ (ulong)flash_sect_addr, end_addr);
+
+ if (flash_sect_protect (0, flash_sect_addr, end_addr))
+ return 1;
+
+ puts ("Erasing Flash...");
+ if (flash_sect_erase (flash_sect_addr, end_addr))
+ return 1;
+
+ puts ("Writing to Flash... ");
+ rc = flash_write(env_buffer, flash_sect_addr, len);
+ if (rc != 0) {
+ flash_perror (rc);
+ rcode = 1;
+ } else {
+ puts ("done\n");
+ }
+
+ /* try to re-protect */
+ (void) flash_sect_protect (1, flash_sect_addr, end_addr);
+ return rcode;
+}
+
+#endif /* CMD_SAVEENV */
+
+#endif /* CFG_ENV_ADDR_REDUND */
+
+void env_relocate_spec (void)
+{
+#if !defined(ENV_IS_EMBEDDED) || defined(CFG_ENV_ADDR_REDUND)
+#ifdef CFG_ENV_ADDR_REDUND
+ DECLARE_GLOBAL_DATA_PTR;
+
+ if (gd->env_addr != (ulong)&(flash_addr->data))
+ {
+ env_t * etmp = flash_addr;
+ ulong ltmp = end_addr;
+
+ flash_addr = flash_addr_new;
+ flash_addr_new = etmp;
+
+ end_addr = end_addr_new;
+ end_addr_new = ltmp;
+ }
+
+ if (flash_addr_new->flags != obsolete_flag &&
+ crc32(0, flash_addr_new->data, ENV_SIZE) ==
+ flash_addr_new->crc)
+ {
+ gd->env_valid = 2;
+ flash_sect_protect (0, (ulong)flash_addr_new, end_addr_new);
+ flash_write((char *)&obsolete_flag,
+ (ulong)&(flash_addr_new->flags),
+ sizeof(flash_addr_new->flags));
+ flash_sect_protect (1, (ulong)flash_addr_new, end_addr_new);
+ }
+
+ if (flash_addr->flags != active_flag &&
+ (flash_addr->flags & active_flag) == active_flag)
+ {
+ gd->env_valid = 2;
+ flash_sect_protect (0, (ulong)flash_addr, end_addr);
+ flash_write((char *)&active_flag,
+ (ulong)&(flash_addr->flags),
+ sizeof(flash_addr->flags));
+ flash_sect_protect (1, (ulong)flash_addr, end_addr);
+ }
+
+ if (gd->env_valid == 2)
+ puts ("*** Warning - some problems detected "
+ "reading environment; recovered successfully\n\n");
+#endif /* CFG_ENV_ADDR_REDUND */
+ memcpy (env_ptr, (void*)flash_addr, CFG_ENV_SIZE);
+#endif /* ! ENV_IS_EMBEDDED || CFG_ENV_ADDR_REDUND */
+}
+
+#endif /* CFG_ENV_IS_IN_FLASH) */
--- /dev/null
+/*
+ * (C) Copyright 2000-2002
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * (C) Copyright 2001 Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Andreas Heppel <aheppel@sysgo.de>
+
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/*
+ * 09-18-2001 Andreas Heppel, Sysgo RTS GmbH <aheppel@sysgo.de>
+ *
+ * It might not be possible in all cases to use 'memcpy()' to copy
+ * the environment to NVRAM, as the NVRAM might not be mapped into
+ * the memory space. (I.e. this is the case for the BAB750). In those
+ * cases it might be possible to access the NVRAM using a different
+ * method. For example, the RTC on the BAB750 is accessible in IO
+ * space using its address and data registers. To enable usage of
+ * NVRAM in those cases I invented the functions 'nvram_read()' and
+ * 'nvram_write()', which will be activated upon the configuration
+ * #define CFG_NVRAM_ACCESS_ROUTINE. Note, that those functions are
+ * strongly dependent on the used HW, and must be redefined for each
+ * board that wants to use them.
+ */
+
+#include <common.h>
+
+#ifdef CFG_ENV_IS_IN_NVRAM /* Environment is in NVRAM */
+
+#include <command.h>
+#include <environment.h>
+#include <cmd_nvedit.h>
+#include <linux/stddef.h>
+#include <malloc.h>
+
+#ifdef CFG_NVRAM_ACCESS_ROUTINE
+extern void *nvram_read(void *dest, const long src, size_t count);
+extern void nvram_write(long dest, const void *src, size_t count);
+env_t *env_ptr = NULL;
+#else
+env_t *env_ptr = (env_t *)CFG_ENV_ADDR;
+#endif
+
+char * env_name_spec = "NVRAM";
+
+extern uchar default_environment[];
+extern int default_environment_size;
+
+extern uchar (*env_get_char)(int);
+extern uchar env_get_char_memory (int index);
+
+
+uchar env_get_char_spec (int index)
+{
+#ifdef CFG_NVRAM_ACCESS_ROUTINE
+ uchar c;
+
+ nvram_read(&c, CFG_ENV_ADDR+index, 1);
+
+ return c;
+#else
+ DECLARE_GLOBAL_DATA_PTR;
+
+ return *((uchar *)(gd->env_addr + index));
+#endif
+}
+
+void env_relocate_spec (void)
+{
+#if defined(CFG_NVRAM_ACCESS_ROUTINE)
+ nvram_read(env_ptr, CFG_ENV_ADDR, CFG_ENV_SIZE);
+#else
+ memcpy (env_ptr, (void*)CFG_ENV_ADDR, CFG_ENV_SIZE);
+#endif
+}
+
+int saveenv (void)
+{
+ int rcode = 0;
+
+#ifdef CFG_NVRAM_ACCESS_ROUTINE
+ nvram_write(CFG_ENV_ADDR, env_ptr, CFG_ENV_SIZE);
+#else
+ if (memcpy ((char *)CFG_ENV_ADDR, env_ptr, CFG_ENV_SIZE) == NULL)
+ rcode = 1 ;
+#endif
+ return rcode;
+}
+
+
+/************************************************************************
+ * Initialize Environment use
+ *
+ * We are still running from ROM, so data use is limited
+ */
+int env_init (void)
+{
+ DECLARE_GLOBAL_DATA_PTR;
+
+#if defined(CFG_NVRAM_ACCESS_ROUTINE)
+ ulong crc;
+ uchar data[ENV_SIZE];
+ nvram_read (&crc, CFG_ENV_ADDR, sizeof(ulong));
+ nvram_read (data, CFG_ENV_ADDR+sizeof(ulong), ENV_SIZE);
+
+ if (crc32(0, data, ENV_SIZE) == crc) {
+ gd->env_addr = (ulong)CFG_ENV_ADDR + sizeof(long);
+#else
+ if (crc32(0, env_ptr->data, ENV_SIZE) == env_ptr->crc) {
+ gd->env_addr = (ulong)&(env_ptr->data);
+#endif
+ gd->env_valid = 1;
+ } else {
+ gd->env_addr = (ulong)&default_environment[0];
+ gd->env_valid = 0;
+ }
+
+ return (0);
+}
+
+#endif /* CFG_ENV_IS_IN_NVRAM */
--- /dev/null
+/*
+ * (C) Copyright 2001
+ * Erik Theisen, Wave 7 Optics, etheisen@mindspring.com.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <config.h>
+#include <environment.h>
+
+/*
+ * Handle HOSTS that have prepended
+ * crap on symbol names, not TARGETS.
+ */
+#if defined(__APPLE__)
+/* Leading underscore on symbols */
+# define SYM_CHAR "_"
+#else /* No leading character on symbols */
+# define SYM_CHAR
+#endif
+
+/*
+ * Generate embedded environment table
+ * inside U-Boot image, if needed.
+ */
+#if defined(ENV_IS_EMBEDDED)
+/*
+ * Only put the environment in it's own section when we are building
+ * U-Boot proper. The host based program "tools/envcrc" does not need
+ * a seperate section. Note that ENV_CRC is only defined when building
+ * U-Boot itself.
+ */
+#if (defined(CONFIG_FADS) || \
+ defined(CONFIG_HYMOD) || \
+ defined(CONFIG_ICU862) || \
+ defined(CONFIG_R360MPI) || \
+ defined(CONFIG_TQM8xxL) || \
+ defined(CONFIG_RRVISION) || \
+ defined(CONFIG_TRAB) ) && \
+ defined(ENV_CRC) /* Environment embedded in U-Boot .ppcenv section */
+/* XXX - This only works with GNU C */
+# define __PPCENV__ __attribute__ ((section(".ppcenv")))
+# define __PPCTEXT__ __attribute__ ((section(".text")))
+
+#elif defined(USE_HOSTCC) /* Native for 'tools/envcrc' */
+# define __PPCENV__ /*XXX DO_NOT_DEL_THIS_COMMENT*/
+# define __PPCTEXT__ /*XXX DO_NOT_DEL_THIS_COMMENT*/
+
+#else /* Environment is embedded in U-Boot's .text section */
+/* XXX - This only works with GNU C */
+# define __PPCENV__ __attribute__ ((section(".text")))
+# define __PPCTEXT__ __attribute__ ((section(".text")))
+#endif
+
+/*
+ * Macros to generate global absolutes.
+ */
+#define GEN_SYMNAME(str) SYM_CHAR #str
+#define GEN_VALUE(str) #str
+#define GEN_ABS(name, value) \
+ asm (".globl " GEN_SYMNAME(name)); \
+ asm (GEN_SYMNAME(name) " = " GEN_VALUE(value))
+
+/*
+ * Macros to transform values
+ * into environment strings.
+ */
+#define XMK_STR(x) #x
+#define MK_STR(x) XMK_STR(x)
+
+/*
+ * Check to see if we are building with a
+ * computed CRC. Otherwise define it as ~0.
+ */
+#if !defined(ENV_CRC)
+# define ENV_CRC ~0
+#endif
+
+env_t environment __PPCENV__ = {
+ ENV_CRC, /* CRC Sum */
+#ifdef CFG_REDUNDAND_ENVIRONMENT
+ 1, /* Flags: valid */
+#endif
+ {
+#if defined(CONFIG_BOOTARGS)
+ "bootargs=" CONFIG_BOOTARGS "\0"
+#endif
+#if defined(CONFIG_BOOTCOMMAND)
+ "bootcmd=" CONFIG_BOOTCOMMAND "\0"
+#endif
+#if defined(CONFIG_RAMBOOTCOMMAND)
+ "ramboot=" CONFIG_RAMBOOTCOMMAND "\0"
+#endif
+#if defined(CONFIG_NFSBOOTCOMMAND)
+ "nfsboot=" CONFIG_NFSBOOTCOMMAND "\0"
+#endif
+#if defined(CONFIG_BOOTDELAY) && (CONFIG_BOOTDELAY >= 0)
+ "bootdelay=" MK_STR(CONFIG_BOOTDELAY) "\0"
+#endif
+#if defined(CONFIG_BAUDRATE) && (CONFIG_BAUDRATE >= 0)
+ "baudrate=" MK_STR(CONFIG_BAUDRATE) "\0"
+#endif
+#ifdef CONFIG_LOADS_ECHO
+ "loads_echo=" MK_STR(CONFIG_LOADS_ECHO) "\0"
+#endif
+#ifdef CONFIG_ETHADDR
+ "ethaddr=" MK_STR(CONFIG_ETHADDR) "\0"
+#endif
+#ifdef CONFIG_ETH1ADDR
+ "eth1addr=" MK_STR(CONFIG_ETH1ADDR) "\0"
+#endif
+#ifdef CONFIG_ETH2ADDR
+ "eth2addr=" MK_STR(CONFIG_ETH2ADDR) "\0"
+#endif
+#ifdef CONFIG_ETHPRIME
+ "ethprime=" CONFIG_ETHPRIME "\0"
+#endif
+#ifdef CONFIG_IPADDR
+ "ipaddr=" MK_STR(CONFIG_IPADDR) "\0"
+#endif
+#ifdef CONFIG_SERVERIP
+ "serverip=" MK_STR(CONFIG_SERVERIP) "\0"
+#endif
+#ifdef CFG_AUTOLOAD
+ "autoload=" CFG_AUTOLOAD "\0"
+#endif
+#ifdef CONFIG_ROOTPATH
+ "rootpath=" MK_STR(CONFIG_ROOTPATH) "\0"
+#endif
+#ifdef CONFIG_GATEWAYIP
+ "gatewayip=" MK_STR(CONFIG_GATEWAYIP) "\0"
+#endif
+#ifdef CONFIG_NETMASK
+ "netmask=" MK_STR(CONFIG_NETMASK) "\0"
+#endif
+#ifdef CONFIG_HOSTNAME
+ "hostname=" MK_STR(CONFIG_HOSTNAME) "\0"
+#endif
+#ifdef CONFIG_BOOTFILE
+ "bootfile=" MK_STR(CONFIG_BOOTFILE) "\0"
+#endif
+#ifdef CONFIG_LOADADDR
+ "loadaddr=" MK_STR(CONFIG_LOADADDR) "\0"
+#endif
+#ifdef CONFIG_PREBOOT
+ "preboot=" CONFIG_PREBOOT "\0"
+#endif
+#ifdef CONFIG_CLOCKS_IN_MHZ
+ "clocks_in_mhz=" "1" "\0"
+#endif
+#ifdef CONFIG_EXTRA_ENV_SETTINGS
+ CONFIG_EXTRA_ENV_SETTINGS
+#endif
+ "\0" /* Term. env_t.data with 2 NULLs */
+ }
+};
+#ifdef CFG_ENV_ADDR_REDUND
+env_t redundand_environment __PPCENV__ = {
+ 0, /* CRC Sum: invalid */
+ 0, /* Flags: invalid */
+ {
+ "\0"
+ }
+};
+#endif /* CFG_ENV_ADDR_REDUND */
+
+/*
+ * These will end up in the .text section
+ * if the environment strings are embedded
+ * in the image. When this is used for
+ * tools/envcrc, they are placed in the
+ * .data/.sdata section.
+ *
+ */
+unsigned long env_size __PPCTEXT__ = sizeof(env_t);
+
+/*
+ * Add in absolutes.
+ */
+GEN_ABS(env_offset, CFG_ENV_OFFSET);
+
+#endif /* ENV_IS_EMBEDDED */
--- /dev/null
+/*
+ * (C) Copyright 2000
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <watchdog.h>
+#include <command.h>
+#include <cmd_nvedit.h>
+#include <cmd_bootm.h>
+#include <malloc.h>
+#if defined(CONFIG_BOOT_RETRY_TIME) && defined(CONFIG_RESET_TO_RETRY)
+#include <cmd_boot.h> /* for do_reset() prototype */
+#endif
+
+#ifdef CFG_HUSH_PARSER
+#include <hush.h>
+#endif
+
+#define MAX_DELAY_STOP_STR 32
+
+static char * delete_char (char *buffer, char *p, int *colp, int *np, int plen);
+static int parse_line (char *, char *[]);
+#if defined(CONFIG_BOOTDELAY) && (CONFIG_BOOTDELAY >= 0)
+static int abortboot(int);
+#endif
+
+#undef DEBUG_PARSER
+
+char console_buffer[CFG_CBSIZE]; /* console I/O buffer */
+
+static char erase_seq[] = "\b \b"; /* erase sequence */
+static char tab_seq[] = " "; /* used to expand TABs */
+
+#ifdef CONFIG_BOOT_RETRY_TIME
+static uint64_t endtime = 0; /* must be set, default is instant timeout */
+static int retry_time = -1; /* -1 so can call readline before main_loop */
+#endif
+
+#define endtick(seconds) (get_ticks() + (uint64_t)(seconds) * get_tbclk())
+
+#ifndef CONFIG_BOOT_RETRY_MIN
+#define CONFIG_BOOT_RETRY_MIN CONFIG_BOOT_RETRY_TIME
+#endif
+
+#ifdef CONFIG_MODEM_SUPPORT
+int do_mdm_init = 0;
+extern void mdm_init(void); /* defined in board.c */
+#endif
+
+/***************************************************************************
+ * Watch for 'delay' seconds for autoboot stop or autoboot delay string.
+ * returns: 0 - no key string, allow autoboot
+ * 1 - got key string, abort
+ */
+#if defined(CONFIG_BOOTDELAY) && (CONFIG_BOOTDELAY >= 0)
+# if defined(CONFIG_AUTOBOOT_KEYED)
+static __inline__ int abortboot(int bootdelay)
+{
+ int abort = 0;
+ uint64_t etime = endtick(bootdelay);
+ struct
+ {
+ char* str;
+ u_int len;
+ int retry;
+ }
+ delaykey [] =
+ {
+ { str: getenv ("bootdelaykey"), retry: 1 },
+ { str: getenv ("bootdelaykey2"), retry: 1 },
+ { str: getenv ("bootstopkey"), retry: 0 },
+ { str: getenv ("bootstopkey2"), retry: 0 },
+ };
+
+ char presskey [MAX_DELAY_STOP_STR];
+ u_int presskey_len = 0;
+ u_int presskey_max = 0;
+ u_int i;
+
+# ifdef CONFIG_AUTOBOOT_PROMPT
+ printf (CONFIG_AUTOBOOT_PROMPT, bootdelay);
+# endif
+
+# ifdef CONFIG_AUTOBOOT_DELAY_STR
+ if (delaykey[0].str == NULL)
+ delaykey[0].str = CONFIG_AUTOBOOT_DELAY_STR;
+# endif
+# ifdef CONFIG_AUTOBOOT_DELAY_STR2
+ if (delaykey[1].str == NULL)
+ delaykey[1].str = CONFIG_AUTOBOOT_DELAY_STR2;
+# endif
+# ifdef CONFIG_AUTOBOOT_STOP_STR
+ if (delaykey[2].str == NULL)
+ delaykey[2].str = CONFIG_AUTOBOOT_STOP_STR;
+# endif
+# ifdef CONFIG_AUTOBOOT_STOP_STR2
+ if (delaykey[3].str == NULL)
+ delaykey[3].str = CONFIG_AUTOBOOT_STOP_STR2;
+# endif
+
+ for (i = 0; i < sizeof(delaykey) / sizeof(delaykey[0]); i ++) {
+ delaykey[i].len = delaykey[i].str == NULL ?
+ 0 : strlen (delaykey[i].str);
+ delaykey[i].len = delaykey[i].len > MAX_DELAY_STOP_STR ?
+ MAX_DELAY_STOP_STR : delaykey[i].len;
+
+ presskey_max = presskey_max > delaykey[i].len ?
+ presskey_max : delaykey[i].len;
+
+# if DEBUG_BOOTKEYS
+ printf("%s key:<%s>\n",
+ delaykey[i].retry ? "delay" : "stop",
+ delaykey[i].str ? delaykey[i].str : "NULL");
+# endif
+ }
+
+ /* In order to keep up with incoming data, check timeout only
+ * when catch up.
+ */
+ while (!abort && get_ticks() <= etime) {
+ for (i = 0; i < sizeof(delaykey) / sizeof(delaykey[0]); i ++) {
+ if (delaykey[i].len > 0 &&
+ presskey_len >= delaykey[i].len &&
+ memcmp (presskey + presskey_len - delaykey[i].len,
+ delaykey[i].str,
+ delaykey[i].len) == 0) {
+# if DEBUG_BOOTKEYS
+ printf("got %skey\n",
+ delaykey[i].retry ? "delay" : "stop");
+# endif
+
+# ifdef CONFIG_BOOT_RETRY_TIME
+ /* don't retry auto boot */
+ if (! delaykey[i].retry)
+ retry_time = -1;
+# endif
+ abort = 1;
+ }
+ }
+
+ if (tstc()) {
+ if (presskey_len < presskey_max) {
+ presskey [presskey_len ++] = getc();
+ }
+ else {
+ for (i = 0; i < presskey_max - 1; i ++)
+ presskey [i] = presskey [i + 1];
+
+ presskey [i] = getc();
+ }
+ }
+ }
+# if DEBUG_BOOTKEYS
+ if (!abort)
+ printf("key timeout\n");
+# endif
+
+ return abort;
+}
+
+# else /* !defined(CONFIG_AUTOBOOT_KEYED) */
+
+static __inline__ int abortboot(int bootdelay)
+{
+ int abort = 0;
+
+ printf("Hit any key to stop autoboot: %2d ", bootdelay);
+
+#if defined CONFIG_ZERO_BOOTDELAY_CHECK
+ /*
+ * Check if key already pressed
+ * Don't check if bootdelay < 0
+ */
+ if (bootdelay >= 0) {
+ if (tstc()) { /* we got a key press */
+ (void) getc(); /* consume input */
+ printf ("\b\b\b 0\n");
+ return 1; /* don't auto boot */
+ }
+ }
+#endif
+
+ while (bootdelay > 0) {
+ int i;
+
+ --bootdelay;
+ /* delay 100 * 10ms */
+ for (i=0; !abort && i<100; ++i) {
+ if (tstc()) { /* we got a key press */
+ abort = 1; /* don't auto boot */
+ bootdelay = 0; /* no more delay */
+ (void) getc(); /* consume input */
+ break;
+ }
+ udelay (10000);
+ }
+
+ printf ("\b\b\b%2d ", bootdelay);
+ }
+
+ putc ('\n');
+
+ return abort;
+}
+# endif /* CONFIG_AUTOBOOT_KEYED */
+#endif /* CONFIG_BOOTDELAY >= 0 */
+
+/****************************************************************************/
+
+void main_loop (void)
+{
+#ifndef CFG_HUSH_PARSER
+ static char lastcommand[CFG_CBSIZE] = { 0, };
+ int len;
+ int rc = 1;
+ int flag;
+#endif
+
+#if defined(CONFIG_BOOTDELAY) && (CONFIG_BOOTDELAY >= 0)
+ char *s;
+ int bootdelay;
+#endif
+#ifdef CONFIG_PREBOOT
+ char *p;
+#endif
+
+#if defined(CONFIG_VFD) && defined(VFD_TEST_LOGO)
+ ulong bmp = 0; /* default bitmap */
+ extern int trab_vfd (ulong bitmap);
+
+#ifdef CONFIG_MODEM_SUPPORT
+ if (do_mdm_init)
+ bmp = 1; /* alternate bitmap */
+#endif
+ trab_vfd (bmp);
+#endif /* CONFIG_VFD && VFD_TEST_LOGO */
+
+#ifdef CONFIG_MODEM_SUPPORT
+ debug ("DEBUG: main_loop: do_mdm_init=%d\n", do_mdm_init);
+ if (do_mdm_init) {
+ uchar *str = strdup(getenv("mdm_cmd"));
+ setenv ("preboot", str); /* set or delete definition */
+ if (str != NULL)
+ free (str);
+ mdm_init(); /* wait for modem connection */
+ }
+#endif /* CONFIG_MODEM_SUPPORT */
+
+#ifdef CFG_HUSH_PARSER
+ u_boot_hush_start ();
+#endif
+
+#ifdef CONFIG_PREBOOT
+ if ((p = getenv ("preboot")) != NULL) {
+# ifdef CONFIG_AUTOBOOT_KEYED
+ int prev = disable_ctrlc(1); /* disable Control C checking */
+# endif
+
+# ifndef CFG_HUSH_PARSER
+ run_command (p, 0);
+# else
+ parse_string_outer(p, FLAG_PARSE_SEMICOLON |
+ FLAG_EXIT_FROM_LOOP);
+# endif
+
+# ifdef CONFIG_AUTOBOOT_KEYED
+ disable_ctrlc(prev); /* restore Control C checking */
+# endif
+ }
+#endif /* CONFIG_PREBOOT */
+
+#if defined(CONFIG_BOOTDELAY) && (CONFIG_BOOTDELAY >= 0)
+ s = getenv ("bootdelay");
+ bootdelay = s ? (int)simple_strtol(s, NULL, 10) : CONFIG_BOOTDELAY;
+
+#if 0
+ printf ("### main_loop entered:\n\n");
+#endif
+
+# ifdef CONFIG_BOOT_RETRY_TIME
+ s = getenv ("bootretry");
+ if (s != NULL)
+ retry_time = (int)simple_strtoul(s, NULL, 10);
+ else
+ retry_time = CONFIG_BOOT_RETRY_TIME;
+ if (retry_time >= 0 && retry_time < CONFIG_BOOT_RETRY_MIN)
+ retry_time = CONFIG_BOOT_RETRY_MIN;
+# endif /* CONFIG_BOOT_RETRY_TIME */
+
+ s = getenv ("bootcmd");
+ if (bootdelay >= 0 && s && !abortboot (bootdelay)) {
+# ifdef CONFIG_AUTOBOOT_KEYED
+ int prev = disable_ctrlc(1); /* disable Control C checking */
+# endif
+
+# ifndef CFG_HUSH_PARSER
+ run_command (s, 0);
+# else
+ parse_string_outer(s, FLAG_PARSE_SEMICOLON |
+ FLAG_EXIT_FROM_LOOP);
+# endif
+
+# ifdef CONFIG_AUTOBOOT_KEYED
+ disable_ctrlc(prev); /* restore Control C checking */
+# endif
+ }
+#endif /* CONFIG_BOOTDELAY */
+
+ /*
+ * Main Loop for Monitor Command Processing
+ */
+#ifdef CFG_HUSH_PARSER
+ parse_file_outer();
+ /* This point is never reached */
+ for (;;);
+#else
+ for (;;) {
+#ifdef CONFIG_BOOT_RETRY_TIME
+ if (rc >= 0) {
+ /* Saw enough of a valid command to
+ * restart the timeout.
+ */
+ reset_cmd_timeout();
+ }
+#endif
+ len = readline (CFG_PROMPT);
+
+ flag = 0; /* assume no special flags for now */
+ if (len > 0)
+ strcpy (lastcommand, console_buffer);
+ else if (len == 0)
+ flag |= CMD_FLAG_REPEAT;
+#ifdef CONFIG_BOOT_RETRY_TIME
+ else if (len == -2) {
+ /* -2 means timed out, retry autoboot
+ */
+ printf("\nTimed out waiting for command\n");
+# ifdef CONFIG_RESET_TO_RETRY
+ /* Reinit board to run initialization code again */
+ do_reset (NULL, 0, 0, NULL);
+# else
+ return; /* retry autoboot */
+# endif
+ }
+#endif
+
+ if (len == -1)
+ printf ("<INTERRUPT>\n");
+ else
+ rc = run_command (lastcommand, flag);
+
+ if (rc <= 0) {
+ /* invalid command or not repeatable, forget it */
+ lastcommand[0] = 0;
+ }
+ }
+#endif /*CFG_HUSH_PARSER*/
+}
+
+/***************************************************************************
+ * reset command line timeout to retry_time seconds
+ */
+#ifdef CONFIG_BOOT_RETRY_TIME
+void reset_cmd_timeout(void)
+{
+ endtime = endtick(retry_time);
+}
+#endif
+
+/****************************************************************************/
+
+/*
+ * Prompt for input and read a line.
+ * If CONFIG_BOOT_RETRY_TIME is defined and retry_time >= 0,
+ * time out when time goes past endtime (timebase time in ticks).
+ * Return: number of read characters
+ * -1 if break
+ * -2 if timed out
+ */
+int readline (const char *const prompt)
+{
+ char *p = console_buffer;
+ int n = 0; /* buffer index */
+ int plen = 0; /* prompt length */
+ int col; /* output column cnt */
+ char c;
+
+ /* print prompt */
+ if (prompt) {
+ plen = strlen (prompt);
+ puts (prompt);
+ }
+ col = plen;
+
+ for (;;) {
+#ifdef CONFIG_BOOT_RETRY_TIME
+ while (!tstc()) { /* while no incoming data */
+ if (retry_time >= 0 && get_ticks() > endtime)
+ return (-2); /* timed out */
+ }
+#endif
+ WATCHDOG_RESET(); /* Trigger watchdog, if needed */
+
+#ifdef CONFIG_SHOW_ACTIVITY
+ while (!tstc()) {
+ extern void show_activity(int arg);
+ show_activity(0);
+ }
+#endif
+ c = getc();
+
+ /*
+ * Special character handling
+ */
+ switch (c) {
+ case '\r': /* Enter */
+ case '\n':
+ *p = '\0';
+ puts ("\r\n");
+ return (p - console_buffer);
+
+ case 0x03: /* ^C - break */
+ console_buffer[0] = '\0'; /* discard input */
+ return (-1);
+
+ case 0x15: /* ^U - erase line */
+ while (col > plen) {
+ puts (erase_seq);
+ --col;
+ }
+ p = console_buffer;
+ n = 0;
+ continue;
+
+ case 0x17: /* ^W - erase word */
+ p=delete_char(console_buffer, p, &col, &n, plen);
+ while ((n > 0) && (*p != ' ')) {
+ p=delete_char(console_buffer, p, &col, &n, plen);
+ }
+ continue;
+
+ case 0x08: /* ^H - backspace */
+ case 0x7F: /* DEL - backspace */
+ p=delete_char(console_buffer, p, &col, &n, plen);
+ continue;
+
+ default:
+ /*
+ * Must be a normal character then
+ */
+ if (n < CFG_CBSIZE-2) {
+ if (c == '\t') { /* expand TABs */
+ puts (tab_seq+(col&07));
+ col += 8 - (col&07);
+ } else {
+ ++col; /* echo input */
+ putc (c);
+ }
+ *p++ = c;
+ ++n;
+ } else { /* Buffer full */
+ putc ('\a');
+ }
+ }
+ }
+}
+
+/****************************************************************************/
+
+static char * delete_char (char *buffer, char *p, int *colp, int *np, int plen)
+{
+ char *s;
+
+ if (*np == 0) {
+ return (p);
+ }
+
+ if (*(--p) == '\t') { /* will retype the whole line */
+ while (*colp > plen) {
+ puts (erase_seq);
+ (*colp)--;
+ }
+ for (s=buffer; s<p; ++s) {
+ if (*s == '\t') {
+ puts (tab_seq+((*colp) & 07));
+ *colp += 8 - ((*colp) & 07);
+ } else {
+ ++(*colp);
+ putc (*s);
+ }
+ }
+ } else {
+ puts (erase_seq);
+ (*colp)--;
+ }
+ (*np)--;
+ return (p);
+}
+
+/****************************************************************************/
+
+int parse_line (char *line, char *argv[])
+{
+ int nargs = 0;
+
+#ifdef DEBUG_PARSER
+ printf ("parse_line: \"%s\"\n", line);
+#endif
+ while (nargs < CFG_MAXARGS) {
+
+ /* skip any white space */
+ while ((*line == ' ') || (*line == '\t')) {
+ ++line;
+ }
+
+ if (*line == '\0') { /* end of line, no more args */
+ argv[nargs] = NULL;
+#ifdef DEBUG_PARSER
+ printf ("parse_line: nargs=%d\n", nargs);
+#endif
+ return (nargs);
+ }
+
+ argv[nargs++] = line; /* begin of argument string */
+
+ /* find end of string */
+ while (*line && (*line != ' ') && (*line != '\t')) {
+ ++line;
+ }
+
+ if (*line == '\0') { /* end of line, no more args */
+ argv[nargs] = NULL;
+#ifdef DEBUG_PARSER
+ printf ("parse_line: nargs=%d\n", nargs);
+#endif
+ return (nargs);
+ }
+
+ *line++ = '\0'; /* terminate current arg */
+ }
+
+ printf ("** Too many args (max. %d) **\n", CFG_MAXARGS);
+
+#ifdef DEBUG_PARSER
+ printf ("parse_line: nargs=%d\n", nargs);
+#endif
+ return (nargs);
+}
+
+/****************************************************************************/
+
+static void process_macros (const char *input, char *output)
+{
+ char c, prev;
+ const char *varname_start = NULL;
+ int inputcnt = strlen (input);
+ int outputcnt = CFG_CBSIZE;
+ int state = 0; /* 0 = waiting for '$' */
+ /* 1 = waiting for '(' */
+ /* 2 = waiting for ')' */
+
+#ifdef DEBUG_PARSER
+ char *output_start = output;
+
+ printf ("[PROCESS_MACROS] INPUT len %d: \"%s\"\n", strlen(input), input);
+#endif
+
+ prev = '\0'; /* previous character */
+
+ while (inputcnt && outputcnt) {
+ c = *input++;
+ inputcnt--;
+
+ /* remove one level of escape characters */
+ if ((c == '\\') && (prev != '\\')) {
+ if (inputcnt-- == 0)
+ break;
+ prev = c;
+ c = *input++;
+ }
+
+ switch (state) {
+ case 0: /* Waiting for (unescaped) $ */
+ if ((c == '$') && (prev != '\\')) {
+ state++;
+ } else {
+ *(output++) = c;
+ outputcnt--;
+ }
+ break;
+ case 1: /* Waiting for ( */
+ if (c == '(') {
+ state++;
+ varname_start = input;
+ } else {
+ state = 0;
+ *(output++) = '$';
+ outputcnt--;
+
+ if (outputcnt) {
+ *(output++) = c;
+ outputcnt--;
+ }
+ }
+ break;
+ case 2: /* Waiting for ) */
+ if (c == ')') {
+ int i;
+ char envname[CFG_CBSIZE], *envval;
+ int envcnt = input-varname_start-1; /* Varname # of chars */
+
+ /* Get the varname */
+ for (i = 0; i < envcnt; i++) {
+ envname[i] = varname_start[i];
+ }
+ envname[i] = 0;
+
+ /* Get its value */
+ envval = getenv (envname);
+
+ /* Copy into the line if it exists */
+ if (envval != NULL)
+ while ((*envval) && outputcnt) {
+ *(output++) = *(envval++);
+ outputcnt--;
+ }
+ /* Look for another '$' */
+ state = 0;
+ }
+ break;
+ }
+
+ prev = c;
+ }
+
+ if (outputcnt)
+ *output = 0;
+
+#ifdef DEBUG_PARSER
+ printf ("[PROCESS_MACROS] OUTPUT len %d: \"%s\"\n",
+ strlen(output_start), output_start);
+#endif
+}
+
+/****************************************************************************
+ * returns:
+ * 1 - command executed, repeatable
+ * 0 - command executed but not repeatable, interrupted commands are
+ * always considered not repeatable
+ * -1 - not executed (unrecognized, bootd recursion or too many args)
+ * (If cmd is NULL or "" or longer than CFG_CBSIZE-1 it is
+ * considered unrecognized)
+ *
+ * WARNING:
+ *
+ * We must create a temporary copy of the command since the command we get
+ * may be the result from getenv(), which returns a pointer directly to
+ * the environment data, which may change magicly when the command we run
+ * creates or modifies environment variables (like "bootp" does).
+ */
+
+int run_command (const char *cmd, int flag)
+{
+ cmd_tbl_t *cmdtp;
+ char cmdbuf[CFG_CBSIZE]; /* working copy of cmd */
+ char *token; /* start of token in cmdbuf */
+ char *sep; /* end of token (separator) in cmdbuf */
+ char finaltoken[CFG_CBSIZE];
+ char *str = cmdbuf;
+ char *argv[CFG_MAXARGS + 1]; /* NULL terminated */
+ int argc;
+ int repeatable = 1;
+
+#ifdef DEBUG_PARSER
+ printf ("[RUN_COMMAND] cmd[%p]=\"", cmd);
+ puts (cmd ? cmd : "NULL"); /* use puts - string may be loooong */
+ puts ("\"\n");
+#endif
+
+ clear_ctrlc(); /* forget any previous Control C */
+
+ if (!cmd || !*cmd) {
+ return -1; /* empty command */
+ }
+
+ if (strlen(cmd) >= CFG_CBSIZE) {
+ puts ("## Command too long!\n");
+ return -1;
+ }
+
+ strcpy (cmdbuf, cmd);
+
+ /* Process separators and check for invalid
+ * repeatable commands
+ */
+
+#ifdef DEBUG_PARSER
+ printf ("[PROCESS_SEPARATORS] %s\n", cmd);
+#endif
+ while (*str) {
+
+ /*
+ * Find separator, or string end
+ * Allow simple escape of ';' by writing "\;"
+ */
+ for (sep = str; *sep; sep++) {
+ if ((*sep == ';') && /* separator */
+ ( sep != str) && /* past string start */
+ (*(sep-1) != '\\')) /* and NOT escaped */
+ break;
+ }
+
+ /*
+ * Limit the token to data between separators
+ */
+ token = str;
+ if (*sep) {
+ str = sep + 1; /* start of command for next pass */
+ *sep = '\0';
+ }
+ else
+ str = sep; /* no more commands for next pass */
+#ifdef DEBUG_PARSER
+ printf ("token: \"%s\"\n", token);
+#endif
+
+ /* find macros in this token and replace them */
+ process_macros (token, finaltoken);
+
+ /* Extract arguments */
+ argc = parse_line (finaltoken, argv);
+
+ /* Look up command in command table */
+ if ((cmdtp = find_cmd(argv[0])) == NULL) {
+ printf ("Unknown command '%s' - try 'help'\n", argv[0]);
+ return -1; /* give up after bad command */
+ }
+
+ /* found - check max args */
+ if (argc > cmdtp->maxargs) {
+ printf ("Usage:\n%s\n", cmdtp->usage);
+ return -1;
+ }
+
+#if (CONFIG_COMMANDS & CFG_CMD_BOOTD)
+ /* avoid "bootd" recursion */
+ if (cmdtp->cmd == do_bootd) {
+#ifdef DEBUG_PARSER
+ printf ("[%s]\n", finaltoken);
+#endif
+ if (flag & CMD_FLAG_BOOTD) {
+ printf ("'bootd' recursion detected\n");
+ return -1;
+ }
+ else
+ flag |= CMD_FLAG_BOOTD;
+ }
+#endif /* CFG_CMD_BOOTD */
+
+ /* OK - call function to do the command */
+ if ((cmdtp->cmd) (cmdtp, flag, argc, argv) != 0) {
+ return (-1);
+ }
+
+ repeatable &= cmdtp->repeatable;
+
+ /* Did the user stop this? */
+ if (had_ctrlc ())
+ return 0; /* if stopped then not repeatable */
+ }
+
+ return repeatable;
+}
+
+/****************************************************************************/
+
+#if (CONFIG_COMMANDS & CFG_CMD_RUN)
+int do_run (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
+{
+ int i;
+ int rcode = 1;
+
+ if (argc < 2) {
+ printf ("Usage:\n%s\n", cmdtp->usage);
+ return 1;
+ }
+
+ for (i=1; i<argc; ++i) {
+#ifndef CFG_HUSH_PARSER
+ if (run_command (getenv (argv[i]), flag) != -1) ++rcode;
+#else
+ if (parse_string_outer(getenv (argv[i]),
+ FLAG_PARSE_SEMICOLON | FLAG_EXIT_FROM_LOOP) == 0) ++rcode;
+#endif
+ }
+ return ((rcode == i) ? 0 : 1);
+}
+#endif
--- /dev/null
+/*
+ * (C) Copyright 2001
+ * Gerald Van Baren, Custom IDEAS, vanbaren@cideas.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
+ */
+
+/*
+ * This provides a bit-banged interface to the ethernet MII management
+ * channel.
+ */
+
+#include <common.h>
+#include <miiphy.h>
+
+#if defined(CONFIG_MII) || (CONFIG_COMMANDS & CFG_CMD_MII)
+
+/*****************************************************************************
+ *
+ * Read the OUI, manufacture's model number, and revision number.
+ *
+ * OUI: 22 bits (unsigned int)
+ * Model: 6 bits (unsigned char)
+ * Revision: 4 bits (unsigned char)
+ *
+ * Returns:
+ * 0 on success
+ */
+int miiphy_info (unsigned char addr,
+ unsigned int *oui,
+ unsigned char *model, unsigned char *rev)
+{
+ unsigned int reg = 0;
+
+ /*
+ * Trick: we are reading two 16 registers into a 32 bit variable
+ * so we do a 16 read into the high order bits of the variable (big
+ * endian, you know), shift it down 16 bits, and the read the rest.
+ */
+ if (miiphy_read (addr, PHY_PHYIDR2, (unsigned short *) ®) != 0) {
+#ifdef DEBUG
+ printf ("PHY ID register 2 read failed\n");
+#endif
+ return (-1);
+ }
+ reg >>= 16;
+
+#ifdef DEBUG
+ printf ("PHY_PHYIDR2 @ 0x%x = 0x%04x\n", addr, reg);
+#endif
+ if (reg == 0xFFFF) {
+ /* No physical device present at this address */
+ return (-1);
+ }
+
+ if (miiphy_read (addr, PHY_PHYIDR1, (unsigned short *) ®) != 0) {
+#ifdef DEBUG
+ printf ("PHY ID register 1 read failed\n");
+#endif
+ return (-1);
+ }
+#ifdef DEBUG
+ printf ("PHY_PHYIDR[1,2] @ 0x%x = 0x%08x\n", addr, reg);
+#endif
+ *oui = ( reg >> 10);
+ *model = (unsigned char) ((reg >> 4) & 0x0000003F);
+ *rev = (unsigned char) ( reg & 0x0000000F);
+ return (0);
+}
+
+
+/*****************************************************************************
+ *
+ * Reset the PHY.
+ * Returns:
+ * 0 on success
+ */
+int miiphy_reset (unsigned char addr)
+{
+ unsigned short reg;
+ int loop_cnt;
+
+ if (miiphy_write (addr, PHY_BMCR, 0x8000) != 0) {
+#ifdef DEBUG
+ printf ("PHY reset failed\n");
+#endif
+ return (-1);
+ }
+
+ /*
+ * Poll the control register for the reset bit to go to 0 (it is
+ * auto-clearing). This should happen within 0.5 seconds per the
+ * IEEE spec.
+ */
+ loop_cnt = 0;
+ reg = 0x8000;
+ while (((reg & 0x8000) != 0) && (loop_cnt++ < 1000000)) {
+ if (miiphy_read (addr, PHY_BMCR, ®) != 0) {
+# ifdef DEBUG
+ printf ("PHY status read failed\n");
+# endif
+ return (-1);
+ }
+ }
+ if ((reg & 0x8000) == 0) {
+ return (0);
+ } else {
+ printf ("PHY reset timed out\n");
+ return (-1);
+ }
+ return (0);
+}
+
+
+/*****************************************************************************
+ *
+ * Determine the ethernet speed (10/100).
+ */
+int miiphy_speed (unsigned char addr)
+{
+ unsigned short reg;
+
+ if (miiphy_read (addr, PHY_ANLPAR, ®)) {
+ printf ("PHY speed1 read failed, assuming 10bT\n");
+ return (_10BASET);
+ }
+
+ if ((reg & PHY_ANLPAR_100) != 0) {
+ return (_100BASET);
+ } else {
+ return (_10BASET);
+ }
+}
+
+
+/*****************************************************************************
+ *
+ * Determine full/half duplex.
+ */
+int miiphy_duplex (unsigned char addr)
+{
+ unsigned short reg;
+
+ if (miiphy_read (addr, PHY_ANLPAR, ®)) {
+ printf ("PHY duplex read failed, assuming half duplex\n");
+ return (HALF);
+ }
+
+ if ((reg & (PHY_ANLPAR_10FD | PHY_ANLPAR_TXFD)) != 0) {
+ return (FULL);
+ } else {
+ return (HALF);
+ }
+}
+
+#endif /* CONFIG_MII || (CONFIG_COMMANDS & CFG_CMD_MII) */
--- /dev/null
+/*
+ * (C) Copyright 2001, 2002
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ * This has been changed substantially by Gerald Van Baren, Custom IDEAS,
+ * vanbaren@cideas.com. It was heavily influenced by LiMon, written by
+ * Neil Russell.
+ */
+
+#include <common.h>
+#ifdef CONFIG_MPC8260 /* only valid for MPC8260 */
+#include <ioports.h>
+#endif
+#include <i2c.h>
+
+#if defined(CONFIG_SOFT_I2C)
+
+/* #define DEBUG_I2C */
+
+
+/*-----------------------------------------------------------------------
+ * Definitions
+ */
+
+#define RETRIES 0
+
+
+#define I2C_ACK 0 /* PD_SDA level to ack a byte */
+#define I2C_NOACK 1 /* PD_SDA level to noack a byte */
+
+
+#ifdef DEBUG_I2C
+#define PRINTD(fmt,args...) do { \
+ DECLARE_GLOBAL_DATA_PTR; \
+ if (gd->have_console) \
+ printf (fmt ,##args); \
+ } while (0)
+#else
+#define PRINTD(fmt,args...)
+#endif
+
+/*-----------------------------------------------------------------------
+ * Local functions
+ */
+static void send_reset (void);
+static void send_start (void);
+static void send_stop (void);
+static void send_ack (int);
+static int write_byte (uchar byte);
+static uchar read_byte (int);
+
+
+/*-----------------------------------------------------------------------
+ * Send a reset sequence consisting of 9 clocks with the data signal high
+ * to clock any confused device back into an idle state. Also send a
+ * <stop> at the end of the sequence for belts & suspenders.
+ */
+static void send_reset(void)
+{
+#ifdef CONFIG_MPC8260
+ volatile ioport_t *iop = ioport_addr((immap_t *)CFG_IMMR, I2C_PORT);
+#endif
+#ifdef CONFIG_8xx
+ volatile immap_t *immr = (immap_t *)CFG_IMMR;
+#endif
+ int j;
+
+ I2C_ACTIVE;
+ I2C_SDA(1);
+ for(j = 0; j < 9; j++) {
+ I2C_SCL(0);
+ I2C_DELAY;
+ I2C_DELAY;
+ I2C_SCL(1);
+ I2C_DELAY;
+ I2C_DELAY;
+ }
+ send_stop();
+ I2C_TRISTATE;
+}
+
+/*-----------------------------------------------------------------------
+ * START: High -> Low on SDA while SCL is High
+ */
+static void send_start(void)
+{
+#ifdef CONFIG_MPC8260
+ volatile ioport_t *iop = ioport_addr((immap_t *)CFG_IMMR, I2C_PORT);
+#endif
+#ifdef CONFIG_8xx
+ volatile immap_t *immr = (immap_t *)CFG_IMMR;
+#endif
+
+ I2C_DELAY;
+ I2C_SDA(1);
+ I2C_ACTIVE;
+ I2C_DELAY;
+ I2C_SCL(1);
+ I2C_DELAY;
+ I2C_SDA(0);
+ I2C_DELAY;
+}
+
+/*-----------------------------------------------------------------------
+ * STOP: Low -> High on SDA while SCL is High
+ */
+static void send_stop(void)
+{
+#ifdef CONFIG_MPC8260
+ volatile ioport_t *iop = ioport_addr((immap_t *)CFG_IMMR, I2C_PORT);
+#endif
+#ifdef CONFIG_8xx
+ volatile immap_t *immr = (immap_t *)CFG_IMMR;
+#endif
+
+ I2C_SCL(0);
+ I2C_DELAY;
+ I2C_SDA(0);
+ I2C_ACTIVE;
+ I2C_DELAY;
+ I2C_SCL(1);
+ I2C_DELAY;
+ I2C_SDA(1);
+ I2C_DELAY;
+ I2C_TRISTATE;
+}
+
+
+/*-----------------------------------------------------------------------
+ * ack should be I2C_ACK or I2C_NOACK
+ */
+static void send_ack(int ack)
+{
+#ifdef CONFIG_MPC8260
+ volatile ioport_t *iop = ioport_addr((immap_t *)CFG_IMMR, I2C_PORT);
+#endif
+#ifdef CONFIG_8xx
+ volatile immap_t *immr = (immap_t *)CFG_IMMR;
+#endif
+
+ I2C_ACTIVE;
+ I2C_SCL(0);
+ I2C_DELAY;
+
+ I2C_SDA(ack);
+
+ I2C_ACTIVE;
+ I2C_DELAY;
+ I2C_SCL(1);
+ I2C_DELAY;
+ I2C_DELAY;
+ I2C_SCL(0);
+ I2C_DELAY;
+}
+
+
+/*-----------------------------------------------------------------------
+ * Send 8 bits and look for an acknowledgement.
+ */
+static int write_byte(uchar data)
+{
+#ifdef CONFIG_MPC8260
+ volatile ioport_t *iop = ioport_addr((immap_t *)CFG_IMMR, I2C_PORT);
+#endif
+#ifdef CONFIG_8xx
+ volatile immap_t *immr = (immap_t *)CFG_IMMR;
+#endif
+ int j;
+ int nack;
+
+ I2C_ACTIVE;
+ for(j = 0; j < 8; j++) {
+ I2C_SCL(0);
+ I2C_DELAY;
+ I2C_SDA(data & 0x80);
+ I2C_DELAY;
+ I2C_SCL(1);
+ I2C_DELAY;
+ I2C_DELAY;
+
+ data <<= 1;
+ }
+
+ /*
+ * Look for an <ACK>(negative logic) and return it.
+ */
+ I2C_SCL(0);
+ I2C_DELAY;
+ I2C_SDA(1);
+ I2C_TRISTATE;
+ I2C_DELAY;
+ I2C_SCL(1);
+ I2C_DELAY;
+ I2C_DELAY;
+ nack = I2C_READ;
+ I2C_SCL(0);
+ I2C_DELAY;
+ I2C_ACTIVE;
+
+ return(nack); /* not a nack is an ack */
+}
+
+
+/*-----------------------------------------------------------------------
+ * if ack == I2C_ACK, ACK the byte so can continue reading, else
+ * send I2C_NOACK to end the read.
+ */
+static uchar read_byte(int ack)
+{
+#ifdef CONFIG_MPC8260
+ volatile ioport_t *iop = ioport_addr((immap_t *)CFG_IMMR, I2C_PORT);
+#endif
+#ifdef CONFIG_8xx
+ volatile immap_t *immr = (immap_t *)CFG_IMMR;
+#endif
+ int data;
+ int j;
+
+ /*
+ * Read 8 bits, MSB first.
+ */
+ I2C_TRISTATE;
+ data = 0;
+ for(j = 0; j < 8; j++) {
+ I2C_SCL(0);
+ I2C_DELAY;
+ I2C_SCL(1);
+ I2C_DELAY;
+ data <<= 1;
+ data |= I2C_READ;
+ I2C_DELAY;
+ }
+ send_ack(ack);
+
+ return(data);
+}
+
+/*=====================================================================*/
+/* Public Functions */
+/*=====================================================================*/
+
+/*-----------------------------------------------------------------------
+ * Initialization
+ */
+void i2c_init (int speed, int slaveaddr)
+{
+#ifdef CONFIG_8xx
+ volatile immap_t *immr = (immap_t *)CFG_IMMR;
+#endif
+
+#ifdef I2C_INIT
+ I2C_INIT;
+#endif
+ /*
+ * WARNING: Do NOT save speed in a static variable: if the
+ * I2C routines are called before RAM is initialized (to read
+ * the DIMM SPD, for instance), RAM won't be usable and your
+ * system will crash.
+ */
+ send_reset ();
+}
+
+/*-----------------------------------------------------------------------
+ * Probe to see if a chip is present. Also good for checking for the
+ * completion of EEPROM writes since the chip stops responding until
+ * the write completes (typically 10mSec).
+ */
+int i2c_probe(uchar addr)
+{
+ int rc;
+
+ send_start();
+ rc = write_byte ((addr << 1) | 1);
+ send_stop();
+
+ return (rc ? 1 : 0);
+}
+
+/*-----------------------------------------------------------------------
+ * Read bytes
+ */
+int i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len)
+{
+ int shift;
+ PRINTD("i2c_read: chip %02X addr %02X alen %d buffer %p len %d\n",
+ chip, addr, alen, buffer, len);
+
+#ifdef CFG_I2C_EEPROM_ADDR_OVERFLOW
+ /*
+ * EEPROM chips that implement "address overflow" are ones
+ * like Catalyst 24WC04/08/16 which has 9/10/11 bits of
+ * address and the extra bits end up in the "chip address"
+ * bit slots. This makes a 24WC08 (1Kbyte) chip look like
+ * four 256 byte chips.
+ *
+ * Note that we consider the length of the address field to
+ * still be one byte because the extra address bits are
+ * hidden in the chip address.
+ */
+ chip |= ((addr >> (alen * 8)) & CFG_I2C_EEPROM_ADDR_OVERFLOW);
+
+ PRINTD("i2c_read: fix addr_overflow: chip %02X addr %02X\n",
+ chip, addr);
+#endif
+
+ /*
+ * Do the addressing portion of a write cycle to set the
+ * chip's address pointer. If the address length is zero,
+ * don't do the normal write cycle to set the address pointer,
+ * there is no address pointer in this chip.
+ */
+ send_start();
+ if(alen > 0) {
+ if(write_byte(chip << 1)) { /* write cycle */
+ send_stop();
+ PRINTD("i2c_read, no chip responded %02X\n", chip);
+ return(1);
+ }
+ shift = (alen-1) * 8;
+ while(alen-- > 0) {
+ if(write_byte(addr >> shift)) {
+ PRINTD("i2c_read, address not <ACK>ed\n");
+ return(1);
+ }
+ shift -= 8;
+ }
+ send_stop(); /* reportedly some chips need a full stop */
+ send_start();
+ }
+ /*
+ * Send the chip address again, this time for a read cycle.
+ * Then read the data. On the last byte, we do a NACK instead
+ * of an ACK(len == 0) to terminate the read.
+ */
+ write_byte((chip << 1) | 1); /* read cycle */
+ while(len-- > 0) {
+ *buffer++ = read_byte(len == 0);
+ }
+ send_stop();
+ return(0);
+}
+
+/*-----------------------------------------------------------------------
+ * Write bytes
+ */
+int i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len)
+{
+ int shift, failures = 0;
+
+ PRINTD("i2c_write: chip %02X addr %02X alen %d buffer %p len %d\n",
+ chip, addr, alen, buffer, len);
+
+ send_start();
+ if(write_byte(chip << 1)) { /* write cycle */
+ send_stop();
+ PRINTD("i2c_write, no chip responded %02X\n", chip);
+ return(1);
+ }
+ shift = (alen-1) * 8;
+ while(alen-- > 0) {
+ if(write_byte(addr >> shift)) {
+ PRINTD("i2c_write, address not <ACK>ed\n");
+ return(1);
+ }
+ shift -= 8;
+ }
+
+ while(len-- > 0) {
+ if(write_byte(*buffer++)) {
+ failures++;
+ }
+ }
+ send_stop();
+ return(failures);
+}
+
+/*-----------------------------------------------------------------------
+ * Read a register
+ */
+uchar i2c_reg_read(uchar i2c_addr, uchar reg)
+{
+ char buf;
+
+ i2c_read(i2c_addr, reg, 1, &buf, 1);
+
+ return(buf);
+}
+
+/*-----------------------------------------------------------------------
+ * Write a register
+ */
+void i2c_reg_write(uchar i2c_addr, uchar reg, uchar val)
+{
+ i2c_write(i2c_addr, reg, 1, &val, 1);
+}
+
+
+#endif /* CONFIG_SOFT_I2C */
--- /dev/null
+#
+# (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 = serial.o interrupts.o cpu.o
+
+all: .depend $(START) $(LIB)
+
+$(LIB): $(OBJS)
+ $(AR) crv $@ $(OBJS)
+
+#########################################################################
+
+.depend: Makefile $(START:.o=.S) $(OBJS:.o=.c)
+ $(CC) -M $(CFLAGS) $(START:.o=.S) $(OBJS:.o=.c) > $@
+
+sinclude .depend
+
+#########################################################################
--- /dev/null
+/*
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Marius Groeger <mgroeger@sysgo.de>
+ *
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Alex Zuepke <azu@sysgo.de>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <clps7111.h>
+
+#include <asm/proc-armv/ptrace.h>
+
+extern void reset_cpu(ulong addr);
+
+/* we always count down the max. */
+#define TIMER_LOAD_VAL 0xffff
+
+/* macro to read the 16 bit timer */
+#define READ_TIMER (IO_TC1D & 0xffff)
+
+#ifdef CONFIG_USE_IRQ
+/* enable IRQ/FIQ interrupts */
+void enable_interrupts (void)
+{
+ unsigned long temp;
+ __asm__ __volatile__("mrs %0, cpsr\n"
+ "bic %0, %0, #0x80\n"
+ "msr cpsr_c, %0"
+ : "=r" (temp)
+ :
+ : "memory");
+}
+
+
+/*
+ * disable IRQ/FIQ interrupts
+ * returns true if interrupts had been enabled before we disabled them
+ */
+int disable_interrupts (void)
+{
+ unsigned long old,temp;
+ __asm__ __volatile__("mrs %0, cpsr\n"
+ "orr %1, %0, #0x80\n"
+ "msr cpsr_c, %1"
+ : "=r" (old), "=r" (temp)
+ :
+ : "memory");
+ return (old & 0x80) == 0;
+}
+#else
+void enable_interrupts (void)
+{
+ return;
+}
+int disable_interrupts (void)
+{
+ return 0;
+}
+#endif
+
+
+
+void bad_mode (void)
+{
+ panic ("Resetting CPU ...\n");
+ reset_cpu (0);
+}
+
+void show_regs (struct pt_regs *regs)
+{
+ unsigned long flags;
+ const char *processor_modes[] =
+ { "USER_26", "FIQ_26", "IRQ_26", "SVC_26", "UK4_26", "UK5_26",
+"UK6_26", "UK7_26",
+ "UK8_26", "UK9_26", "UK10_26", "UK11_26", "UK12_26", "UK13_26",
+ "UK14_26", "UK15_26",
+ "USER_32", "FIQ_32", "IRQ_32", "SVC_32", "UK4_32", "UK5_32",
+ "UK6_32", "ABT_32",
+ "UK8_32", "UK9_32", "UK10_32", "UND_32", "UK12_32", "UK13_32",
+ "UK14_32", "SYS_32"
+ };
+
+ flags = condition_codes (regs);
+
+ printf ("pc : [<%08lx>] lr : [<%08lx>]\n"
+ "sp : %08lx ip : %08lx fp : %08lx\n",
+ instruction_pointer (regs),
+ regs->ARM_lr, regs->ARM_sp, regs->ARM_ip, regs->ARM_fp);
+ printf ("r10: %08lx r9 : %08lx r8 : %08lx\n",
+ regs->ARM_r10, regs->ARM_r9, regs->ARM_r8);
+ printf ("r7 : %08lx r6 : %08lx r5 : %08lx r4 : %08lx\n",
+ regs->ARM_r7, regs->ARM_r6, regs->ARM_r5, regs->ARM_r4);
+ printf ("r3 : %08lx r2 : %08lx r1 : %08lx r0 : %08lx\n",
+ regs->ARM_r3, regs->ARM_r2, regs->ARM_r1, regs->ARM_r0);
+ printf ("Flags: %c%c%c%c",
+ flags & CC_N_BIT ? 'N' : 'n',
+ flags & CC_Z_BIT ? 'Z' : 'z',
+ flags & CC_C_BIT ? 'C' : 'c', flags & CC_V_BIT ? 'V' : 'v');
+ printf (" IRQs %s FIQs %s Mode %s%s\n",
+ interrupts_enabled (regs) ? "on" : "off",
+ fast_interrupts_enabled (regs) ? "on" : "off",
+ processor_modes[processor_mode (regs)],
+ thumb_mode (regs) ? " (T)" : "");
+}
+
+void do_undefined_instruction (struct pt_regs *pt_regs)
+{
+ printf ("undefined instruction\n");
+ show_regs (pt_regs);
+ bad_mode ();
+}
+
+void do_software_interrupt (struct pt_regs *pt_regs)
+{
+ printf ("software interrupt\n");
+ show_regs (pt_regs);
+ bad_mode ();
+}
+
+void do_prefetch_abort (struct pt_regs *pt_regs)
+{
+ printf ("prefetch abort\n");
+ show_regs (pt_regs);
+ bad_mode ();
+}
+
+void do_data_abort (struct pt_regs *pt_regs)
+{
+ printf ("data abort\n");
+ show_regs (pt_regs);
+ bad_mode ();
+}
+
+void do_not_used (struct pt_regs *pt_regs)
+{
+ printf ("not used\n");
+ show_regs (pt_regs);
+ bad_mode ();
+}
+
+void do_fiq (struct pt_regs *pt_regs)
+{
+ printf ("fast interrupt request\n");
+ show_regs (pt_regs);
+ bad_mode ();
+}
+
+void do_irq (struct pt_regs *pt_regs)
+{
+ printf ("interrupt request\n");
+ show_regs (pt_regs);
+ bad_mode ();
+}
+
+static ulong timestamp;
+static ulong lastdec;
+
+int interrupt_init (void)
+{
+ /* disable all interrupts */
+ IO_INTMR1 = 0;
+
+ /* operate timer 1 in prescale mode */
+ IO_SYSCON1 |= SYSCON1_TC1M;
+
+ /* select 2kHz clock source for timer 1 */
+ IO_SYSCON1 &= ~SYSCON1_TC1S;
+
+ /* set timer 1 counter */
+ lastdec = IO_TC1D = TIMER_LOAD_VAL;
+ timestamp = 0;
+
+ return (0);
+}
+
+/*
+ * timer without interrupts
+ */
+
+void reset_timer (void)
+{
+ reset_timer_masked ();
+}
+
+ulong get_timer (ulong base)
+{
+ return get_timer_masked () - base;
+}
+
+void set_timer (ulong t)
+{
+ timestamp = t;
+}
+
+void udelay (unsigned long usec)
+{
+ ulong tmo;
+
+ tmo = usec / 1000;
+ tmo *= CFG_HZ;
+ tmo /= 1000;
+
+ tmo += get_timer (0);
+
+ while (get_timer_masked () < tmo)
+ /*NOP*/;
+}
+
+void reset_timer_masked (void)
+{
+ /* reset time */
+ lastdec = READ_TIMER;
+ timestamp = 0;
+}
+
+ulong get_timer_masked (void)
+{
+ ulong now = READ_TIMER;
+
+ if (lastdec >= now) {
+ /* normal mode */
+ timestamp += lastdec - now;
+ } else {
+ /* we have an overflow ... */
+ timestamp += lastdec + TIMER_LOAD_VAL - now;
+ }
+ lastdec = now;
+
+ return timestamp;
+}
+
+void udelay_masked (unsigned long usec)
+{
+ ulong tmo;
+
+ tmo = usec / 1000;
+ tmo *= CFG_HZ;
+ tmo /= 1000;
+
+ reset_timer_masked ();
+
+ while (get_timer_masked () < tmo)
+ /*NOP*/;
+}
--- /dev/null
+#
+# (C) Copyright 2000, 2001, 2002
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+include $(TOPDIR)/config.mk
+
+LIB = lib$(CPU).a
+
+START = start.o
+OBJS = serial.o interrupts.o cpu.o speed.o
+
+all: .depend $(START) $(LIB)
+
+$(LIB): $(OBJS)
+ $(AR) crv $@ $(OBJS)
+
+#########################################################################
+
+.depend: Makefile $(START:.o=.S) $(OBJS:.o=.c)
+ $(CC) -M $(CFLAGS) $(START:.o=.S) $(OBJS:.o=.c) > $@
+
+sinclude .depend
+
+#########################################################################
--- /dev/null
+/*
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Marius Groeger <mgroeger@sysgo.de>
+ *
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Alex Zuepke <azu@sysgo.de>
+ *
+ * (C) Copyright 2002
+ * Gary Jennejohn, DENX Software Engineering, <gj@denx.de>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <arm920t.h>
+#if defined(CONFIG_S3C2400)
+#include <s3c2400.h>
+#elif defined(CONFIG_S3C2410)
+#include <s3c2410.h>
+#endif
+
+#include <asm/proc-armv/ptrace.h>
+
+extern void reset_cpu(ulong addr);
+int timer_load_val = 0;
+
+/* macro to read the 16 bit timer */
+#define READ_TIMER (rTCNTO4 & 0xffff)
+
+#ifdef CONFIG_USE_IRQ
+/* enable IRQ interrupts */
+void enable_interrupts (void)
+{
+ unsigned long temp;
+ __asm__ __volatile__("mrs %0, cpsr\n"
+ "bic %0, %0, #0x80\n"
+ "msr cpsr_c, %0"
+ : "=r" (temp)
+ :
+ : "memory");
+}
+
+
+/*
+ * disable IRQ/FIQ interrupts
+ * returns true if interrupts had been enabled before we disabled them
+ */
+int disable_interrupts (void)
+{
+ unsigned long old,temp;
+ __asm__ __volatile__("mrs %0, cpsr\n"
+ "orr %1, %0, #0xc0\n"
+ "msr cpsr_c, %1"
+ : "=r" (old), "=r" (temp)
+ :
+ : "memory");
+ return (old & 0x80) == 0;
+}
+#else
+void enable_interrupts (void)
+{
+ return;
+}
+int disable_interrupts (void)
+{
+ return 0;
+}
+#endif
+
+
+
+void bad_mode (void)
+{
+ panic ("Resetting CPU ...\n");
+ reset_cpu (0);
+}
+
+void show_regs (struct pt_regs *regs)
+{
+ unsigned long flags;
+ const char *processor_modes[] = {
+ "USER_26", "FIQ_26", "IRQ_26", "SVC_26",
+ "UK4_26", "UK5_26", "UK6_26", "UK7_26",
+ "UK8_26", "UK9_26", "UK10_26", "UK11_26",
+ "UK12_26", "UK13_26", "UK14_26", "UK15_26",
+ "USER_32", "FIQ_32", "IRQ_32", "SVC_32",
+ "UK4_32", "UK5_32", "UK6_32", "ABT_32",
+ "UK8_32", "UK9_32", "UK10_32", "UND_32",
+ "UK12_32", "UK13_32", "UK14_32", "SYS_32",
+ };
+
+ flags = condition_codes (regs);
+
+ printf ("pc : [<%08lx>] lr : [<%08lx>]\n"
+ "sp : %08lx ip : %08lx fp : %08lx\n",
+ instruction_pointer (regs),
+ regs->ARM_lr, regs->ARM_sp, regs->ARM_ip, regs->ARM_fp);
+ printf ("r10: %08lx r9 : %08lx r8 : %08lx\n",
+ regs->ARM_r10, regs->ARM_r9, regs->ARM_r8);
+ printf ("r7 : %08lx r6 : %08lx r5 : %08lx r4 : %08lx\n",
+ regs->ARM_r7, regs->ARM_r6, regs->ARM_r5, regs->ARM_r4);
+ printf ("r3 : %08lx r2 : %08lx r1 : %08lx r0 : %08lx\n",
+ regs->ARM_r3, regs->ARM_r2, regs->ARM_r1, regs->ARM_r0);
+ printf ("Flags: %c%c%c%c",
+ flags & CC_N_BIT ? 'N' : 'n',
+ flags & CC_Z_BIT ? 'Z' : 'z',
+ flags & CC_C_BIT ? 'C' : 'c', flags & CC_V_BIT ? 'V' : 'v');
+ printf (" IRQs %s FIQs %s Mode %s%s\n",
+ interrupts_enabled (regs) ? "on" : "off",
+ fast_interrupts_enabled (regs) ? "on" : "off",
+ processor_modes[processor_mode (regs)],
+ thumb_mode (regs) ? " (T)" : "");
+}
+
+void do_undefined_instruction (struct pt_regs *pt_regs)
+{
+ printf ("undefined instruction\n");
+ show_regs (pt_regs);
+ bad_mode ();
+}
+
+void do_software_interrupt (struct pt_regs *pt_regs)
+{
+ printf ("software interrupt\n");
+ show_regs (pt_regs);
+ bad_mode ();
+}
+
+void do_prefetch_abort (struct pt_regs *pt_regs)
+{
+ printf ("prefetch abort\n");
+ show_regs (pt_regs);
+ bad_mode ();
+}
+
+void do_data_abort (struct pt_regs *pt_regs)
+{
+ printf ("data abort\n");
+ show_regs (pt_regs);
+ bad_mode ();
+}
+
+void do_not_used (struct pt_regs *pt_regs)
+{
+ printf ("not used\n");
+ show_regs (pt_regs);
+ bad_mode ();
+}
+
+void do_fiq (struct pt_regs *pt_regs)
+{
+ printf ("fast interrupt request\n");
+ show_regs (pt_regs);
+ bad_mode ();
+}
+
+void do_irq (struct pt_regs *pt_regs)
+{
+ printf ("interrupt request\n");
+ show_regs (pt_regs);
+ bad_mode ();
+}
+
+static ulong timestamp;
+static ulong lastdec;
+
+int interrupt_init (void)
+{
+ /* use PWM Timer 4 because it has no output */
+ /* prescaler for Timer 4 is 16 */
+ rTCFG0 = 0x0f00;
+ if (timer_load_val == 0)
+ {
+ /*
+ * for 10 ms clock period @ PCLK with 4 bit divider = 1/2
+ * (default) and prescaler = 16. Should be 10390
+ * @33.25MHz and 15625 @ 50 MHz
+ */
+ timer_load_val = get_PCLK()/(2 * 16 * 100);
+ }
+ /* load value for 10 ms timeout */
+ lastdec = rTCNTB4 = timer_load_val;
+ /* auto load, manual update of Timer 4 */
+ rTCON = 0x600000;
+ /* auto load, start Timer 4 */
+ rTCON = 0x500000;
+ timestamp = 0;
+
+ return (0);
+}
+
+/*
+ * timer without interrupts
+ */
+
+void reset_timer (void)
+{
+ reset_timer_masked ();
+}
+
+ulong get_timer (ulong base)
+{
+ return get_timer_masked () - base;
+}
+
+void set_timer (ulong t)
+{
+ timestamp = t;
+}
+
+void udelay (unsigned long usec)
+{
+ ulong tmo;
+
+ tmo = usec / 1000;
+ tmo *= (timer_load_val * 100);
+ tmo /= 1000;
+
+ tmo += get_timer (0);
+
+ while (get_timer_masked () < tmo)
+ /*NOP*/;
+}
+
+void reset_timer_masked (void)
+{
+ /* reset time */
+ lastdec = READ_TIMER;
+ timestamp = 0;
+}
+
+ulong get_timer_masked (void)
+{
+ ulong now = READ_TIMER;
+
+ if (lastdec >= now) {
+ /* normal mode */
+ timestamp += lastdec - now;
+ } else {
+ /* we have an overflow ... */
+ timestamp += lastdec + timer_load_val - now;
+ }
+ lastdec = now;
+
+ return timestamp;
+}
+
+void udelay_masked (unsigned long usec)
+{
+ ulong tmo;
+
+ tmo = usec / 1000;
+ tmo *= (timer_load_val * 100);
+ tmo /= 1000;
+
+ reset_timer_masked ();
+
+ while (get_timer_masked () < tmo)
+ /*NOP*/;
+}
+
+/*
+ * This function is derived from PowerPC code (read timebase as long long).
+ * On ARM it just returns the timer value.
+ */
+unsigned long long get_ticks(void)
+{
+ return get_timer(0);
+}
+
+/*
+ * This function is derived from PowerPC code (timebase clock frequency).
+ * On ARM it returns the number of timer ticks per second.
+ */
+ulong get_tbclk (void)
+{
+ ulong tbclk;
+
+#if defined(CONFIG_SMDK2400) || defined(CONFIG_TRAB)
+ tbclk = timer_load_val * 100;
+#elif defined(CONFIG_SMDK2410)
+ tbclk = CFG_HZ;
+#endif
+
+ return tbclk;
+}
--- /dev/null
+/*
+ * (C) Copyright 2002
+ * Gary Jennejohn, DENX Software Engineering, <gj@denx.de>
+ *
+ * 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(CONFIG_S3C2400) || defined(CONFIG_TRAB)
+#include <s3c2400.h>
+#elif defined(CONFIG_S3C2410)
+#include <s3c2410.h>
+#endif
+
+
+void serial_setbrg (void)
+{
+ DECLARE_GLOBAL_DATA_PTR;
+
+ int i;
+ unsigned int reg = 0;
+
+ /* value is calculated so : (int)(PCLK/16./baudrate) -1 */
+ reg = get_PCLK() / (16 * gd->baudrate) - 1;
+
+#ifdef CONFIG_SERIAL1
+ /* FIFO enable, Tx/Rx FIFO clear */
+ rUFCON0 = 0x07;
+ rUMCON0 = 0x0;
+ /* Normal,No parity,1 stop,8 bit */
+ rULCON0 = 0x3;
+ /*
+ * tx=level,rx=edge,disable timeout int.,enable rx error int.,
+ * normal,interrupt or polling
+ */
+ rUCON0 = 0x245;
+ rUBRDIV0 = reg;
+
+#ifdef CONFIG_HWFLOW
+ rUMCON0 = 0x1; /* RTS up */
+#endif
+ for (i = 0; i < 100; i++);
+#elif CONFIG_SERIAL2
+# if defined(CONFIG_TRAB)
+# #error "TRAB supports only CONFIG_SERIAL1"
+# endif
+ /* FIFO enable, Tx/Rx FIFO clear */
+ rUFCON1 = 0x06;
+ rUMCON1 = 0x0;
+ /* Normal,No parity,1 stop,8 bit */
+ rULCON1 = 0x3;
+ /*
+ * tx=level,rx=edge,disable timeout int.,enable rx error int.,
+ * normal,interrupt or polling
+ */
+ rUCON1 = 0x245;
+ rUBRDIV1 = reg;
+
+#ifdef CONFIG_HWFLOW
+ rUMCON1 = 0x1; /* RTS up */
+#endif
+ for (i = 0; i < 100; i++);
+#else
+#error "Bad: you didn't configure serial ..."
+#endif
+}
+
+/*
+ * Initialise the serial port with the given baudrate. The settings
+ * are always 8 data bits, no parity, 1 stop bit, no start bits.
+ *
+ */
+int serial_init (void)
+{
+ serial_setbrg ();
+
+ return (0);
+}
+
+/*
+ * Read a single byte from the serial port. Returns 1 on success, 0
+ * otherwise. When the function is succesfull, the character read is
+ * written into its argument c.
+ */
+int serial_getc (void)
+{
+#ifdef CONFIG_SERIAL1
+ while (!(rUTRSTAT0 & 0x1));
+
+ return rURXH0 & 0xff;
+#elif CONFIG_SERIAL2
+ while (!(rUTRSTAT1 & 0x1));
+
+ return rURXH1 & 0xff;
+#endif
+}
+
+#ifdef CONFIG_HWFLOW
+static int hwflow = 0; /* turned off by default */
+int hwflow_onoff(int on)
+{
+ switch(on) {
+ case 0:
+ default:
+ break; /* return current */
+ case 1:
+ hwflow = 1; /* turn on */
+ break;
+ case -1:
+ hwflow = 0; /* turn off */
+ break;
+ }
+ return hwflow;
+}
+#endif
+
+#ifdef CONFIG_MODEM_SUPPORT
+static int be_quiet = 0;
+void disable_putc(void)
+{
+ be_quiet = 1;
+}
+
+void enable_putc(void)
+{
+ be_quiet = 0;
+}
+#endif
+
+
+/*
+ * Output a single byte to the serial port.
+ */
+void serial_putc (const char c)
+{
+#ifdef CONFIG_MODEM_SUPPORT
+ if (be_quiet)
+ return;
+#endif
+
+#ifdef CONFIG_SERIAL1
+ /* wait for room in the tx FIFO on SERIAL1 */
+ while (!(rUTRSTAT0 & 0x2));
+
+#ifdef CONFIG_HWFLOW
+ /* Wait for CTS up */
+ while(hwflow && !(rUMSTAT0 & 0x1))
+ ;
+#endif
+
+ rUTXH0 = c;
+#elif CONFIG_SERIAL2
+ /* wait for room in the tx FIFO on SERIAL2 */
+ while (!(rUTRSTAT1 & 0x2));
+
+#ifdef CONFIG_HWFLOW
+ /* Wait for CTS up */
+ while(hwflow && !(rUMSTAT1 & 0x1))
+ ;
+#endif
+ rUTXH1 = c;
+#endif
+
+ /* If \n, also do \r */
+ if (c == '\n')
+ serial_putc ('\r');
+}
+
+/*
+ * Test whether a character is in the RX buffer
+ */
+int serial_tstc (void)
+{
+#ifdef CONFIG_SERIAL1
+ return rUTRSTAT0 & 0x1;
+#elif CONFIG_SERIAL2
+ return rUTRSTAT1 & 0x1;
+#endif
+}
+
+void
+serial_puts (const char *s)
+{
+ while (*s) {
+ serial_putc (*s++);
+ }
+}
--- /dev/null
+/*
+ * (C) Copyright 2001-2002
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * (C) Copyright 2002
+ * David Mueller, ELSOFT AG, d.mueller@elsoft.ch
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/* This code should work for both the S3C2400 and the S3C2410
+ * as they seem to have the same PLL and clock machinery inside.
+ * The different address mapping is handled by the s3c24xx.h files below.
+ */
+
+#include <common.h>
+#if defined(CONFIG_S3C2400)
+#include <s3c2400.h>
+#elif defined(CONFIG_S3C2410)
+#include <s3c2410.h>
+#endif
+
+#define MPLL 0
+#define UPLL 1
+
+/* ------------------------------------------------------------------------- */
+/* NOTE: This describes the proper use of this file.
+ *
+ * CONFIG_PLL_INPUT_FREQ should be defined as the input frequency of the PLL.
+ *
+ * get_FCLK(), get_HCLK(), get_PCLK() and get_UCLK() return the clock of
+ * the specified bus in HZ.
+ */
+/* ------------------------------------------------------------------------- */
+
+static ulong get_PLLCLK(int pllreg)
+{
+ ulong r, m, p, s;
+
+ if (pllreg == MPLL)
+ r = rMPLLCON;
+ else if (pllreg == UPLL)
+ r = rUPLLCON;
+ else
+ hang();
+
+ m = ((r & 0xFF000) >> 12) + 8;
+ p = ((r & 0x003F0) >> 4) + 2;
+ s = r & 0x3;
+
+ return((CONFIG_PLL_INPUT_FREQ * m) / (p << s));
+}
+
+/* return FCLK frequency */
+ulong get_FCLK(void)
+{
+ return(get_PLLCLK(MPLL));
+}
+
+/* return HCLK frequency */
+ulong get_HCLK(void)
+{
+ ulong clkdiv = rCLKDIVN;
+
+ return((clkdiv & 0x2) ? get_FCLK()/2 : get_FCLK());
+}
+
+/* return PCLK frequency */
+ulong get_PCLK(void)
+{
+ ulong clkdiv = rCLKDIVN;
+
+ return((clkdiv & 0x1) ? get_HCLK()/2 : get_HCLK());
+}
+
+/* return UCLK frequency */
+ulong get_UCLK(void)
+{
+ return(get_PLLCLK(UPLL));
+}
--- /dev/null
+/*
+ * (C) Copyright 2000
+ * Rob Taylor. Flying Pig Systems. robt@flyingpig.com.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <asm/processor.h>
+#include <mpc824x.h>
+
+#ifndef CFG_BANK0_ROW
+#define CFG_BANK0_ROW 0
+#endif
+#ifndef CFG_BANK1_ROW
+#define CFG_BANK1_ROW 0
+#endif
+#ifndef CFG_BANK2_ROW
+#define CFG_BANK2_ROW 0
+#endif
+#ifndef CFG_BANK3_ROW
+#define CFG_BANK3_ROW 0
+#endif
+#ifndef CFG_BANK4_ROW
+#define CFG_BANK4_ROW 0
+#endif
+#ifndef CFG_BANK5_ROW
+#define CFG_BANK5_ROW 0
+#endif
+#ifndef CFG_BANK6_ROW
+#define CFG_BANK6_ROW 0
+#endif
+#ifndef CFG_BANK7_ROW
+#define CFG_BANK7_ROW 0
+#endif
+#ifndef CFG_DBUS_SIZE2
+#define CFG_DBUS_SIZE2 0
+#endif
+
+/*
+ * Breath some life into the CPU...
+ *
+ * Set up the memory map,
+ * initialize a bunch of registers,
+ */
+void
+cpu_init_f (void)
+{
+/* MOUSSE board is initialized in asm */
+#if !defined(CONFIG_MOUSSE) && !defined(CONFIG_BMW)
+ register unsigned long val;
+ CONFIG_WRITE_HALFWORD(PCICR, 0x06); /* Bus Master, respond to PCI memory space acesses*/
+/* CONFIG_WRITE_HALFWORD(PCISR, 0xffff); */ /*reset PCISR*/
+
+#if defined(CONFIG_MUSENKI) || defined(CONFIG_PN62)
+/* Why is this here, you ask? Try, just try setting 0x8000
+ * in PCIACR with CONFIG_WRITE_HALFWORD()
+ * this one was a stumper, and we are annoyed
+ */
+
+#define M_CONFIG_WRITE_HALFWORD( addr, data ) \
+ __asm__ __volatile__( \
+ " \
+ stw %2,0(%0)\n \
+ sync\n \
+ sth %3,2(%1)\n \
+ sync\n \
+ " \
+ : /* no output */ \
+ : "r" (CONFIG_ADDR), "r" (CONFIG_DATA), \
+ "r" (PCISWAP(addr & ~3)), "r" (PCISWAP(data << 16)) \
+ );
+
+ M_CONFIG_WRITE_HALFWORD(PCIACR, 0x8000);
+#endif
+
+ CONFIG_WRITE_BYTE(PCLSR, 0x8); /* set PCI cache line size */
+
+ /*
+ * Note that although this bit is cleared after a hard reset, it
+ * must be explicitly set and then cleared by software during
+ * initialization in order to guarantee correct operation of the
+ * DLL and the SDRAM_CLK[0:3] signals (if they are used).
+ */
+ CONFIG_READ_BYTE (AMBOR, val);
+ CONFIG_WRITE_BYTE(AMBOR, val & 0xDF);
+ CONFIG_WRITE_BYTE(AMBOR, val | 0x20);
+ CONFIG_WRITE_BYTE(AMBOR, val & 0xDF);
+
+ CONFIG_READ_WORD(PICR1, val);
+#if defined(CONFIG_MPC8240)
+ CONFIG_WRITE_WORD( PICR1,
+ (val & (PICR1_ADDRESS_MAP | PICR1_RCS0)) |
+ PIRC1_MSK | PICR1_PROC_TYPE_603E |
+ PICR1_FLASH_WR_EN | PICR1_MCP_EN |
+ PICR1_CF_DPARK | PICR1_EN_PCS |
+ PICR1_CF_APARK );
+#elif defined(CONFIG_MPC8245)
+ CONFIG_WRITE_WORD( PICR1,
+ (val & (PICR1_RCS0)) |
+ PICR1_PROC_TYPE_603E |
+ PICR1_FLASH_WR_EN | PICR1_MCP_EN |
+ PICR1_CF_DPARK | PICR1_NO_BUSW_CK |
+ PICR1_DEC| PICR1_CF_APARK | 0x10); /* 8245 UM says bit 4 must be set */
+#else
+#error Specific type of MPC824x must be defined (i.e. CONFIG_MPC8240)
+#endif
+
+ CONFIG_READ_WORD(PICR2, val);
+ val= val & ~ (PICR2_CF_SNOOP_WS_MASK | PICR2_CF_APHASE_WS_MASK); /*mask off waitstate bits*/
+#ifndef CONFIG_PN62
+ val |= PICR2_CF_SNOOP_WS_1WS | PICR2_CF_APHASE_WS_1WS; /*1 wait state*/
+#endif
+ CONFIG_WRITE_WORD(PICR2, val);
+
+ CONFIG_WRITE_WORD(EUMBBAR, CFG_EUMB_ADDR);
+#ifndef CFG_RAMBOOT
+ CONFIG_WRITE_WORD(MCCR1, (CFG_ROMNAL << MCCR1_ROMNAL_SHIFT) |
+ (CFG_BANK0_ROW) |
+ (CFG_BANK1_ROW << MCCR1_BANK1ROW_SHIFT) |
+ (CFG_BANK2_ROW << MCCR1_BANK2ROW_SHIFT) |
+ (CFG_BANK3_ROW << MCCR1_BANK3ROW_SHIFT) |
+ (CFG_BANK4_ROW << MCCR1_BANK4ROW_SHIFT) |
+ (CFG_BANK5_ROW << MCCR1_BANK5ROW_SHIFT) |
+ (CFG_BANK6_ROW << MCCR1_BANK6ROW_SHIFT) |
+ (CFG_BANK7_ROW << MCCR1_BANK7ROW_SHIFT) |
+ (CFG_ROMFAL << MCCR1_ROMFAL_SHIFT));
+#endif
+
+#if defined(CFG_ASRISE) && defined(CFG_ASFALL)
+ CONFIG_WRITE_WORD(MCCR2, CFG_REFINT << MCCR2_REFINT_SHIFT |
+ CFG_ASRISE << MCCR2_ASRISE_SHIFT |
+ CFG_ASFALL << MCCR2_ASFALL_SHIFT);
+#else
+ CONFIG_WRITE_WORD(MCCR2, CFG_REFINT << MCCR2_REFINT_SHIFT);
+#endif
+
+#if defined(CONFIG_MPC8240)
+ CONFIG_WRITE_WORD(MCCR3,
+ (((CFG_BSTOPRE & 0x003c) >> 2) << MCCR3_BSTOPRE2TO5_SHIFT) |
+ (CFG_REFREC << MCCR3_REFREC_SHIFT) |
+ (CFG_RDLAT << MCCR3_RDLAT_SHIFT));
+#elif defined(CONFIG_MPC8245)
+ CONFIG_WRITE_WORD(MCCR3,
+ (((CFG_BSTOPRE & 0x003c) >> 2) << MCCR3_BSTOPRE2TO5_SHIFT) |
+ (CFG_REFREC << MCCR3_REFREC_SHIFT));
+#else
+#error Specific type of MPC824x must be defined (i.e. CONFIG_MPC8240)
+#endif
+
+/* this is gross. We think these should all be the same, and various boards
+ * should define CFG_ACTORW to 0 if they don't want to set it, or even, if
+ * its not set, we define it to zero in this file
+ */
+#if defined(CONFIG_CU824) || defined(CONFIG_PN62)
+ CONFIG_WRITE_WORD(MCCR4,
+ (CFG_PRETOACT << MCCR4_PRETOACT_SHIFT) |
+ (CFG_ACTTOPRE << MCCR4_ACTTOPRE_SHIFT) |
+ MCCR4_BIT21 |
+ (CFG_REGISTERD_TYPE_BUFFER ? MCCR4_REGISTERED: 0) |
+ ((CFG_BSTOPRE & 0x0003) <<MCCR4_BSTOPRE0TO1_SHIFT ) |
+ (((CFG_SDMODE_CAS_LAT <<4) | (CFG_SDMODE_WRAP <<3) |
+ CFG_SDMODE_BURSTLEN) << MCCR4_SDMODE_SHIFT) |
+ (CFG_ACTORW << MCCR4_ACTTORW_SHIFT) |
+ (((CFG_BSTOPRE & 0x03c0) >> 6) << MCCR4_BSTOPRE6TO9_SHIFT));
+#elif defined(CONFIG_MPC8240)
+ CONFIG_WRITE_WORD(MCCR4,
+ (CFG_PRETOACT << MCCR4_PRETOACT_SHIFT) |
+ (CFG_ACTTOPRE << MCCR4_ACTTOPRE_SHIFT) |
+ MCCR4_BIT21 |
+ (CFG_REGISTERD_TYPE_BUFFER ? MCCR4_REGISTERED: 0) |
+ ((CFG_BSTOPRE & 0x0003) <<MCCR4_BSTOPRE0TO1_SHIFT ) |
+ (((CFG_SDMODE_CAS_LAT <<4) | (CFG_SDMODE_WRAP <<3) |
+ (CFG_SDMODE_BURSTLEN)) <<MCCR4_SDMODE_SHIFT) |
+ (((CFG_BSTOPRE & 0x03c0) >> 6) <<MCCR4_BSTOPRE6TO9_SHIFT ));
+#elif defined(CONFIG_MPC8245)
+ CONFIG_READ_WORD(MCCR1, val);
+ val &= MCCR1_DBUS_SIZE0; /* test for 64-bit mem bus */
+
+ CONFIG_WRITE_WORD(MCCR4,
+ (CFG_PRETOACT << MCCR4_PRETOACT_SHIFT) |
+ (CFG_ACTTOPRE << MCCR4_ACTTOPRE_SHIFT) |
+ (CFG_EXTROM ? MCCR4_EXTROM : 0) |
+ (CFG_REGDIMM ? MCCR4_REGDIMM : 0) |
+ (CFG_REGISTERD_TYPE_BUFFER ? MCCR4_REGISTERED: 0) |
+ ((CFG_BSTOPRE & 0x0003) <<MCCR4_BSTOPRE0TO1_SHIFT ) |
+ (CFG_DBUS_SIZE2 << MCCR4_DBUS_SIZE2_SHIFT) |
+ (((CFG_SDMODE_CAS_LAT <<4) | (CFG_SDMODE_WRAP <<3) |
+ (val ? 2 : 3)) << MCCR4_SDMODE_SHIFT) |
+ (CFG_ACTORW << MCCR4_ACTTORW_SHIFT) |
+ (((CFG_BSTOPRE & 0x03c0) >> 6) <<MCCR4_BSTOPRE6TO9_SHIFT ));
+#else
+#error Specific type of MPC824x must be defined (i.e. CONFIG_MPC8240)
+#endif
+
+ CONFIG_WRITE_WORD(MSAR1,
+ ( (CFG_BANK0_START & MICR_ADDR_MASK) >> MICR_ADDR_SHIFT) |
+ (((CFG_BANK1_START & MICR_ADDR_MASK) >> MICR_ADDR_SHIFT) << 8) |
+ (((CFG_BANK2_START & MICR_ADDR_MASK) >> MICR_ADDR_SHIFT) << 16) |
+ (((CFG_BANK3_START & MICR_ADDR_MASK) >> MICR_ADDR_SHIFT) << 24));
+ CONFIG_WRITE_WORD(EMSAR1,
+ ( (CFG_BANK0_START & MICR_EADDR_MASK) >> MICR_EADDR_SHIFT) |
+ (((CFG_BANK1_START & MICR_EADDR_MASK) >> MICR_EADDR_SHIFT) << 8) |
+ (((CFG_BANK2_START & MICR_EADDR_MASK) >> MICR_EADDR_SHIFT) << 16) |
+ (((CFG_BANK3_START & MICR_EADDR_MASK) >> MICR_EADDR_SHIFT) << 24));
+ CONFIG_WRITE_WORD(MSAR2,
+ ( (CFG_BANK4_START & MICR_ADDR_MASK) >> MICR_ADDR_SHIFT) |
+ (((CFG_BANK5_START & MICR_ADDR_MASK) >> MICR_ADDR_SHIFT) << 8) |
+ (((CFG_BANK6_START & MICR_ADDR_MASK) >> MICR_ADDR_SHIFT) << 16) |
+ (((CFG_BANK7_START & MICR_ADDR_MASK) >> MICR_ADDR_SHIFT) << 24));
+ CONFIG_WRITE_WORD(EMSAR2,
+ ( (CFG_BANK4_START & MICR_EADDR_MASK) >> MICR_EADDR_SHIFT) |
+ (((CFG_BANK5_START & MICR_EADDR_MASK) >> MICR_EADDR_SHIFT) << 8) |
+ (((CFG_BANK6_START & MICR_EADDR_MASK) >> MICR_EADDR_SHIFT) << 16) |
+ (((CFG_BANK7_START & MICR_EADDR_MASK) >> MICR_EADDR_SHIFT) << 24));
+ CONFIG_WRITE_WORD(MEAR1,
+ ( (CFG_BANK0_END & MICR_ADDR_MASK) >> MICR_ADDR_SHIFT) |
+ (((CFG_BANK1_END & MICR_ADDR_MASK) >> MICR_ADDR_SHIFT) << 8) |
+ (((CFG_BANK2_END & MICR_ADDR_MASK) >> MICR_ADDR_SHIFT) << 16) |
+ (((CFG_BANK3_END & MICR_ADDR_MASK) >> MICR_ADDR_SHIFT) << 24));
+ CONFIG_WRITE_WORD(EMEAR1,
+ ( (CFG_BANK0_END & MICR_EADDR_MASK) >> MICR_EADDR_SHIFT) |
+ (((CFG_BANK1_END & MICR_EADDR_MASK) >> MICR_EADDR_SHIFT) << 8) |
+ (((CFG_BANK2_END & MICR_EADDR_MASK) >> MICR_EADDR_SHIFT) << 16) |
+ (((CFG_BANK3_END & MICR_EADDR_MASK) >> MICR_EADDR_SHIFT) << 24));
+ CONFIG_WRITE_WORD(MEAR2,
+ ( (CFG_BANK4_END & MICR_ADDR_MASK) >> MICR_ADDR_SHIFT) |
+ (((CFG_BANK5_END & MICR_ADDR_MASK) >> MICR_ADDR_SHIFT) << 8) |
+ (((CFG_BANK6_END & MICR_ADDR_MASK) >> MICR_ADDR_SHIFT) << 16) |
+ (((CFG_BANK7_END & MICR_ADDR_MASK) >> MICR_ADDR_SHIFT) << 24));
+ CONFIG_WRITE_WORD(EMEAR2,
+ ( (CFG_BANK4_END & MICR_EADDR_MASK) >> MICR_EADDR_SHIFT) |
+ (((CFG_BANK5_END & MICR_EADDR_MASK) >> MICR_EADDR_SHIFT) << 8) |
+ (((CFG_BANK6_END & MICR_EADDR_MASK) >> MICR_EADDR_SHIFT) << 16) |
+ (((CFG_BANK7_END & MICR_EADDR_MASK) >> MICR_EADDR_SHIFT) << 24));
+
+ CONFIG_WRITE_BYTE(ODCR, CFG_ODCR);
+#ifdef CFG_DLL_MAX_DELAY
+ CONFIG_WRITE_BYTE(MIOCR1, CFG_DLL_MAX_DELAY); /* needed to make DLL lock */
+#endif
+#if defined(CFG_DLL_EXTEND) && defined(CFG_PCI_HOLD_DEL)
+ CONFIG_WRITE_BYTE(PMCR2, CFG_DLL_EXTEND | CFG_PCI_HOLD_DEL);
+#endif
+#if defined(MIOCR2) && defined(CFG_SDRAM_DSCD)
+ CONFIG_WRITE_BYTE(MIOCR2, CFG_SDRAM_DSCD); /* change memory input */
+#endif /* setup & hold time */
+
+ CONFIG_WRITE_BYTE(MBER,
+ CFG_BANK0_ENABLE |
+ (CFG_BANK1_ENABLE << 1) |
+ (CFG_BANK2_ENABLE << 2) |
+ (CFG_BANK3_ENABLE << 3) |
+ (CFG_BANK4_ENABLE << 4) |
+ (CFG_BANK5_ENABLE << 5) |
+ (CFG_BANK6_ENABLE << 6) |
+ (CFG_BANK7_ENABLE << 7));
+
+#ifdef CFG_PGMAX
+ CONFIG_WRITE_BYTE(MPMR, CFG_PGMAX);
+#endif
+
+ /* ! Wait 200us before initialize other registers */
+ /*FIXME: write a decent udelay wait */
+ __asm__ __volatile__(
+ " mtctr %0 \n \
+ 0: bdnz 0b\n"
+ :
+ : "r" (0x10000));
+
+ CONFIG_READ_WORD(MCCR1, val);
+ CONFIG_WRITE_WORD(MCCR1, val | MCCR1_MEMGO); /* set memory access going */
+ __asm__ __volatile__("eieio");
+
+#endif /* !CONFIG_MOUSSE && !CONFIG_BMW */
+}
+
+
+#ifdef CONFIG_MOUSSE
+#ifdef INCLUDE_MPC107_REPORT
+struct MPC107_s{
+ unsigned int iobase;
+ char desc[120];
+} MPC107Regs[] ={
+ {BMC_BASE+0x0, "MPC107 Vendor/Device ID"},
+ {BMC_BASE+0x4, "MPC107 PCI Command/Status Register"},
+ {BMC_BASE+0x8, "MPC107 Revision"},
+ {BMC_BASE+0xC, "MPC107 Cache Line Size"},
+ {BMC_BASE+0x10, "MPC107 LMBAR"},
+ {BMC_BASE+0x14, "MPC824x PCSR"},
+ {BMC_BASE+0xA8, "MPC824x PICR1"},
+ {BMC_BASE+0xAC, "MPC824x PICR2"},
+ {BMC_BASE+0x46, "MPC824x PACR"},
+ {BMC_BASE+0x310, "MPC824x ITWR"},
+ {BMC_BASE+0x300, "MPC824x OMBAR"},
+ {BMC_BASE+0x308, "MPC824x OTWR"},
+ {BMC_BASE+0x14, "MPC107 Peripheral Control and Status Register"},
+ {BMC_BASE+0x78, "MPC107 EUMBAR"},
+ {BMC_BASE+0xC0, "MPC107 Processor Bus Error Status"},
+ {BMC_BASE+0xC4, "MPC107 PCI Bus Error Status"},
+ {BMC_BASE+0xC8, "MPC107 Processor/PCI Error Address"},
+ {BMC_BASE+0xE0, "MPC107 AMBOR Register"},
+ {BMC_BASE+0xF0, "MPC107 MCCR1 Register"},
+ {BMC_BASE+0xF4, "MPC107 MCCR2 Register"},
+ {BMC_BASE+0xF8, "MPC107 MCCR3 Register"},
+ {BMC_BASE+0xFC, "MPC107 MCCR4 Register"}
+};
+#define N_MPC107_Regs (sizeof(MPC107Regs)/sizeof(MPC107Regs[0]))
+#endif /* INCLUDE_MPC107_REPORT */
+#endif /* CONFIG_MOUSSE */
+
+/*
+ * initialize higher level parts of CPU like time base and timers
+ */
+int cpu_init_r (void)
+{
+#ifdef CONFIG_MOUSSE
+#ifdef INCLUDE_MPC107_REPORT
+ unsigned int tmp = 0, i;
+#endif
+ /*
+ * Initialize the EUMBBAR (Embedded Util Mem Block Base Addr Reg).
+ * This is necessary before the EPIC, DMA ctlr, I2C ctlr, etc. can
+ * be accessed.
+ */
+
+#ifdef CONFIG_MPC8240 /* only on MPC8240 */
+ mpc824x_mpc107_setreg (EUMBBAR, EUMBBAR_VAL);
+ /* MOT/SPS: Issue #10002, PCI (FD Alias enable) */
+ mpc824x_mpc107_setreg (AMBOR, 0x000000C0);
+#endif
+
+
+#ifdef INCLUDE_MPC107_REPORT
+ /* Check MPC824x PCI Device and Vendor ID */
+ while ((tmp = mpc824x_mpc107_getreg (BMC_BASE)) != 0x31057) {
+ printf (" MPC107: offset=0x%x, val = 0x%x\n",
+ BMC_BASE,
+ tmp);
+ }
+
+ for (i = 0; i < N_MPC107_Regs; i++) {
+ printf (" 0x%x/%s = 0x%x\n",
+ MPC107Regs[i].iobase,
+ MPC107Regs[i].desc,
+ mpc824x_mpc107_getreg (MPC107Regs[i].iobase));
+ }
+
+ printf ("IBAT0L = 0x%08X\n", mfspr (IBAT0L));
+ printf ("IBAT0U = 0x%08X\n", mfspr (IBAT0U));
+ printf ("IBAT1L = 0x%08X\n", mfspr (IBAT1L));
+ printf ("IBAT1U = 0x%08X\n", mfspr (IBAT1U));
+ printf ("IBAT2L = 0x%08X\n", mfspr (IBAT2L));
+ printf ("IBAT2U = 0x%08X\n", mfspr (IBAT2U));
+ printf ("IBAT3L = 0x%08X\n", mfspr (IBAT3L));
+ printf ("IBAT3U = 0x%08X\n", mfspr (IBAT3U));
+ printf ("DBAT0L = 0x%08X\n", mfspr (DBAT0L));
+ printf ("DBAT0U = 0x%08X\n", mfspr (DBAT0U));
+ printf ("DBAT1L = 0x%08X\n", mfspr (DBAT1L));
+ printf ("DBAT1U = 0x%08X\n", mfspr (DBAT1U));
+ printf ("DBAT2L = 0x%08X\n", mfspr (DBAT2L));
+ printf ("DBAT2U = 0x%08X\n", mfspr (DBAT2U));
+ printf ("DBAT3L = 0x%08X\n", mfspr (DBAT3L));
+ printf ("DBAT3U = 0x%08X\n", mfspr (DBAT3U));
+#endif /* INCLUDE_MPC107_REPORT */
+#endif /* CONFIG_MOUSSE */
+ return (0);
+}
--- /dev/null
+/*************************************************************
+ *
+ * Copyright @ Motorola, 1999
+ *
+ ************************************************************/
+#include <common.h>
+
+#ifdef CONFIG_HARD_I2C
+#include <i2c.h>
+#include "i2c_export.h"
+#include "i2c.h"
+
+#undef I2CDBG0
+#undef DEBUG
+
+/* Define a macro to use an optional application-layer print function, if
+ * one was passed to the I2C library during initialization. If there was
+ * no function pointer passed, this protects against calling it. Also define
+ * the global variable that holds the passed pointer.
+ */
+#define TIMEOUT (CFG_HZ/4)
+#define PRINT if ( app_print ) app_print
+static int (*app_print) (char *, ...);
+
+/******************* Internal to I2C Driver *****************/
+static unsigned int ByteToXmit = 0;
+static unsigned int XmitByte = 0;
+static unsigned char *XmitBuf = 0;
+static unsigned int XmitBufEmptyStop = 0;
+static unsigned int ByteToRcv = 0;
+static unsigned int RcvByte = 0;
+static unsigned char *RcvBuf = 0;
+static unsigned int RcvBufFulStop = 0;
+static unsigned int MasterRcvAddress = 0;
+
+/* Set by call to get_eumbbar during I2C_Initialize.
+ * This could be globally available to the I2C library, but there is
+ * an advantage to passing it as a parameter: it is already in a register
+ * and doesn't have to be loaded from memory. Also, that is the way the
+ * I2C library was already implemented and I don't want to change it without
+ * a more detailed analysis.
+ * It is being set as a global variable in I2C_Initialize to hide it from
+ * the DINK application layer, because it is Kahlua-specific. I think that
+ * get_eumbbar, load_runtime_reg, and store_runtime_reg should be defined in
+ * a Kahlua-specific library dealing with the embedded utilities memory block.
+ * Right now, get_eumbbar is defined in dink32/kahlua.s. The other two are
+ * defined in dink32/drivers/i2c/i2c2.s.
+ */
+static unsigned int Global_eumbbar = 0;
+
+extern unsigned int load_runtime_reg (unsigned int eumbbar,
+ unsigned int reg);
+
+extern unsigned int store_runtime_reg (unsigned int eumbbar,
+ unsigned int reg, unsigned int val);
+
+/************************** API *****************/
+
+/* Application Program Interface (API) are the calls provided by the I2C
+ * library to upper layer applications (i.e., DINK) to access the Kahlua
+ * I2C bus interface. The functions and values that are part of this API
+ * are declared in i2c_export.h.
+ */
+
+/* Initialize I2C unit with the following:
+ * driver's slave address
+ * interrupt enabled
+ * optional pointer to application layer print function
+ *
+ * These parameters may be added:
+ * desired clock rate
+ * digital filter frequency sampling rate
+ *
+ * This function must be called before I2C unit can be used.
+ */
+I2C_Status I2C_Initialize (unsigned char addr,
+ I2C_INTERRUPT_MODE en_int,
+ int (*p) (char *, ...))
+{
+ I2CStatus status;
+
+ /* establish the pointer, if there is one, to the application's "printf" */
+ app_print = p;
+
+ /* If this is the first call, get the embedded utilities memory block
+ * base address. I'm not sure what to do about error handling here:
+ * if a non-zero value is returned, accept it.
+ */
+ if (Global_eumbbar == 0)
+ Global_eumbbar = get_eumbbar ();
+ if (Global_eumbbar == 0) {
+ PRINT ("I2C_Initialize: can't find EUMBBAR\n");
+ return I2C_ERROR;
+ }
+
+ /* validate the I2C address */
+ if (addr & 0x80) {
+ PRINT ("I2C_Initialize, I2C address invalid: %d 0x%x\n",
+ (unsigned int) addr, (unsigned int) addr);
+ return I2C_ERROR;
+ }
+
+ /* Call the internal I2C library function to perform work.
+ * Accept the default frequency sampling rate (no way to set it currently,
+ * via I2C_Init) and set the clock frequency to something reasonable.
+ */
+ status = I2C_Init (Global_eumbbar, (unsigned char) 0x31, addr, en_int);
+ if (status != I2CSUCCESS) {
+ PRINT ("I2C_Initialize: error in initiation\n");
+ return I2C_ERROR;
+ }
+
+ /* all is well */
+ return I2C_SUCCESS;
+}
+
+
+/* Perform the given I2C transaction, only MASTER_XMIT and MASTER_RCV
+ * are implemented. Both are only in polling mode.
+ *
+ * en_int controls interrupt/polling mode
+ * act is the type of transaction
+ * i2c_addr is the I2C address of the slave device
+ * data_addr is the address of the data on the slave device
+ * len is the length of data to send or receive
+ * buffer is the address of the data buffer
+ * stop = I2C_NO_STOP, don't signal STOP at end of transaction
+ * I2C_STOP, signal STOP at end of transaction
+ * retry is the timeout retry value, currently ignored
+ * rsta = I2C_NO_RESTART, this is not continuation of existing transaction
+ * I2C_RESTART, this is a continuation of existing transaction
+ */
+I2C_Status I2C_do_transaction ( I2C_INTERRUPT_MODE en_int,
+ I2C_TRANSACTION_MODE act,
+ unsigned char i2c_addr,
+ unsigned char data_addr,
+ int len,
+ char *buffer,
+ I2C_STOP_MODE stop,
+ int retry, I2C_RESTART_MODE rsta)
+{
+ I2C_Status status;
+ unsigned char data_addr_buffer[1];
+
+#if 1
+/* This is a temporary work-around. The I2C library breaks the protocol
+ * if it attempts to handle a data transmission in more than one
+ * transaction, so the data address and the actual data bytes are put
+ * into a single buffer before sending it to the library internal functions.
+ * The problem is related to being able to restart a transaction without
+ * sending the I2C device address or repeating the data address. It may take
+ * a day or two to sort it all out, so I'll have to get back to it later.
+ * Look at I2C_Start to see about using some status flags (I'm not sure that
+ * "stop" and "rsta" are enough to reflect the states, maybe so; but the logic
+ * in the library is insufficient) to control correct handling of the protocol.
+ */
+ unsigned char dummy_buffer[257];
+
+ if (act == I2C_MASTER_XMIT) {
+ int i;
+
+ if (len > 256)
+ return I2C_ERROR;
+ for (i = 1; i <= len; i++)
+ dummy_buffer[i] = buffer[i - 1];
+ dummy_buffer[0] = data_addr;
+ status = I2C_do_buffer (en_int, act, i2c_addr, 1 + len,
+ dummy_buffer, stop, retry, rsta);
+ if (status != I2C_SUCCESS) {
+ PRINT ("I2C_do_transaction: can't perform data transfer\n");
+ return I2C_ERROR;
+ }
+ return I2C_SUCCESS;
+ }
+#endif /* end of temp work-around */
+
+ /* validate requested transaction type */
+ if ((act != I2C_MASTER_XMIT) && (act != I2C_MASTER_RCV)) {
+ PRINT ("I2C_do_transaction, invalid transaction request: %d\n",
+ act);
+ return I2C_ERROR;
+ }
+
+ /* range check the I2C address */
+ if (i2c_addr & 0x80) {
+ PRINT ("I2C_do_transaction, I2C address out of range: %d 0x%x\n",
+ (unsigned int) i2c_addr, (unsigned int) i2c_addr);
+ return I2C_ERROR;
+ } else {
+ data_addr_buffer[0] = data_addr;
+ }
+
+ /*
+ * We first have to contact the slave device and transmit the
+ * data address. Be careful about the STOP and restart stuff.
+ * We don't want to signal STOP after sending the data
+ * address, but this could be a continuation if the
+ * application didn't release the bus after the previous
+ * transaction, by not sending a STOP after it.
+ */
+ status = I2C_do_buffer (en_int, I2C_MASTER_XMIT, i2c_addr, 1,
+ data_addr_buffer, I2C_NO_STOP, retry, rsta);
+ if (status != I2C_SUCCESS) {
+ PRINT ("I2C_do_transaction: can't send data address for read\n");
+ return I2C_ERROR;
+ }
+
+ /* The data transfer will be a continuation. */
+ rsta = I2C_RESTART;
+
+ /* now handle the user data */
+ status = I2C_do_buffer (en_int, act, i2c_addr, len,
+ buffer, stop, retry, rsta);
+ if (status != I2C_SUCCESS) {
+ PRINT ("I2C_do_transaction: can't perform data transfer\n");
+ return I2C_ERROR;
+ }
+
+ /* all is well */
+ return I2C_SUCCESS;
+}
+
+/* This function performs the work for I2C_do_transaction. The work is
+ * split into this function to enable I2C_do_transaction to first transmit
+ * the data address to the I2C slave device without putting the data address
+ * into the first byte of the buffer.
+ *
+ * en_int controls interrupt/polling mode
+ * act is the type of transaction
+ * i2c_addr is the I2C address of the slave device
+ * len is the length of data to send or receive
+ * buffer is the address of the data buffer
+ * stop = I2C_NO_STOP, don't signal STOP at end of transaction
+ * I2C_STOP, signal STOP at end of transaction
+ * retry is the timeout retry value, currently ignored
+ * rsta = I2C_NO_RESTART, this is not continuation of existing transaction
+ * I2C_RESTART, this is a continuation of existing transaction
+ */
+static I2C_Status I2C_do_buffer (I2C_INTERRUPT_MODE en_int,
+ I2C_TRANSACTION_MODE act,
+ unsigned char i2c_addr,
+ int len,
+ unsigned char *buffer,
+ I2C_STOP_MODE stop,
+ int retry, I2C_RESTART_MODE rsta)
+{
+ I2CStatus rval;
+ unsigned int dev_stat;
+
+ if (act == I2C_MASTER_RCV) {
+ /* set up for master-receive transaction */
+ rval = I2C_get (Global_eumbbar, i2c_addr, buffer, len, stop, rsta);
+ } else {
+ /* set up for master-transmit transaction */
+ rval = I2C_put (Global_eumbbar, i2c_addr, buffer, len, stop, rsta);
+ }
+
+ /* validate the setup */
+ if (rval != I2CSUCCESS) {
+ dev_stat = load_runtime_reg (Global_eumbbar, I2CSR);
+ PRINT ("Error(I2C_do_buffer): control phase, code(0x%08x), status(0x%08x)\n", rval, dev_stat);
+ I2C_Stop (Global_eumbbar);
+ return I2C_ERROR;
+ }
+
+ if (en_int == 1) {
+ /* this should not happen, no interrupt handling yet */
+ return I2C_SUCCESS;
+ }
+
+ /* this performs the polling action, when the transfer is completed,
+ * the status returned from I2C_Timer_Event will be I2CBUFFFULL or
+ * I2CBUFFEMPTY (rcv or xmit), I2CSUCCESS or I2CADDRESS indicates the
+ * transaction is not yet complete, anything else is an error.
+ */
+ while (rval == I2CSUCCESS || rval == I2CADDRESS) {
+ int timeval = get_timer (0);
+
+ /* poll the device until something happens */
+ do {
+ rval = I2C_Timer_Event (Global_eumbbar, 0);
+ }
+ while (rval == I2CNOEVENT && get_timer (timeval) < TIMEOUT);
+
+ /* check for error condition */
+ if (rval == I2CSUCCESS ||
+ rval == I2CBUFFFULL ||
+ rval == I2CBUFFEMPTY ||
+ rval == I2CADDRESS) {
+ ; /* do nothing */
+ } else {
+ /* report the error condition */
+ dev_stat = load_runtime_reg (Global_eumbbar, I2CSR);
+ PRINT ("Error(I2C_do_buffer): code(0x%08x), status(0x%08x)\n",
+ rval, dev_stat);
+ return I2C_ERROR;
+ }
+ }
+
+ /* all is well */
+ return I2C_SUCCESS;
+}
+
+/**
+ * Note:
+ *
+ * In all following functions,
+ * the caller shall pass the configured embedded utility memory
+ * block base, EUMBBAR.
+ **/
+
+/***********************************************************
+ * function: I2C_put
+ *
+ * description:
+ Send a buffer of data to the intended rcv_addr.
+ * If stop_flag is set, after the whole buffer
+ * is sent, generate a STOP signal provided that the
+ * receiver doesn't signal the STOP in the middle.
+ * I2C is the master performing transmitting. If
+ * no STOP signal is generated at the end of current
+ * transaction, the master can generate a START signal
+ * to another slave addr.
+ *
+ * note: this is master xmit API
+ *********************************************************/
+static I2CStatus I2C_put (unsigned int eumbbar, unsigned char rcv_addr, /* receiver's address */
+ unsigned char *buffer_ptr, /* pointer of data to be sent */
+ unsigned int length, /* number of byte of in the buffer */
+ unsigned int stop_flag, /* 1 - signal STOP when buffer is empty
+ * 0 - no STOP signal when buffer is empty
+ */
+ unsigned int is_cnt)
+{ /* 1 - this is a restart, don't check MBB
+ * 0 - this is a new start, check MBB
+ */
+ if (buffer_ptr == 0 || length == 0) {
+ return I2CERROR;
+ }
+#ifdef I2CDBG0
+ PRINT ("%s(%d): I2C_put\n", __FILE__, __LINE__);
+#endif
+
+ XmitByte = 0;
+ ByteToXmit = length;
+ XmitBuf = buffer_ptr;
+ XmitBufEmptyStop = stop_flag;
+
+ RcvByte = 0;
+ ByteToRcv = 0;
+ RcvBuf = 0;
+
+ /* we are the master, start transaction */
+ return I2C_Start (eumbbar, rcv_addr, XMIT, is_cnt);
+}
+
+/***********************************************************
+ * function: I2C_get
+ *
+ * description:
+ * Receive a buffer of data from the desired sender_addr
+ * If stop_flag is set, when the buffer is full and the
+ * sender does not signal STOP, generate a STOP signal.
+ * I2C is the master performing receiving. If no STOP signal
+ * is generated, the master can generate a START signal
+ * to another slave addr.
+ *
+ * note: this is master receive API
+ **********************************************************/
+static I2CStatus I2C_get (unsigned int eumbbar, unsigned char rcv_from, /* sender's address */
+ unsigned char *buffer_ptr, /* pointer of receiving buffer */
+ unsigned int length, /* length of the receiving buffer */
+ unsigned int stop_flag, /* 1 - signal STOP when buffer is full
+ * 0 - no STOP signal when buffer is full
+ */
+ unsigned int is_cnt)
+{ /* 1 - this is a restart, don't check MBB
+ * 0 - this is a new start, check MBB
+ */
+ if (buffer_ptr == 0 || length == 0) {
+ return I2CERROR;
+ }
+#ifdef I2CDBG0
+ PRINT ("%s(%d): I2C_get\n", __FILE__, __LINE__);
+#endif
+
+ RcvByte = 0;
+ ByteToRcv = length;
+ RcvBuf = buffer_ptr;
+ RcvBufFulStop = stop_flag;
+
+ XmitByte = 0;
+ ByteToXmit = 0;
+ XmitBuf = 0;
+
+ /* we are the master, start the transaction */
+ return I2C_Start (eumbbar, rcv_from, RCV, is_cnt);
+
+}
+
+#if 0 /* turn off dead code */
+/*********************************************************
+ * function: I2C_write
+ *
+ * description:
+ * Send a buffer of data to the requiring master.
+ * If stop_flag is set, after the whole buffer is sent,
+ * generate a STOP signal provided that the requiring
+ * receiver doesn't signal the STOP in the middle.
+ * I2C is the slave performing transmitting.
+ *
+ * Note: this is slave xmit API.
+ *
+ * due to the current Kahlua design, slave transmitter
+ * shall not signal STOP since there is no way
+ * for master to detect it, causing I2C bus hung.
+ *
+ * For the above reason, the stop_flag is always
+ * set, i.e., 0.
+ *
+ * programmer shall use the timer on Kahlua to
+ * control the interval of data byte at the
+ * master side.
+ *******************************************************/
+static I2CStatus I2C_write (unsigned int eumbbar, unsigned char *buffer_ptr, /* pointer of data to be sent */
+ unsigned int length, /* number of byte of in the buffer */
+ unsigned int stop_flag)
+{ /* 1 - signal STOP when buffer is empty
+ * 0 - no STOP signal when buffer is empty
+ */
+ if (buffer_ptr == 0 || length == 0) {
+ return I2CERROR;
+ }
+
+ XmitByte = 0;
+ ByteToXmit = length;
+ XmitBuf = buffer_ptr;
+ XmitBufEmptyStop = 0; /* in order to avoid bus hung, ignored the user's stop_flag */
+
+ RcvByte = 0;
+ ByteToRcv = 0;
+ RcvBuf = 0;
+
+ /* we are the slave, just wait for being called, or pull */
+ /* I2C_Timer_Event( eumbbar ); */
+}
+
+/******************************************************
+ * function: I2C_read
+ *
+ * description:
+ * Receive a buffer of data from the sending master.
+ * If stop_flag is set, when the buffer is full and the
+ * sender does not signal STOP, generate a STOP signal.
+ * I2C is the slave performing receiving.
+ *
+ * note: this is slave receive API
+ ****************************************************/
+static I2CStatus I2C_read (unsigned int eumbbar, unsigned char *buffer_ptr, /* pointer of receiving buffer */
+ unsigned int length, /* length of the receiving buffer */
+ unsigned int stop_flag)
+{ /* 1 - signal STOP when buffer is full
+ * 0 - no STOP signal when buffer is full
+ */
+ if (buffer_ptr == 0 || length == 0) {
+ return I2CERROR;
+ }
+
+ RcvByte = 0;
+ ByteToRcv = length;
+ RcvBuf = buffer_ptr;
+ RcvBufFulStop = stop_flag;
+
+ XmitByte = 0;
+ ByteToXmit = 0;
+ XmitBuf = 0;
+
+ /* wait for master to call us, or poll */
+ /* I2C_Timer_Event( eumbbar ); */
+}
+#endif /* turn off dead code */
+
+/*********************************************************
+ * function: I2c_Timer_Event
+ *
+ * description:
+ * if interrupt is not used, this is the timer event handler.
+ * After each fixed time interval, this function can be called
+ * to check the I2C status and call appropriate function to
+ * handle the status event.
+ ********************************************************/
+static I2CStatus I2C_Timer_Event (unsigned int eumbbar,
+ I2CStatus (*handler) (unsigned int))
+{
+ I2C_STAT stat;
+
+#ifdef I2CDBG0
+ PRINT ("%s(%d): I2C_Timer_Event\n", __FILE__, __LINE__);
+#endif
+
+ stat = I2C_Get_Stat (eumbbar);
+
+ if (stat.mif == 1) {
+ if (handler == 0) {
+ return I2C_ISR (eumbbar);
+ } else {
+ return (*handler) (eumbbar);
+ }
+ }
+
+ return I2CNOEVENT;
+}
+
+
+/****************** Device I/O function *****************/
+
+/******************************************************
+ * function: I2C_Start
+ *
+ * description: Generate a START signal in the desired mode.
+ * I2C is the master.
+ *
+ * Return I2CSUCCESS if no error.
+ *
+ * note:
+ ****************************************************/
+static I2CStatus I2C_Start (unsigned int eumbbar, unsigned char slave_addr, /* address of the receiver */
+ I2C_MODE mode, /* XMIT(1) - put (write)
+ * RCV(0) - get (read)
+ */
+ unsigned int is_cnt)
+{ /* 1 - this is a restart, don't check MBB
+ * 0 - this is a new start
+ */
+ unsigned int tmp = 0;
+ I2C_STAT stat;
+ I2C_CTRL ctrl;
+
+#ifdef I2CDBG0
+ PRINT ("%s(%d): I2C_Start addr 0x%x mode %d cnt %d\n", __FILE__,
+ __LINE__, slave_addr, mode, is_cnt);
+#endif
+
+ ctrl = I2C_Get_Ctrl (eumbbar);
+
+ /* first make sure I2C has been initialized */
+ if (ctrl.men == 0) {
+ return I2CERROR;
+ }
+
+ /* next make sure bus is idle */
+ stat = I2C_Get_Stat (eumbbar);
+
+ if (is_cnt == 0 && stat.mbb == 1) {
+ /* sorry, we lost */
+ return I2CBUSBUSY;
+ } else if (is_cnt == 1 && stat.mif == 1 && stat.mal == 0) {
+ /* sorry, we lost the bus */
+ return I2CALOSS;
+ }
+
+
+ /* OK, I2C is enabled and we have the bus */
+
+ /* prepare to write the slave address */
+ ctrl.msta = 1;
+ ctrl.mtx = 1;
+ ctrl.txak = 0;
+ ctrl.rsta = is_cnt; /* set the repeat start bit */
+ I2C_Set_Ctrl (eumbbar, ctrl);
+
+ /* write the slave address and xmit/rcv mode bit */
+ tmp = load_runtime_reg (eumbbar, I2CDR);
+ tmp = (tmp & 0xffffff00) |
+ ((slave_addr & 0x007f) << 1) |
+ (mode == XMIT ? 0x0 : 0x1);
+ store_runtime_reg (eumbbar, I2CDR, tmp);
+
+ if (mode == RCV) {
+ MasterRcvAddress = 1;
+ } else {
+ MasterRcvAddress = 0;
+ }
+
+#ifdef I2CDBG0
+ PRINT ("%s(%d): I2C_Start exit\n", __FILE__, __LINE__);
+#endif
+
+ /* wait for the interrupt or poll */
+ return I2CSUCCESS;
+}
+
+/***********************************************************
+ * function: I2c_Stop
+ *
+ * description: Generate a STOP signal to terminate the master
+ * transaction.
+ * return I2CSUCCESS
+ *
+ **********************************************************/
+static I2CStatus I2C_Stop (unsigned int eumbbar)
+{
+ I2C_CTRL ctrl;
+
+#ifdef I2CDBG0
+ PRINT ("%s(%d): I2C_Stop enter\n", __FILE__, __LINE__);
+#endif
+
+ ctrl = I2C_Get_Ctrl (eumbbar);
+ ctrl.msta = 0;
+ I2C_Set_Ctrl (eumbbar, ctrl);
+
+#ifdef I2CDBG0
+ PRINT ("%s(%d): I2C_Stop exit\n", __FILE__, __LINE__);
+#endif
+
+ return I2CSUCCESS;
+}
+
+/****************************************************
+ * function: I2C_Master_Xmit
+ *
+ * description: Master sends one byte of data to
+ * slave target
+ *
+ * return I2CSUCCESS if the byte transmitted.
+ * Otherwise no-zero
+ *
+ * Note: condition must meet when this function is called:
+ * I2CSR(MIF) == 1 && I2CSR(MCF) == 1 && I2CSR(RXAK) == 0
+ * I2CCR(MSTA) == 1 && I2CCR(MTX) == 1
+ *
+ ***************************************************/
+static I2CStatus I2C_Master_Xmit (unsigned int eumbbar)
+{
+ unsigned int val;
+
+ if (ByteToXmit > 0) {
+
+ if (ByteToXmit == XmitByte) {
+ /* all xmitted */
+ ByteToXmit = 0;
+
+ if (XmitBufEmptyStop == 1) {
+ I2C_Stop (eumbbar);
+ }
+
+ return I2CBUFFEMPTY;
+
+ }
+#ifdef I2CDBG0
+ PRINT ("%s(%d): xmit 0x%02x\n", __FILE__, __LINE__,
+ *(XmitBuf + XmitByte));
+#endif
+
+ val = *(XmitBuf + XmitByte);
+ val &= 0x000000ff;
+ store_runtime_reg (eumbbar, I2CDR, val);
+ XmitByte++;
+
+ return I2CSUCCESS;
+
+ }
+
+ return I2CBUFFEMPTY;
+}
+
+/***********************************************
+ * function: I2C_Master_Rcv
+ *
+ * description: master reads one byte data
+ * from slave source
+ *
+ * return I2CSUCCESS if no error
+ *
+ * Note: condition must meet when this function is called:
+ * I2CSR(MIF) == 1 && I2CSR(MCF) == 1 &&
+ * I2CCR(MSTA) == 1 && I2CCR(MTX) == 0
+ *
+ ***********************************************/
+static I2CStatus I2C_Master_Rcv (unsigned int eumbbar)
+{
+ I2C_CTRL ctrl;
+ unsigned int val;
+
+ if (ByteToRcv > 0) {
+
+ if (ByteToRcv - RcvByte == 2 && RcvBufFulStop == 1) {
+ /* master requests more than or equal to 2 bytes
+ * we are reading 2nd to last byte
+ */
+
+ /* we need to set I2CCR(TXAK) to generate a STOP */
+ ctrl = I2C_Get_Ctrl (eumbbar);
+ ctrl.txak = 1;
+ I2C_Set_Ctrl (eumbbar, ctrl);
+
+ /* Kahlua will automatically generate a STOP
+ * next time a transaction happens
+ */
+
+ /* note: the case of master requesting one byte is
+ * handled in I2C_ISR
+ */
+ }
+
+ /* generat a STOP before reading the last byte */
+ if (RcvByte + 1 == ByteToRcv && RcvBufFulStop == 1) {
+ I2C_Stop (eumbbar);
+ }
+
+ val = load_runtime_reg (eumbbar, I2CDR);
+ *(RcvBuf + RcvByte) = val & 0xFF;
+
+#ifdef I2CDBG0
+ PRINT ("%s(%d): rcv 0x%02x\n", __FILE__, __LINE__,
+ *(RcvBuf + RcvByte));
+#endif
+
+ RcvByte++;
+
+ if (ByteToRcv == RcvByte) {
+ ByteToRcv = 0;
+
+ return I2CBUFFFULL;
+ }
+
+ return I2CSUCCESS;
+ }
+
+ return I2CBUFFFULL;
+
+}
+
+/****************************************************
+ * function: I2C_Slave_Xmit
+ *
+ * description: Slave sends one byte of data to
+ * requesting destination
+ *
+ * return SUCCESS if the byte transmitted. Otherwise
+ * No-zero
+ *
+ * Note: condition must meet when this function is called:
+ * I2CSR(MIF) == 1 && I2CSR(MCF) == 1 && I2CSR(RXAK) = 0
+ * I2CCR(MSTA) == 0 && I2CCR(MTX) == 1
+ *
+ ***************************************************/
+static I2CStatus I2C_Slave_Xmit (unsigned int eumbbar)
+{
+ unsigned int val;
+
+ if (ByteToXmit > 0) {
+
+ if (ByteToXmit == XmitByte) {
+ /* no more data to send */
+ ByteToXmit = 0;
+
+ /*
+ * do not toggle I2CCR(MTX). Doing so will
+ * cause bus-hung since current Kahlua design
+ * does not give master a way to detect slave
+ * stop. It is always a good idea for master
+ * to use timer to prevent the long long
+ * delays
+ */
+
+ return I2CBUFFEMPTY;
+ }
+#ifdef I2CDBG
+ PRINT ("%s(%d): xmit 0x%02x\n", __FILE__, __LINE__,
+ *(XmitBuf + XmitByte));
+#endif
+
+ val = *(XmitBuf + XmitByte);
+ val &= 0x000000ff;
+ store_runtime_reg (eumbbar, I2CDR, val);
+ XmitByte++;
+
+ return I2CSUCCESS;
+ }
+
+ return I2CBUFFEMPTY;
+}
+
+/***********************************************
+ * function: I2C_Slave_Rcv
+ *
+ * description: slave reads one byte data
+ * from master source
+ *
+ * return I2CSUCCESS if no error otherwise non-zero
+ *
+ * Note: condition must meet when this function is called:
+ * I2CSR(MIF) == 1 && I2CSR(MCF) == 1 &&
+ * I2CCR(MSTA) == 0 && I2CCR(MTX) = 0
+ *
+ ***********************************************/
+static I2CStatus I2C_Slave_Rcv (unsigned int eumbbar)
+{
+ unsigned int val;
+ I2C_CTRL ctrl;
+
+ if (ByteToRcv > 0) {
+ val = load_runtime_reg (eumbbar, I2CDR);
+ *(RcvBuf + RcvByte) = val & 0xff;
+#ifdef I2CDBG
+ PRINT ("%s(%d): rcv 0x%02x\n", __FILE__, __LINE__,
+ *(RcvBuf + RcvByte));
+#endif
+ RcvByte++;
+
+ if (ByteToRcv == RcvByte) {
+ if (RcvBufFulStop == 1) {
+ /* all done */
+ ctrl = I2C_Get_Ctrl (eumbbar);
+ ctrl.txak = 1;
+ I2C_Set_Ctrl (eumbbar, ctrl);
+ }
+
+ ByteToRcv = 0;
+ return I2CBUFFFULL;
+ }
+
+ return I2CSUCCESS;
+ }
+
+ return I2CBUFFFULL;
+}
+
+/****************** Device Control Function *************/
+
+/*********************************************************
+ * function: I2C_Init
+ *
+ * description: Initialize I2C unit with desired frequency divider,
+ * master's listening address, with interrupt enabled
+ * or disabled.
+ *
+ * note:
+ ********************************************************/
+static I2CStatus I2C_Init (unsigned int eumbbar, unsigned char fdr, /* frequency divider */
+ unsigned char slave_addr, /* driver's address used for receiving */
+ unsigned int en_int)
+{ /* 1 - enable I2C interrupt
+ * 0 - disable I2C interrup
+ */
+ I2C_CTRL ctrl;
+ unsigned int tmp;
+
+#ifdef I2CDBG0
+ PRINT ("%s(%d): I2C_Init enter\n", __FILE__, __LINE__);
+#endif
+
+ ctrl = I2C_Get_Ctrl (eumbbar);
+ /* disable the I2C module before we change everything */
+ ctrl.men = 0;
+ I2C_Set_Ctrl (eumbbar, ctrl);
+
+ /* set the frequency diver */
+ tmp = load_runtime_reg (eumbbar, I2CFDR);
+ tmp = (tmp & 0xffffffc0) | (fdr & 0x3f);
+ store_runtime_reg (eumbbar, I2CFDR, tmp);
+
+ /* Set our listening (slave) address */
+ tmp = load_runtime_reg (eumbbar, I2CADR);
+ tmp = (tmp & 0xffffff01) | ((slave_addr & 0x7f) << 1);
+ store_runtime_reg (eumbbar, I2CADR, tmp);
+
+ /* enable I2C with desired interrupt setting */
+ ctrl.men = 1;
+ ctrl.mien = en_int & 0x1;
+ I2C_Set_Ctrl (eumbbar, ctrl);
+#ifdef I2CDBG0
+ PRINT ("%s(%d): I2C_Init exit\n", __FILE__, __LINE__);
+#endif
+
+ return I2CSUCCESS;
+
+}
+
+/*****************************************
+ * function I2c_Get_Stat
+ *
+ * description: Query I2C Status, i.e., read I2CSR
+ *
+ ****************************************/
+static I2C_STAT I2C_Get_Stat (unsigned int eumbbar)
+{
+ unsigned int temp;
+ I2C_STAT stat;
+
+ temp = load_runtime_reg (eumbbar, I2CSR);
+
+#ifdef I2CDBG0
+ PRINT ("%s(%d): get stat = 0x%08x\n", __FILE__, __LINE__, temp);
+#endif
+
+ stat.rsrv0 = (temp & 0xffffff00) >> 8;
+ stat.mcf = (temp & 0x00000080) >> 7;
+ stat.maas = (temp & 0x00000040) >> 6;
+ stat.mbb = (temp & 0x00000020) >> 5;
+ stat.mal = (temp & 0x00000010) >> 4;
+ stat.rsrv1 = (temp & 0x00000008) >> 3;
+ stat.srw = (temp & 0x00000004) >> 2;
+ stat.mif = (temp & 0x00000002) >> 1;
+ stat.rxak = (temp & 0x00000001);
+ return stat;
+}
+
+/*********************************************
+ * function: I2c_Set_Ctrl
+ *
+ * description: Change I2C Control bits,
+ * i.e., write to I2CCR
+ *
+ ********************************************/
+static void I2C_Set_Ctrl (unsigned int eumbbar, I2C_CTRL ctrl)
+{ /* new control value */
+ unsigned int temp = load_runtime_reg (eumbbar, I2CCR);
+
+ temp &= 0xffffff03;
+ temp |= ((ctrl.men & 0x1) << 7);
+ temp |= ((ctrl.mien & 0x1) << 6);
+ temp |= ((ctrl.msta & 0x1) << 5);
+ temp |= ((ctrl.mtx & 0x1) << 4);
+ temp |= ((ctrl.txak & 0x1) << 3);
+ temp |= ((ctrl.rsta & 0x1) << 2);
+#ifdef I2CDBG0
+ PRINT ("%s(%d): set ctrl = 0x%08x\n", __FILE__, __LINE__, temp);
+#endif
+ store_runtime_reg (eumbbar, I2CCR, temp);
+
+}
+
+/*****************************************
+ * function: I2C_Get_Ctrl
+ *
+ * description: Query I2C Control bits,
+ * i.e., read I2CCR
+ *****************************************/
+static I2C_CTRL I2C_Get_Ctrl (unsigned int eumbbar)
+{
+ union {
+ I2C_CTRL ctrl;
+ unsigned int temp;
+ } s;
+
+ s.temp = load_runtime_reg (eumbbar, I2CCR);
+#ifdef I2CDBG0
+ PRINT ("%s(%d): get ctrl = 0x%08x\n", __FILE__, __LINE__, s.temp);
+#endif
+
+ return s.ctrl;
+}
+
+
+/****************************************
+ * function: I2C_Slave_Addr
+ *
+ * description: Process slave address phase.
+ * return I2CSUCCESS if no error
+ *
+ * note: Precondition for calling this function:
+ * I2CSR(MIF) == 1 &&
+ * I2CSR(MAAS) == 1
+ ****************************************/
+static I2CStatus I2C_Slave_Addr (unsigned int eumbbar)
+{
+ I2C_STAT stat = I2C_Get_Stat (eumbbar);
+ I2C_CTRL ctrl = I2C_Get_Ctrl (eumbbar);
+
+ if (stat.srw == 1) {
+ /* we are asked to xmit */
+ ctrl.mtx = 1;
+ I2C_Set_Ctrl (eumbbar, ctrl); /* set MTX */
+ return I2C_Slave_Xmit (eumbbar);
+ }
+
+ /* we are asked to receive data */
+ ctrl.mtx = 0;
+ I2C_Set_Ctrl (eumbbar, ctrl);
+ (void) load_runtime_reg (eumbbar, I2CDR); /* do a fake read to start */
+
+ return I2CADDRESS;
+}
+
+/***********************************************
+ * function: I2C_ISR
+ *
+ * description: I2C Interrupt service routine
+ *
+ * note: Precondition:
+ * I2CSR(MIF) == 1
+ **********************************************/
+static I2CStatus I2C_ISR (unsigned int eumbbar)
+{
+ I2C_STAT stat;
+ I2C_CTRL ctrl;
+
+#ifdef I2CDBG0
+ PRINT ("%s(%d): I2C_ISR\n", __FILE__, __LINE__);
+#endif
+
+ stat = I2C_Get_Stat (eumbbar);
+ ctrl = I2C_Get_Ctrl (eumbbar);
+
+ /* clear MIF */
+ stat.mif = 0;
+
+ /* Now let see what kind of event this is */
+ if (stat.mcf == 1) {
+ /* transfer compete */
+
+ /* clear the MIF bit */
+ I2C_Set_Stat (eumbbar, stat);
+
+ if (ctrl.msta == 1) {
+ /* master */
+ if (ctrl.mtx == 1) {
+ /* check if this is the address phase for master receive */
+ if (MasterRcvAddress == 1) {
+ /* Yes, it is the address phase of master receive */
+ ctrl.mtx = 0;
+ /* now check how much we want to receive */
+ if (ByteToRcv == 1 && RcvBufFulStop == 1) {
+ ctrl.txak = 1;
+ }
+
+ I2C_Set_Ctrl (eumbbar, ctrl);
+ (void) load_runtime_reg (eumbbar, I2CDR); /* fake read first */
+
+ MasterRcvAddress = 0;
+ return I2CADDRESS;
+
+ }
+
+ /* master xmit */
+ if (stat.rxak == 0) {
+ /* slave has acknowledged */
+ return I2C_Master_Xmit (eumbbar);
+ }
+
+ /* slave has not acknowledged yet, generate a STOP */
+ if (XmitBufEmptyStop == 1) {
+ ctrl.msta = 0;
+ I2C_Set_Ctrl (eumbbar, ctrl);
+ }
+
+ return I2CSUCCESS;
+ }
+
+ /* master receive */
+ return I2C_Master_Rcv (eumbbar);
+ }
+
+ /* slave */
+ if (ctrl.mtx == 1) {
+ /* slave xmit */
+ if (stat.rxak == 0) {
+ /* master has acknowledged */
+ return I2C_Slave_Xmit (eumbbar);
+ }
+
+ /* master has not acknowledged, wait for STOP */
+ /* do nothing for preventing bus from hung */
+ return I2CSUCCESS;
+ }
+
+ /* slave rcv */
+ return I2C_Slave_Rcv (eumbbar);
+
+ } else if (stat.maas == 1) {
+ /* received a call from master */
+
+ /* clear the MIF bit */
+ I2C_Set_Stat (eumbbar, stat);
+
+ /* master is calling us, process the address phase */
+ return I2C_Slave_Addr (eumbbar);
+ } else {
+ /* has to be arbitration lost */
+ stat.mal = 0;
+ I2C_Set_Stat (eumbbar, stat);
+
+ ctrl.msta = 0; /* return to receive mode */
+ I2C_Set_Ctrl (eumbbar, ctrl);
+ }
+
+ return I2CSUCCESS;
+
+}
+
+/******************************************************
+ * function: I2C_Set_Stat
+ *
+ * description: modify the I2CSR
+ *
+ *****************************************************/
+static void I2C_Set_Stat (unsigned int eumbbar, I2C_STAT stat)
+{
+ union {
+ unsigned int val;
+ I2C_STAT stat;
+ } s_tmp;
+ union {
+ unsigned int val;
+ I2C_STAT stat;
+ } s;
+
+ s.val = load_runtime_reg (eumbbar, I2CSR);
+ s.val &= 0xffffff08;
+ s_tmp.stat = stat;
+ s.val |= (s_tmp.val & 0xf7);
+
+#ifdef I2CDBG0
+ PRINT ("%s(%d): set stat = 0x%08x\n", __FILE__, __LINE__, s.val);
+#endif
+
+ store_runtime_reg (eumbbar, I2CSR, s.val);
+
+}
+
+/******************************************************
+ * The following are routines to glue the rest of
+ * U-Boot to the Sandpoint I2C driver.
+ *****************************************************/
+
+void i2c_init (int speed, int slaveadd)
+{
+#ifdef DEBUG
+ I2C_Initialize (0x7f, 0, (void *) printf);
+#else
+ I2C_Initialize (0x7f, 0, 0);
+#endif
+}
+
+int i2c_probe (uchar chip)
+{
+ int tmp;
+
+ /*
+ * Try to read the first location of the chip. The underlying
+ * driver doesn't appear to support sending just the chip address
+ * and looking for an <ACK> back.
+ */
+ udelay(10000);
+ return i2c_read (chip, 0, 1, (char *)&tmp, 1);
+}
+
+int i2c_read (uchar chip, uint addr, int alen, uchar * buffer, int len)
+{
+ I2CStatus status;
+ uchar xaddr[4];
+
+ if (alen > 0) {
+ xaddr[0] = (addr >> 24) & 0xFF;
+ xaddr[1] = (addr >> 16) & 0xFF;
+ xaddr[2] = (addr >> 8) & 0xFF;
+ xaddr[3] = addr & 0xFF;
+
+ status = I2C_do_buffer (0, I2C_MASTER_XMIT, chip, alen,
+ &xaddr[4 - alen], I2C_NO_STOP, 1,
+ I2C_NO_RESTART);
+ if (status != I2C_SUCCESS) {
+ PRINT ("i2c_read: can't send data address for read\n");
+ return 1;
+ }
+ }
+
+ /* The data transfer will be a continuation. */
+ status = I2C_do_buffer (0, I2C_MASTER_RCV, chip, len,
+ buffer, I2C_STOP, 1, (alen > 0 ? I2C_RESTART :
+ I2C_NO_RESTART));
+
+ if (status != I2C_SUCCESS) {
+ PRINT ("i2c_read: can't perform data transfer\n");
+ return 1;
+ }
+
+ return 0;
+}
+
+int i2c_write (uchar chip, uint addr, int alen, uchar * buffer, int len)
+{
+ I2CStatus status;
+ unsigned char dummy_buffer[I2C_RXTX_LEN + 2];
+ int i;
+
+ dummy_buffer[0] = addr & 0xFF;
+ if (alen == 2)
+ dummy_buffer[1] = (addr >> 8) & 0xFF;
+ for (i = 0; i < len; i++)
+ dummy_buffer[i + alen] = buffer[i];
+
+ status = I2C_do_buffer (0, I2C_MASTER_XMIT, chip, alen + len,
+ dummy_buffer, I2C_STOP, 1, I2C_NO_RESTART);
+
+#ifdef CFG_EEPROM_PAGE_WRITE_DELAY_MS
+ udelay(CFG_EEPROM_PAGE_WRITE_DELAY_MS * 1000);
+#endif
+ if (status != I2C_SUCCESS) {
+ PRINT ("i2c_write: can't perform data transfer\n");
+ return 1;
+ }
+
+ return 0;
+}
+
+uchar i2c_reg_read (uchar i2c_addr, uchar reg)
+{
+ char buf[1];
+
+ i2c_init (0, 0);
+
+ i2c_read (i2c_addr, reg, 1, buf, 1);
+
+ return (buf[0]);
+}
+
+void i2c_reg_write (uchar i2c_addr, uchar reg, uchar val)
+{
+ i2c_init (0, 0);
+
+ i2c_write (i2c_addr, reg, 1, &val, 1);
+}
+
+#endif /* CONFIG_HARD_I2C */
--- /dev/null
+/*
+ * arch/ppc/kernel/mpc10x_common.c
+ *
+ * Common routines for the Motorola SPS MPC106, MPC107 and MPC8240 Host bridge,
+ * Mem ctlr, EPIC, etc.
+ *
+ * Author: Mark A. Greer
+ * mgreer@mvista.com
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include <common.h>
+
+#ifdef CONFIG_PCI
+
+#include <asm/processor.h>
+#include <asm/io.h>
+#include <pci.h>
+#include <mpc824x.h>
+
+void pci_mpc824x_init (struct pci_controller *hose)
+{
+ hose->first_busno = 0;
+ hose->last_busno = 0xff;
+
+ /* System memory space */
+ pci_set_region(hose->regions + 0,
+ CHRP_PCI_MEMORY_BUS,
+ CHRP_PCI_MEMORY_PHYS,
+ CHRP_PCI_MEMORY_SIZE,
+ PCI_REGION_MEM | PCI_REGION_MEMORY);
+
+ /* PCI memory space */
+ pci_set_region(hose->regions + 1,
+ CHRP_PCI_MEM_BUS,
+ CHRP_PCI_MEM_PHYS,
+ CHRP_PCI_MEM_SIZE,
+ PCI_REGION_MEM);
+
+ /* ISA/PCI memory space */
+ pci_set_region(hose->regions + 2,
+ CHRP_ISA_MEM_BUS,
+ CHRP_ISA_MEM_PHYS,
+ CHRP_ISA_MEM_SIZE,
+ PCI_REGION_MEM);
+
+ /* PCI I/O space */
+ pci_set_region(hose->regions + 3,
+ CHRP_PCI_IO_BUS,
+ CHRP_PCI_IO_PHYS,
+ CHRP_PCI_IO_SIZE,
+ PCI_REGION_IO);
+
+ /* ISA/PCI I/O space */
+ pci_set_region(hose->regions + 4,
+ CHRP_ISA_IO_BUS,
+ CHRP_ISA_IO_PHYS,
+ CHRP_ISA_IO_SIZE,
+ PCI_REGION_IO);
+
+ hose->region_count = 5;
+
+ pci_setup_indirect(hose,
+ CHRP_REG_ADDR,
+ CHRP_REG_DATA);
+
+ pci_register_hose(hose);
+
+ hose->last_busno = pci_hose_scan(hose);
+}
+
+#endif
--- /dev/null
+/*
+ * Copyright (C) 1998 Dan Malek <dmalek@jlc.net>
+ * Copyright (C) 1999 Magnus Damm <kieraypc01.p.y.kie.era.ericsson.se>
+ * Copyright (C) 2000,2001,2002 Wolfgang Denk <wd@denx.de>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/* U-Boot - Startup Code for PowerPC based Embedded Boards
+ *
+ *
+ * The processor starts at 0x00000100 and the code is executed
+ * from flash. The code is organized to be at an other address
+ * in memory, but as long we don't jump around before relocating.
+ * board_init lies at a quite high address and when the cpu has
+ * jumped there, everything is ok.
+ * This works because the cpu gives the FLASH (CS0) the whole
+ * address space at startup, and board_init lies as a echo of
+ * the flash somewhere up there in the memorymap.
+ *
+ * board_init will change CS0 to be positioned at the correct
+ * address and (s)dram will be positioned at address 0
+ */
+#include <config.h>
+#include <mpc824x.h>
+#include <version.h>
+
+#define _LINUX_CONFIG_H 1 /* avoid reading Linux autoconf.h file */
+
+#include <ppc_asm.tmpl>
+#include <ppc_defs.h>
+
+#include <asm/cache.h>
+#include <asm/mmu.h>
+
+#ifndef CONFIG_IDENT_STRING
+#define CONFIG_IDENT_STRING ""
+#endif
+
+/* We don't want the MMU yet.
+*/
+#undef MSR_KERNEL
+/* FP, Machine Check and Recoverable Interr. */
+#define MSR_KERNEL ( MSR_FP | MSR_ME | MSR_RI )
+
+/*
+ * Set up GOT: Global Offset Table
+ *
+ * Use r14 to access the GOT
+ */
+ START_GOT
+ GOT_ENTRY(_GOT2_TABLE_)
+ GOT_ENTRY(_FIXUP_TABLE_)
+
+ GOT_ENTRY(_start)
+ GOT_ENTRY(_start_of_vectors)
+ GOT_ENTRY(_end_of_vectors)
+ GOT_ENTRY(transfer_to_handler)
+
+ GOT_ENTRY(_end)
+ GOT_ENTRY(.bss)
+#if defined(CONFIG_FADS)
+ GOT_ENTRY(environment)
+#endif
+ END_GOT
+
+/*
+ * r3 - 1st arg to board_init(): IMMP pointer
+ * r4 - 2nd arg to board_init(): boot flag
+ */
+ .text
+ .long 0x27051956 /* U-Boot Magic Number */
+ .globl version_string
+version_string:
+ .ascii U_BOOT_VERSION
+ .ascii " (", __DATE__, " - ", __TIME__, ")"
+ .ascii CONFIG_IDENT_STRING, "\0"
+
+ . = EXC_OFF_SYS_RESET
+ .globl _start
+_start:
+ li r21, BOOTFLAG_COLD /* Normal Power-On: Boot from FLASH */
+ b boot_cold
+
+ . = EXC_OFF_SYS_RESET + 0x10
+
+ .globl _start_warm
+_start_warm:
+ li r21, BOOTFLAG_WARM /* Software reboot */
+ b boot_warm
+
+boot_cold:
+boot_warm:
+
+ /* Initialize machine status; enable machine check interrupt */
+ /*----------------------------------------------------------------------*/
+ li r3, MSR_KERNEL /* Set FP, ME, RI flags */
+ mtmsr r3
+ mtspr SRR1, r3 /* Make SRR1 match MSR */
+
+ addis r0,0,0x0000 /* lets make sure that r0 is really 0 */
+ mtspr HID0, r0 /* disable I and D caches */
+
+ mfspr r3, ICR /* clear Interrupt Cause Register */
+
+ mfmsr r3 /* turn off address translation */
+ addis r4,0,0xffff
+ ori r4,r4,0xffcf
+ and r3,r3,r4
+ mtmsr r3
+ isync
+ sync /* the MMU should be off... */
+
+
+in_flash:
+#if defined(CONFIG_BMW)
+ bl early_init_f /* Must be ASM: no stack yet! */
+#endif
+ /*
+ * Setup BATs - cannot be done in C since we don't have a stack yet
+ */
+ bl setup_bats
+
+ /* Enable MMU.
+ */
+ mfmsr r3
+ ori r3, r3, (MSR_IR | MSR_DR)
+ mtmsr r3
+#if !defined(CONFIG_BMW)
+ /* Enable and invalidate data cache.
+ */
+ mfspr r3, HID0
+ mr r2, r3
+ ori r3, r3, HID0_DCE | HID0_DCI
+ ori r2, r2, HID0_DCE
+ sync
+ mtspr HID0, r3
+ mtspr HID0, r2
+ sync
+
+ /* Allocate Initial RAM in data cache.
+ */
+ lis r3, CFG_INIT_RAM_ADDR@h
+ ori r3, r3, CFG_INIT_RAM_ADDR@l
+ li r2, 128
+ mtctr r2
+1:
+ dcbz r0, r3
+ addi r3, r3, 32
+ bdnz 1b
+
+ /* Lock way0 in data cache.
+ */
+ mfspr r3, 1011
+ lis r2, 0xffff
+ ori r2, r2, 0xff1f
+ and r3, r3, r2
+ ori r3, r3, 0x0080
+ sync
+ mtspr 1011, r3
+#endif /* !CONFIG_BMW */
+ /*
+ * Thisk the stack pointer *somewhere* sensible. Doesnt
+ * matter much where as we'll move it when we relocate
+ */
+ lis r1, (CFG_INIT_RAM_ADDR + CFG_GBL_DATA_OFFSET)@h
+ ori r1, r1, (CFG_INIT_RAM_ADDR + CFG_GBL_DATA_OFFSET)@l
+
+ li r0, 0 /* Make room for stack frame header and */
+ stwu r0, -4(r1) /* clear final stack frame so that */
+ stwu r0, -4(r1) /* stack backtraces terminate cleanly */
+
+ /* let the C-code set up the rest */
+ /* */
+ /* Be careful to keep code relocatable ! */
+ /*----------------------------------------------------------------------*/
+
+ GET_GOT /* initialize GOT access */
+
+ /* r3: IMMR */
+ bl cpu_init_f /* run low-level CPU init code (from Flash) */
+
+ mr r3, r21
+ /* r3: BOOTFLAG */
+ bl board_init_f /* run 1st part of board init code (from Flash) */
+
+
+
+ .globl _start_of_vectors
+_start_of_vectors:
+
+/* Machine check */
+ STD_EXCEPTION(EXC_OFF_MACH_CHCK, MachineCheck, MachineCheckException)
+
+/* Data Storage exception. "Never" generated on the 860. */
+ STD_EXCEPTION(EXC_OFF_DATA_STOR, DataStorage, UnknownException)
+
+/* Instruction Storage exception. "Never" generated on the 860. */
+ STD_EXCEPTION(EXC_OFF_INS_STOR, InstStorage, UnknownException)
+
+/* External Interrupt exception. */
+ STD_EXCEPTION(EXC_OFF_EXTERNAL, ExtInterrupt, external_interrupt)
+
+/* Alignment exception. */
+ . = EXC_OFF_ALIGN
+Alignment:
+ EXCEPTION_PROLOG
+ mfspr r4,DAR
+ stw r4,_DAR(r21)
+ mfspr r5,DSISR
+ stw r5,_DSISR(r21)
+ addi r3,r1,STACK_FRAME_OVERHEAD
+ li r20,MSR_KERNEL
+ rlwimi r20,r23,0,16,16 /* copy EE bit from saved MSR */
+ lwz r6,GOT(transfer_to_handler)
+ mtlr r6
+ blrl
+.L_Alignment:
+ .long AlignmentException - _start + EXC_OFF_SYS_RESET
+ .long int_return - _start + EXC_OFF_SYS_RESET
+
+/* Program check exception */
+ . = EXC_OFF_PROGRAM
+ProgramCheck:
+ EXCEPTION_PROLOG
+ addi r3,r1,STACK_FRAME_OVERHEAD
+ li r20,MSR_KERNEL
+ rlwimi r20,r23,0,16,16 /* copy EE bit from saved MSR */
+ lwz r6,GOT(transfer_to_handler)
+ mtlr r6
+ blrl
+.L_ProgramCheck:
+ .long ProgramCheckException - _start + EXC_OFF_SYS_RESET
+ .long int_return - _start + EXC_OFF_SYS_RESET
+
+ /* No FPU on MPC8xx. This exception is not supposed to happen.
+ */
+ STD_EXCEPTION(EXC_OFF_FPUNAVAIL, FPUnavailable, UnknownException)
+
+ /* I guess we could implement decrementer, and may have
+ * to someday for timekeeping.
+ */
+ STD_EXCEPTION(EXC_OFF_DECR, Decrementer, timer_interrupt)
+ STD_EXCEPTION(0xa00, Trap_0a, UnknownException)
+ STD_EXCEPTION(0xb00, Trap_0b, UnknownException)
+
+ . = 0xc00
+/*
+ * r0 - SYSCALL number
+ * r3-... arguments
+ */
+SystemCall:
+ addis r11,r0,0 /* get functions table addr */
+ ori r11,r11,0 /* Note: this code is patched in trap_init */
+ addis r12,r0,0 /* get number of functions */
+ ori r12,r12,0
+
+ cmplw 0, r0, r12
+ bge 1f
+
+ rlwinm r0,r0,2,0,31 /* fn_addr = fn_tbl[r0] */
+ add r11,r11,r0
+ lwz r11,0(r11)
+
+ li r12,0xd00-4*3 /* save LR & SRRx */
+ mflr r0
+ stw r0,0(r12)
+ mfspr r0,SRR0
+ stw r0,4(r12)
+ mfspr r0,SRR1
+ stw r0,8(r12)
+
+ li r12,0xc00+_back-SystemCall
+ mtlr r12
+ mtspr SRR0,r11
+
+1: SYNC
+ rfi
+
+_back:
+
+ mfmsr r11 /* Disable interrupts */
+ li r12,0
+ ori r12,r12,MSR_EE
+ andc r11,r11,r12
+ SYNC /* Some chip revs need this... */
+ mtmsr r11
+ SYNC
+
+ li r12,0xd00-4*3 /* restore regs */
+ lwz r11,0(r12)
+ mtlr r11
+ lwz r11,4(r12)
+ mtspr SRR0,r11
+ lwz r11,8(r12)
+ mtspr SRR1,r11
+
+ SYNC
+ rfi
+
+ STD_EXCEPTION(EXC_OFF_TRACE, SingleStep, UnknownException)
+
+ STD_EXCEPTION(EXC_OFF_FPUNASSIST, Trap_0e, UnknownException)
+ STD_EXCEPTION(EXC_OFF_PMI, Trap_0f, UnknownException)
+
+ STD_EXCEPTION(EXC_OFF_ITME, InstructionTransMiss, UnknownException)
+ STD_EXCEPTION(EXC_OFF_DLTME, DataLoadTransMiss, UnknownException)
+ STD_EXCEPTION(EXC_OFF_DSTME, DataStoreTransMiss, UnknownException)
+ STD_EXCEPTION(EXC_OFF_IABE, InstructionBreakpoint, UnknownException)
+ STD_EXCEPTION(EXC_OFF_SMIE, SysManageInt, UnknownException)
+ STD_EXCEPTION(0x1500, Reserved5, UnknownException)
+ STD_EXCEPTION(0x1600, Reserved6, UnknownException)
+ STD_EXCEPTION(0x1700, Reserved7, UnknownException)
+ STD_EXCEPTION(0x1800, Reserved8, UnknownException)
+ STD_EXCEPTION(0x1900, Reserved9, UnknownException)
+ STD_EXCEPTION(0x1a00, ReservedA, UnknownException)
+ STD_EXCEPTION(0x1b00, ReservedB, UnknownException)
+ STD_EXCEPTION(0x1c00, ReservedC, UnknownException)
+ STD_EXCEPTION(0x1d00, ReservedD, UnknownException)
+ STD_EXCEPTION(0x1e00, ReservedE, UnknownException)
+ STD_EXCEPTION(0x1f00, ReservedF, UnknownException)
+
+ STD_EXCEPTION(EXC_OFF_RMTE, RunModeTrace, UnknownException)
+
+ .globl _end_of_vectors
+_end_of_vectors:
+
+
+ . = 0x3000
+
+/*
+ * This code finishes saving the registers to the exception frame
+ * and jumps to the appropriate handler for the exception.
+ * Register r21 is pointer into trap frame, r1 has new stack pointer.
+ */
+ .globl transfer_to_handler
+transfer_to_handler:
+ stw r22,_NIP(r21)
+ lis r22,MSR_POW@h
+ andc r23,r23,r22
+ stw r23,_MSR(r21)
+ SAVE_GPR(7, r21)
+ SAVE_4GPRS(8, r21)
+ SAVE_8GPRS(12, r21)
+ SAVE_8GPRS(24, r21)
+#if 0
+ andi. r23,r23,MSR_PR
+ mfspr r23,SPRG3 /* if from user, fix up tss.regs */
+ beq 2f
+ addi r24,r1,STACK_FRAME_OVERHEAD
+ stw r24,PT_REGS(r23)
+2: addi r2,r23,-TSS /* set r2 to current */
+ tovirt(r2,r2,r23)
+#endif
+ mflr r23
+ andi. r24,r23,0x3f00 /* get vector offset */
+ stw r24,TRAP(r21)
+ li r22,0
+ stw r22,RESULT(r21)
+ mtspr SPRG2,r22 /* r1 is now kernel sp */
+#if 0
+ addi r24,r2,TASK_STRUCT_SIZE /* check for kernel stack overflow */
+ cmplw 0,r1,r2
+ cmplw 1,r1,r24
+ crand 1,1,4
+ bgt stack_ovf /* if r2 < r1 < r2+TASK_STRUCT_SIZE */
+#endif
+ lwz r24,0(r23) /* virtual address of handler */
+ lwz r23,4(r23) /* where to go when done */
+ mtspr SRR0,r24
+ ori r20,r20,0x30 /* enable IR, DR */
+ mtspr SRR1,r20
+ mtlr r23
+ SYNC
+ rfi /* jump to handler, enable MMU */
+
+int_return:
+ mfmsr r28 /* Disable interrupts */
+ li r4,0
+ ori r4,r4,MSR_EE
+ andc r28,r28,r4
+ SYNC /* Some chip revs need this... */
+ mtmsr r28
+ SYNC
+ lwz r2,_CTR(r1)
+ lwz r0,_LINK(r1)
+ mtctr r2
+ mtlr r0
+ lwz r2,_XER(r1)
+ lwz r0,_CCR(r1)
+ mtspr XER,r2
+ mtcrf 0xFF,r0
+ REST_10GPRS(3, r1)
+ REST_10GPRS(13, r1)
+ REST_8GPRS(23, r1)
+ REST_GPR(31, r1)
+ lwz r2,_NIP(r1) /* Restore environment */
+ lwz r0,_MSR(r1)
+ mtspr SRR0,r2
+ mtspr SRR1,r0
+ lwz r0,GPR0(r1)
+ lwz r2,GPR2(r1)
+ lwz r1,GPR1(r1)
+ SYNC
+ rfi
+
+/* Cache functions.
+*/
+ .globl icache_enable
+icache_enable:
+ mfspr r5,HID0 /* turn on the I cache. */
+ ori r5,r5,0x8800 /* Instruction cache only! */
+ addis r6,0,0xFFFF
+ ori r6,r6,0xF7FF
+ and r6,r5,r6 /* clear the invalidate bit */
+ sync
+ mtspr HID0,r5
+ mtspr HID0,r6
+ isync
+ sync
+ blr
+
+ .globl icache_disable
+icache_disable:
+ mfspr r5,HID0
+ addis r6,0,0xFFFF
+ ori r6,r6,0x7FFF
+ and r5,r5,r6
+ sync
+ mtspr HID0,r5
+ isync
+ sync
+ blr
+
+ .globl icache_status
+icache_status:
+ mfspr r3, HID0
+ srwi r3, r3, 15 /* >>15 & 1=> select bit 16 */
+ andi. r3, r3, 1
+ blr
+
+ .globl dcache_enable
+dcache_enable:
+ mfspr r5,HID0 /* turn on the D cache. */
+ ori r5,r5,0x4400 /* Data cache only! */
+ mfspr r4, PVR /* read PVR */
+ srawi r3, r4, 16 /* shift off the least 16 bits */
+ cmpi 0, 0, r3, 0xC /* Check for Max pvr */
+ bne NotMax
+ ori r5,r5,0x0040 /* setting the DCFA bit, for Max rev 1 errata */
+NotMax:
+ addis r6,0,0xFFFF
+ ori r6,r6,0xFBFF
+ and r6,r5,r6 /* clear the invalidate bit */
+ sync
+ mtspr HID0,r5
+ mtspr HID0,r6
+ isync
+ sync
+ blr
+
+ .globl dcache_disable
+dcache_disable:
+ mfspr r5,HID0
+ addis r6,0,0xFFFF
+ ori r6,r6,0xBFFF
+ and r5,r5,r6
+ sync
+ mtspr HID0,r5
+ isync
+ sync
+ blr
+
+ .globl dcache_status
+dcache_status:
+ mfspr r3, HID0
+ srwi r3, r3, 14 /* >>14 & 1=> select bit 17 */
+ andi. r3, r3, 1
+ blr
+
+ .globl dc_read
+dc_read:
+/*TODO : who uses this, what should it do?
+*/
+ blr
+
+
+ .globl get_pvr
+get_pvr:
+ mfspr r3, PVR
+ blr
+
+
+/*------------------------------------------------------------------------------*/
+
+/*
+ * void relocate_code (addr_sp, gd, addr_moni)
+ *
+ * This "function" does not return, instead it continues in RAM
+ * after relocating the monitor code.
+ *
+ * r3 = dest
+ * r4 = src
+ * r5 = length in bytes
+ * r6 = cachelinesize
+ */
+ .globl relocate_code
+relocate_code:
+
+ mr r1, r3 /* Set new stack pointer */
+ mr r9, r4 /* Save copy of Global Data pointer */
+ mr r10, r5 /* Save copy of Destination Address */
+
+ mr r3, r5 /* Destination Address */
+#ifdef DEBUG
+ lis r4, CFG_SDRAM_BASE@h /* Source Address */
+ ori r4, r4, CFG_SDRAM_BASE@l
+#else
+ lis r4, CFG_MONITOR_BASE@h /* Source Address */
+ ori r4, r4, CFG_MONITOR_BASE@l
+#endif
+ lis r5, CFG_MONITOR_LEN@h /* Length in Bytes */
+ ori r5, r5, CFG_MONITOR_LEN@l
+ li r6, CFG_CACHELINE_SIZE /* Cache Line Size */
+
+ /*
+ * Fix GOT pointer:
+ *
+ * New GOT-PTR = (old GOT-PTR - CFG_MONITOR_BASE) + Destination Address
+ *
+ * Offset:
+ */
+ sub r15, r10, r4
+
+ /* First our own GOT */
+ add r14, r14, r15
+ /* the the one used by the C code */
+ add r30, r30, r15
+
+ /*
+ * Now relocate code
+ */
+
+ cmplw cr1,r3,r4
+ addi r0,r5,3
+ srwi. r0,r0,2
+ beq cr1,4f /* In place copy is not necessary */
+ beq 7f /* Protect against 0 count */
+ mtctr r0
+ bge cr1,2f
+
+ la r8,-4(r4)
+ la r7,-4(r3)
+1: lwzu r0,4(r8)
+ stwu r0,4(r7)
+ bdnz 1b
+ b 4f
+
+2: slwi r0,r0,2
+ add r8,r4,r0
+ add r7,r3,r0
+3: lwzu r0,-4(r8)
+ stwu r0,-4(r7)
+ bdnz 3b
+
+/*
+ * Now flush the cache: note that we must start from a cache aligned
+ * address. Otherwise we might miss one cache line.
+ */
+4: cmpwi r6,0
+ add r5,r3,r5
+ beq 7f /* Always flush prefetch queue in any case */
+ subi r0,r6,1
+ andc r3,r3,r0
+ mr r4,r3
+5: dcbst 0,r4
+ add r4,r4,r6
+ cmplw r4,r5
+ blt 5b
+ sync /* Wait for all dcbst to complete on bus */
+ mr r4,r3
+6: icbi 0,r4
+ add r4,r4,r6
+ cmplw r4,r5
+ blt 6b
+7: sync /* Wait for all icbi to complete on bus */
+ isync
+
+/*
+ * We are done. Do not return, instead branch to second part of board
+ * initialization, now running from RAM.
+ */
+
+ addi r0, r10, in_ram - _start + EXC_OFF_SYS_RESET
+ mtlr r0
+ blr
+
+in_ram:
+
+ /*
+ * Relocation Function, r14 point to got2+0x8000
+ *
+ * Adjust got2 pointers, no need to check for 0, this code
+ * already puts a few entries in the table.
+ */
+ li r0,__got2_entries@sectoff@l
+ la r3,GOT(_GOT2_TABLE_)
+ lwz r11,GOT(_GOT2_TABLE_)
+ mtctr r0
+ sub r11,r3,r11
+ addi r3,r3,-4
+1: lwzu r0,4(r3)
+ add r0,r0,r11
+ stw r0,0(r3)
+ bdnz 1b
+
+ /*
+ * Now adjust the fixups and the pointers to the fixups
+ * in case we need to move ourselves again.
+ */
+2: li r0,__fixup_entries@sectoff@l
+ lwz r3,GOT(_FIXUP_TABLE_)
+ cmpwi r0,0
+ mtctr r0
+ addi r3,r3,-4
+ beq 4f
+3: lwzu r4,4(r3)
+ lwzux r0,r4,r11
+ add r0,r0,r11
+ stw r10,0(r3)
+ stw r0,0(r4)
+ bdnz 3b
+4:
+clear_bss:
+ /*
+ * Now clear BSS segment
+ */
+ lwz r3,GOT(.bss)
+ lwz r4,GOT(_end)
+
+ cmplw 0, r3, r4
+ beq 6f
+
+ li r0, 0
+5:
+ stw r0, 0(r3)
+ addi r3, r3, 4
+ cmplw 0, r3, r4
+ blt 5b
+6:
+
+ mr r3, r9 /* Global Data pointer */
+ mr r4, r10 /* Destination Address */
+ bl board_init_r
+
+ /* Problems accessing "end" in C, so do it here */
+ .globl get_endaddr
+get_endaddr:
+ lwz r3,GOT(_end)
+ blr
+
+ /*
+ * Copy exception vector code to low memory
+ *
+ * r3: dest_addr
+ * r7: source address, r8: end address, r9: target address
+ */
+ .globl trap_init
+trap_init:
+ lwz r7, GOT(_start)
+ lwz r8, GOT(_end_of_vectors)
+
+ rlwinm r9, r7, 0, 18, 31 /* _start & 0x3FFF */
+
+ cmplw 0, r7, r8
+ bgelr /* return if r7>=r8 - just in case */
+
+ mflr r4 /* save link register */
+1:
+ lwz r0, 0(r7)
+ stw r0, 0(r9)
+ addi r7, r7, 4
+ addi r9, r9, 4
+ cmplw 0, r7, r8
+ bne 1b
+
+ /*
+ * relocate `hdlr' and `int_return' entries
+ */
+ li r7, .L_MachineCheck - _start + EXC_OFF_SYS_RESET
+ li r8, Alignment - _start + EXC_OFF_SYS_RESET
+2:
+ bl trap_reloc
+ addi r7, r7, 0x100 /* next exception vector */
+ cmplw 0, r7, r8
+ blt 2b
+
+ li r7, .L_Alignment - _start + EXC_OFF_SYS_RESET
+ bl trap_reloc
+
+ li r7, .L_ProgramCheck - _start + EXC_OFF_SYS_RESET
+ bl trap_reloc
+
+ li r7, .L_FPUnavailable - _start + EXC_OFF_SYS_RESET
+ li r8, SystemCall - _start + EXC_OFF_SYS_RESET
+3:
+ bl trap_reloc
+ addi r7, r7, 0x100 /* next exception vector */
+ cmplw 0, r7, r8
+ blt 3b
+
+ li r7, .L_SingleStep - _start + EXC_OFF_SYS_RESET
+ li r8, _end_of_vectors - _start + EXC_OFF_SYS_RESET
+4:
+ bl trap_reloc
+ addi r7, r7, 0x100 /* next exception vector */
+ cmplw 0, r7, r8
+ blt 4b
+
+ mtlr r4 /* restore link register */
+ blr
+
+ /*
+ * Function: relocate entries for one exception vector
+ */
+trap_reloc:
+ lwz r0, 0(r7) /* hdlr ... */
+ add r0, r0, r3 /* ... += dest_addr */
+ stw r0, 0(r7)
+
+ lwz r0, 4(r7) /* int_return ... */
+ add r0, r0, r3 /* ... += dest_addr */
+ stw r0, 4(r7)
+
+ blr
+
+ /* Setup the BAT registers.
+ */
+setup_bats:
+ lis r4, CFG_IBAT0L@h
+ ori r4, r4, CFG_IBAT0L@l
+ lis r3, CFG_IBAT0U@h
+ ori r3, r3, CFG_IBAT0U@l
+ mtspr IBAT0L, r4
+ mtspr IBAT0U, r3
+ isync
+
+ lis r4, CFG_DBAT0L@h
+ ori r4, r4, CFG_DBAT0L@l
+ lis r3, CFG_DBAT0U@h
+ ori r3, r3, CFG_DBAT0U@l
+ mtspr DBAT0L, r4
+ mtspr DBAT0U, r3
+ isync
+
+ lis r4, CFG_IBAT1L@h
+ ori r4, r4, CFG_IBAT1L@l
+ lis r3, CFG_IBAT1U@h
+ ori r3, r3, CFG_IBAT1U@l
+ mtspr IBAT1L, r4
+ mtspr IBAT1U, r3
+ isync
+
+ lis r4, CFG_DBAT1L@h
+ ori r4, r4, CFG_DBAT1L@l
+ lis r3, CFG_DBAT1U@h
+ ori r3, r3, CFG_DBAT1U@l
+ mtspr DBAT1L, r4
+ mtspr DBAT1U, r3
+ isync
+
+ lis r4, CFG_IBAT2L@h
+ ori r4, r4, CFG_IBAT2L@l
+ lis r3, CFG_IBAT2U@h
+ ori r3, r3, CFG_IBAT2U@l
+ mtspr IBAT2L, r4
+ mtspr IBAT2U, r3
+ isync
+
+ lis r4, CFG_DBAT2L@h
+ ori r4, r4, CFG_DBAT2L@l
+ lis r3, CFG_DBAT2U@h
+ ori r3, r3, CFG_DBAT2U@l
+ mtspr DBAT2L, r4
+ mtspr DBAT2U, r3
+ isync
+
+ lis r4, CFG_IBAT3L@h
+ ori r4, r4, CFG_IBAT3L@l
+ lis r3, CFG_IBAT3U@h
+ ori r3, r3, CFG_IBAT3U@l
+ mtspr IBAT3L, r4
+ mtspr IBAT3U, r3
+ isync
+
+ lis r4, CFG_DBAT3L@h
+ ori r4, r4, CFG_DBAT3L@l
+ lis r3, CFG_DBAT3U@h
+ ori r3, r3, CFG_DBAT3U@l
+ mtspr DBAT3L, r4
+ mtspr DBAT3U, r3
+ isync
+
+ /* Invalidate TLBs.
+ * -> for (val = 0; val < 0x20000; val+=0x1000)
+ * -> tlbie(val);
+ */
+ lis r3, 0
+ lis r5, 2
+
+1:
+ tlbie r3
+ addi r3, r3, 0x1000
+ cmp 0, 0, r3, r5
+ blt 1b
+
+ blr
+
+
--- /dev/null
+/*
+ * (C) Copyright 2000-2002
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <mpc8260.h>
+#include <asm/cpm_8260.h>
+#include <ioports.h>
+
+static void config_8260_ioports (volatile immap_t * immr)
+{
+ int portnum;
+
+ for (portnum = 0; portnum < 4; portnum++) {
+ uint pmsk = 0,
+ ppar = 0,
+ psor = 0,
+ pdir = 0,
+ podr = 0,
+ pdat = 0;
+ iop_conf_t *iopc = (iop_conf_t *) & iop_conf_tab[portnum][0];
+ iop_conf_t *eiopc = iopc + 32;
+ uint msk = 1;
+
+ /*
+ * NOTE:
+ * index 0 refers to pin 31,
+ * index 31 refers to pin 0
+ */
+ while (iopc < eiopc) {
+ if (iopc->conf) {
+ pmsk |= msk;
+ if (iopc->ppar)
+ ppar |= msk;
+ if (iopc->psor)
+ psor |= msk;
+ if (iopc->pdir)
+ pdir |= msk;
+ if (iopc->podr)
+ podr |= msk;
+ if (iopc->pdat)
+ pdat |= msk;
+ }
+
+ msk <<= 1;
+ iopc++;
+ }
+
+ if (pmsk != 0) {
+ volatile ioport_t *iop = ioport_addr (immr, portnum);
+ uint tpmsk = ~pmsk;
+
+ /*
+ * the (somewhat confused) paragraph at the
+ * bottom of page 35-5 warns that there might
+ * be "unknown behaviour" when programming
+ * PSORx and PDIRx, if PPARx = 1, so I
+ * decided this meant I had to disable the
+ * dedicated function first, and enable it
+ * last.
+ */
+ iop->ppar &= tpmsk;
+ iop->psor = (iop->psor & tpmsk) | psor;
+ iop->pdat = (iop->pdat & tpmsk) | pdat;
+ iop->pdir = (iop->pdir & tpmsk) | pdir;
+ iop->podr = (iop->podr & tpmsk) | podr;
+ iop->ppar |= ppar;
+ }
+ }
+}
+
+/*
+ * Breath some life into the CPU...
+ *
+ * Set up the memory map,
+ * initialize a bunch of registers,
+ * initialize the UPM's
+ */
+void cpu_init_f (volatile immap_t * immr)
+{
+ DECLARE_GLOBAL_DATA_PTR;
+
+ volatile memctl8260_t *memctl = &immr->im_memctl;
+ extern void m8260_cpm_reset (void);
+
+ /* Pointer is writable since we allocated a register for it */
+ gd = (gd_t *) (CFG_INIT_RAM_ADDR + CFG_GBL_DATA_OFFSET);
+
+ /* Clear initial global data */
+ memset ((void *) gd, 0, sizeof (gd_t));
+
+ /* RSR - Reset Status Register - clear all status (5-4) */
+ gd->reset_status = immr->im_clkrst.car_rsr;
+ immr->im_clkrst.car_rsr = RSR_ALLBITS;
+
+ /* RMR - Reset Mode Register - contains checkstop reset enable (5-5) */
+ immr->im_clkrst.car_rmr = CFG_RMR;
+
+ /* BCR - Bus Configuration Register (4-25) */
+ immr->im_siu_conf.sc_bcr = CFG_BCR;
+
+ /* SIUMCR - contains debug pin configuration (4-31) */
+ immr->im_siu_conf.sc_siumcr = CFG_SIUMCR;
+
+ config_8260_ioports (immr);
+
+ /* initialize time counter status and control register (4-40) */
+ immr->im_sit.sit_tmcntsc = CFG_TMCNTSC;
+
+ /* initialize the PIT (4-42) */
+ immr->im_sit.sit_piscr = CFG_PISCR;
+
+#if !defined(CONFIG_COGENT) /* done in start.S for the cogent */
+ /* System clock control register (9-8) */
+ immr->im_clkrst.car_sccr = CFG_SCCR;
+#endif /* !CONFIG_COGENT */
+
+ /*
+ * Memory Controller:
+ */
+
+ /* Map banks 0 and 1 to the FLASH banks 0 and 1 at preliminary
+ * addresses - these have to be modified later when FLASH size
+ * has been determined
+ */
+
+#if defined(CFG_OR0_REMAP)
+ memctl->memc_or0 = CFG_OR0_REMAP;
+#endif
+#if defined(CFG_OR1_REMAP)
+ memctl->memc_or1 = CFG_OR1_REMAP;
+#endif
+
+ /* now restrict to preliminary range */
+ memctl->memc_br0 = CFG_BR0_PRELIM;
+ memctl->memc_or0 = CFG_OR0_PRELIM;
+
+#if defined(CFG_BR1_PRELIM) && defined(CFG_OR1_PRELIM)
+ memctl->memc_or1 = CFG_OR1_PRELIM;
+ memctl->memc_br1 = CFG_BR1_PRELIM;
+#endif
+
+#if defined(CFG_BR2_PRELIM) && defined(CFG_OR2_PRELIM)
+ memctl->memc_or2 = CFG_OR2_PRELIM;
+ memctl->memc_br2 = CFG_BR2_PRELIM;
+#endif
+
+#if defined(CFG_BR3_PRELIM) && defined(CFG_OR3_PRELIM)
+ memctl->memc_or3 = CFG_OR3_PRELIM;
+ memctl->memc_br3 = CFG_BR3_PRELIM;
+#endif
+
+#if defined(CFG_BR4_PRELIM) && defined(CFG_OR4_PRELIM)
+ memctl->memc_or4 = CFG_OR4_PRELIM;
+ memctl->memc_br4 = CFG_BR4_PRELIM;
+#endif
+
+#if defined(CFG_BR5_PRELIM) && defined(CFG_OR5_PRELIM)
+ memctl->memc_or5 = CFG_OR5_PRELIM;
+ memctl->memc_br5 = CFG_BR5_PRELIM;
+#endif
+
+#if defined(CFG_BR6_PRELIM) && defined(CFG_OR6_PRELIM)
+ memctl->memc_or6 = CFG_OR6_PRELIM;
+ memctl->memc_br6 = CFG_BR6_PRELIM;
+#endif
+
+#if defined(CFG_BR7_PRELIM) && defined(CFG_OR7_PRELIM)
+ memctl->memc_or7 = CFG_OR7_PRELIM;
+ memctl->memc_br7 = CFG_BR7_PRELIM;
+#endif
+
+#if defined(CFG_BR8_PRELIM) && defined(CFG_OR8_PRELIM)
+ memctl->memc_or8 = CFG_OR8_PRELIM;
+ memctl->memc_br8 = CFG_BR8_PRELIM;
+#endif
+
+#if defined(CFG_BR9_PRELIM) && defined(CFG_OR9_PRELIM)
+ memctl->memc_or9 = CFG_OR9_PRELIM;
+ memctl->memc_br9 = CFG_BR9_PRELIM;
+#endif
+
+#if defined(CFG_BR10_PRELIM) && defined(CFG_OR10_PRELIM)
+ memctl->memc_or10 = CFG_OR10_PRELIM;
+ memctl->memc_br10 = CFG_BR10_PRELIM;
+#endif
+
+#if defined(CFG_BR11_PRELIM) && defined(CFG_OR11_PRELIM)
+ memctl->memc_or11 = CFG_OR11_PRELIM;
+ memctl->memc_br11 = CFG_BR11_PRELIM;
+#endif
+
+ m8260_cpm_reset ();
+}
+
+/*
+ * initialize higher level parts of CPU like time base and timers
+ */
+int cpu_init_r (void)
+{
+ DECLARE_GLOBAL_DATA_PTR;
+
+ volatile immap_t *immr = (immap_t *) gd->bd->bi_immr_base;
+
+ immr->im_cpm.cp_rccr = CFG_RCCR;
+
+ return (0);
+}
+
+/*
+ * print out the reason for the reset
+ */
+int prt_8260_rsr (void)
+{
+ DECLARE_GLOBAL_DATA_PTR;
+
+ static struct {
+ ulong mask;
+ char *desc;
+ } bits[] = {
+ {
+ RSR_JTRS, "JTAG"}, {
+ RSR_CSRS, "Check Stop"}, {
+ RSR_SWRS, "Software Watchdog"}, {
+ RSR_BMRS, "Bus Monitor"}, {
+ RSR_ESRS, "External Soft"}, {
+ RSR_EHRS, "External Hard"}
+ };
+ static int n = sizeof bits / sizeof bits[0];
+ ulong rsr = gd->reset_status;
+ int i;
+ char *sep;
+
+ puts ("MPC8260 Reset Status:");
+
+ sep = " ";
+ for (i = 0; i < n; i++)
+ if (rsr & bits[i].mask) {
+ printf ("%s%s", sep, bits[i].desc);
+ sep = ", ";
+ }
+
+ puts ("\n\n");
+ return (0);
+}
--- /dev/null
+/*
+ * (C) Copyright 2000
+ * Paolo Scaffardi, AIRVENT SAM s.p.a - RIMINI(ITALY), arsenio@tin.it
+ *
+ * (C) Copyright 2000 Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Marius Groeger <mgroeger@sysgo.de>
+ *
+ * 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(CONFIG_HARD_I2C)
+
+#include <asm/cpm_8260.h>
+#include <i2c.h>
+
+/* define to enable debug messages */
+#undef DEBUG_I2C
+
+/* uSec to wait between polls of the i2c */
+#define DELAY_US 100
+/* uSec to wait for the CPM to start processing the buffer */
+#define START_DELAY_US 1000
+
+/*
+ * tx/rx per-byte timeout: we delay DELAY_US uSec between polls so the
+ * timeout will be (tx_length + rx_length) * DELAY_US * TOUT_LOOP
+ */
+#define TOUT_LOOP 5
+
+/*-----------------------------------------------------------------------
+ * Set default values
+ */
+#ifndef CFG_I2C_SPEED
+#define CFG_I2C_SPEED 50000
+#endif
+
+#ifndef CFG_I2C_SLAVE
+#define CFG_I2C_SLAVE 0xFE
+#endif
+/*-----------------------------------------------------------------------
+ */
+
+typedef void (*i2c_ecb_t)(int, int); /* error callback function */
+
+/* This structure keeps track of the bd and buffer space usage. */
+typedef struct i2c_state {
+ int rx_idx; /* index to next free Rx BD */
+ int tx_idx; /* index to next free Tx BD */
+ void *rxbd; /* pointer to next free Rx BD */
+ void *txbd; /* pointer to next free Tx BD */
+ int tx_space; /* number of Tx bytes left */
+ unsigned char *tx_buf; /* pointer to free Tx area */
+ i2c_ecb_t err_cb; /* error callback function */
+} i2c_state_t;
+
+/* flags for i2c_send() and i2c_receive() */
+#define I2CF_ENABLE_SECONDARY 0x01 /* secondary_address is valid */
+#define I2CF_START_COND 0x02 /* tx: generate start condition */
+#define I2CF_STOP_COND 0x04 /* tx: generate stop condition */
+
+/* return codes */
+#define I2CERR_NO_BUFFERS 0x01 /* no more BDs or buffer space */
+#define I2CERR_MSG_TOO_LONG 0x02 /* tried to send/receive to much data */
+#define I2CERR_TIMEOUT 0x03 /* timeout in i2c_doio() */
+#define I2CERR_QUEUE_EMPTY 0x04 /* i2c_doio called without send/receive */
+
+/* error callback flags */
+#define I2CECB_RX_ERR 0x10 /* this is a receive error */
+#define I2CECB_RX_ERR_OV 0x02 /* receive overrun error */
+#define I2CECB_RX_MASK 0x0f /* mask for error bits */
+#define I2CECB_TX_ERR 0x20 /* this is a transmit error */
+#define I2CECB_TX_CL 0x01 /* transmit collision error */
+#define I2CECB_TX_UN 0x02 /* transmit underflow error */
+#define I2CECB_TX_NAK 0x04 /* transmit no ack error */
+#define I2CECB_TX_MASK 0x0f /* mask for error bits */
+#define I2CECB_TIMEOUT 0x40 /* this is a timeout error */
+
+#define ERROR_I2C_NONE 0
+#define ERROR_I2C_LENGTH 1
+
+#define I2C_WRITE_BIT 0x00
+#define I2C_READ_BIT 0x01
+
+#define I2C_RXTX_LEN 128 /* maximum tx/rx buffer length */
+
+
+#define NUM_RX_BDS 4
+#define NUM_TX_BDS 4
+#define MAX_TX_SPACE 256
+
+typedef struct I2C_BD
+{
+ unsigned short status;
+ unsigned short length;
+ unsigned char *addr;
+} I2C_BD;
+#define BD_I2C_TX_START 0x0400 /* special status for i2c: Start condition */
+
+#define BD_I2C_TX_CL 0x0001 /* collision error */
+#define BD_I2C_TX_UN 0x0002 /* underflow error */
+#define BD_I2C_TX_NAK 0x0004 /* no acknowledge error */
+#define BD_I2C_TX_ERR (BD_I2C_TX_NAK|BD_I2C_TX_UN|BD_I2C_TX_CL)
+
+#define BD_I2C_RX_ERR BD_SC_OV
+
+#ifdef DEBUG_I2C
+#define PRINTD(x) printf x
+#else
+#define PRINTD(x)
+#endif
+
+/*
+ * Returns the best value of I2BRG to meet desired clock speed of I2C with
+ * input parameters (clock speed, filter, and predivider value).
+ * It returns computer speed value and the difference between it and desired
+ * speed.
+ */
+static inline int
+i2c_roundrate(int hz, int speed, int filter, int modval,
+ int *brgval, int *totspeed)
+{
+ int moddiv = 1 << (5-(modval & 3)), brgdiv, div;
+
+ PRINTD(("\t[I2C] trying hz=%d, speed=%d, filter=%d, modval=%d\n",
+ hz, speed, filter, modval));
+
+ div = moddiv * speed;
+ brgdiv = (hz + div - 1) / div;
+
+ PRINTD(("\t\tmoddiv=%d, brgdiv=%d\n", moddiv, brgdiv));
+
+ *brgval = (brgdiv / 2) - 3 - (2*filter);
+
+ if ((*brgval < 0) || (*brgval > 255)) {
+ PRINTD(("\t\trejected brgval=%d\n", *brgval));
+ return -1;
+ }
+
+ brgdiv = 2 * (*brgval + 3 + (2 * filter));
+ div = moddiv * brgdiv ;
+ *totspeed = (hz + div - 1) / div;
+
+ PRINTD(("\t\taccepted brgval=%d, totspeed=%d\n", *brgval, *totspeed));
+
+ return 0;
+}
+
+/*
+ * Sets the I2C clock predivider and divider to meet required clock speed.
+ */
+static int i2c_setrate(int hz, int speed)
+{
+ immap_t *immap = (immap_t *)CFG_IMMR ;
+ volatile i2c8260_t *i2c = (i2c8260_t *)&immap->im_i2c;
+ int brgval,
+ modval, /* 0-3 */
+ bestspeed_diff = speed,
+ bestspeed_brgval=0,
+ bestspeed_modval=0,
+ bestspeed_filter=0,
+ totspeed,
+ filter = 0; /* Use this fixed value */
+
+ for (modval = 0; modval < 4; modval++)
+ {
+ if (i2c_roundrate (hz, speed, filter, modval, &brgval, &totspeed) == 0)
+ {
+ int diff = speed - totspeed ;
+
+ if ((diff >= 0) && (diff < bestspeed_diff))
+ {
+ bestspeed_diff = diff ;
+ bestspeed_modval = modval;
+ bestspeed_brgval = brgval;
+ bestspeed_filter = filter;
+ }
+ }
+ }
+
+ PRINTD(("[I2C] Best is:\n"));
+ PRINTD(("[I2C] CPU=%dhz RATE=%d F=%d I2MOD=%08x I2BRG=%08x DIFF=%dhz\n",
+ hz, speed,
+ bestspeed_filter, bestspeed_modval, bestspeed_brgval,
+ bestspeed_diff));
+
+ i2c->i2c_i2mod |= ((bestspeed_modval & 3) << 1) | (bestspeed_filter << 3);
+ i2c->i2c_i2brg = bestspeed_brgval & 0xff;
+
+ PRINTD(("[I2C] i2mod=%08x i2brg=%08x\n", i2c->i2c_i2mod, i2c->i2c_i2brg));
+
+ return 1 ;
+}
+
+void i2c_init(int speed, int slaveadd)
+{
+ DECLARE_GLOBAL_DATA_PTR;
+
+ volatile immap_t *immap = (immap_t *)CFG_IMMR ;
+ volatile cpm8260_t *cp = (cpm8260_t *)&immap->im_cpm;
+ volatile i2c8260_t *i2c = (i2c8260_t *)&immap->im_i2c;
+ volatile iic_t *iip;
+ ulong rbase, tbase;
+ volatile I2C_BD *rxbd, *txbd;
+ uint dpaddr;
+
+ dpaddr = *((unsigned short*)(&immap->im_dprambase[PROFF_I2C_BASE]));
+ if (dpaddr == 0) {
+ /* need to allocate dual port ram */
+ dpaddr = m8260_cpm_dpalloc(64 +
+ (NUM_RX_BDS * sizeof(I2C_BD)) + (NUM_TX_BDS * sizeof(I2C_BD)) +
+ MAX_TX_SPACE, 64);
+ *((unsigned short*)(&immap->im_dprambase[PROFF_I2C_BASE])) = dpaddr;
+ }
+
+ /*
+ * initialise data in dual port ram:
+ *
+ * dpaddr -> parameter ram (64 bytes)
+ * rbase -> rx BD (NUM_RX_BDS * sizeof(I2C_BD) bytes)
+ * tbase -> tx BD (NUM_TX_BDS * sizeof(I2C_BD) bytes)
+ * tx buffer (MAX_TX_SPACE bytes)
+ */
+
+ iip = (iic_t *)&immap->im_dprambase[dpaddr];
+ memset((void*)iip, 0, sizeof(iic_t));
+
+ rbase = dpaddr + 64;
+ tbase = rbase + NUM_RX_BDS * sizeof(I2C_BD);
+
+ /* Disable interrupts */
+ i2c->i2c_i2mod = 0x00;
+ i2c->i2c_i2cmr = 0x00;
+ i2c->i2c_i2cer = 0xff;
+ i2c->i2c_i2add = slaveadd;
+
+ /*
+ * Set the I2C BRG Clock division factor from desired i2c rate
+ * and current CPU rate (we assume sccr dfbgr field is 0;
+ * divide BRGCLK by 1)
+ */
+ PRINTD(("[I2C] Setting rate...\n"));
+ i2c_setrate (gd->brg_clk, CFG_I2C_SPEED) ;
+
+ /* Set I2C controller in master mode */
+ i2c->i2c_i2com = 0x01;
+
+ /* Initialize Tx/Rx parameters */
+ iip->iic_rbase = rbase;
+ iip->iic_tbase = tbase;
+ rxbd = (I2C_BD *)((unsigned char *)&immap->im_dprambase[iip->iic_rbase]);
+ txbd = (I2C_BD *)((unsigned char *)&immap->im_dprambase[iip->iic_tbase]);
+
+ PRINTD(("[I2C] rbase = %04x\n", iip->iic_rbase));
+ PRINTD(("[I2C] tbase = %04x\n", iip->iic_tbase));
+ PRINTD(("[I2C] rxbd = %08x\n", (int)rxbd));
+ PRINTD(("[I2C] txbd = %08x\n", (int)txbd));
+
+ /* Set big endian byte order */
+ iip->iic_tfcr = 0x10;
+ iip->iic_rfcr = 0x10;
+
+ /* Set maximum receive size. */
+ iip->iic_mrblr = I2C_RXTX_LEN;
+
+ cp->cp_cpcr = mk_cr_cmd(CPM_CR_I2C_PAGE,
+ CPM_CR_I2C_SBLOCK,
+ 0x00,
+ CPM_CR_INIT_TRX) | CPM_CR_FLG;
+ do {
+ __asm__ __volatile__ ("eieio");
+ } while (cp->cp_cpcr & CPM_CR_FLG);
+
+ /* Clear events and interrupts */
+ i2c->i2c_i2cer = 0xff;
+ i2c->i2c_i2cmr = 0x00;
+}
+
+static
+void i2c_newio(i2c_state_t *state)
+{
+ volatile immap_t *immap = (immap_t *)CFG_IMMR ;
+ volatile iic_t *iip;
+ uint dpaddr;
+
+ PRINTD(("[I2C] i2c_newio\n"));
+
+ dpaddr = *((unsigned short*)(&immap->im_dprambase[PROFF_I2C_BASE]));
+ iip = (iic_t *)&immap->im_dprambase[dpaddr];
+ state->rx_idx = 0;
+ state->tx_idx = 0;
+ state->rxbd = (void*)&immap->im_dprambase[iip->iic_rbase];
+ state->txbd = (void*)&immap->im_dprambase[iip->iic_tbase];
+ state->tx_space = MAX_TX_SPACE;
+ state->tx_buf = (uchar*)state->txbd + NUM_TX_BDS * sizeof(I2C_BD);
+ state->err_cb = NULL;
+
+ PRINTD(("[I2C] rxbd = %08x\n", (int)state->rxbd));
+ PRINTD(("[I2C] txbd = %08x\n", (int)state->txbd));
+ PRINTD(("[I2C] tx_buf = %08x\n", (int)state->tx_buf));
+
+ /* clear the buffer memory */
+ memset((char *)state->tx_buf, 0, MAX_TX_SPACE);
+}
+
+static
+int i2c_send(i2c_state_t *state,
+ unsigned char address,
+ unsigned char secondary_address,
+ unsigned int flags,
+ unsigned short size,
+ unsigned char *dataout)
+{
+ volatile I2C_BD *txbd;
+ int i,j;
+
+ PRINTD(("[I2C] i2c_send add=%02d sec=%02d flag=%02d size=%d\n",
+ address, secondary_address, flags, size));
+
+ /* trying to send message larger than BD */
+ if (size > I2C_RXTX_LEN)
+ return I2CERR_MSG_TOO_LONG;
+
+ /* no more free bds */
+ if (state->tx_idx >= NUM_TX_BDS || state->tx_space < (2 + size))
+ return I2CERR_NO_BUFFERS;
+
+ txbd = (I2C_BD *)state->txbd;
+ txbd->addr = state->tx_buf;
+
+ PRINTD(("[I2C] txbd = %08x\n", (int)txbd));
+
+ if (flags & I2CF_START_COND)
+ {
+ PRINTD(("[I2C] Formatting addresses...\n"));
+ if (flags & I2CF_ENABLE_SECONDARY)
+ {
+ txbd->length = size + 2; /* Length of message plus dest addresses */
+ txbd->addr[0] = address << 1;
+ txbd->addr[1] = secondary_address;
+ i = 2;
+ }
+ else
+ {
+ txbd->length = size + 1; /* Length of message plus dest address */
+ txbd->addr[0] = address << 1; /* Write destination address to BD */
+ i = 1;
+ }
+ }
+ else
+ {
+ txbd->length = size; /* Length of message */
+ i = 0;
+ }
+
+ /* set up txbd */
+ txbd->status = BD_SC_READY;
+ if (flags & I2CF_START_COND)
+ txbd->status |= BD_I2C_TX_START;
+ if (flags & I2CF_STOP_COND)
+ txbd->status |= BD_SC_LAST | BD_SC_WRAP;
+
+ /* Copy data to send into buffer */
+ PRINTD(("[I2C] copy data...\n"));
+ for(j = 0; j < size; i++, j++)
+ txbd->addr[i] = dataout[j];
+
+ PRINTD(("[I2C] txbd: length=0x%04x status=0x%04x addr[0]=0x%02x addr[1]=0x%02x\n",
+ txbd->length,
+ txbd->status,
+ txbd->addr[0],
+ txbd->addr[1]));
+
+ /* advance state */
+ state->tx_buf += txbd->length;
+ state->tx_space -= txbd->length;
+ state->tx_idx++;
+ state->txbd = (void*)(txbd + 1);
+
+ return 0;
+}
+
+static
+int i2c_receive(i2c_state_t *state,
+ unsigned char address,
+ unsigned char secondary_address,
+ unsigned int flags,
+ unsigned short size_to_expect,
+ unsigned char *datain)
+{
+ volatile I2C_BD *rxbd, *txbd;
+
+ PRINTD(("[I2C] i2c_receive %02d %02d %02d\n", address, secondary_address, flags));
+
+ /* Expected to receive too much */
+ if (size_to_expect > I2C_RXTX_LEN)
+ return I2CERR_MSG_TOO_LONG;
+
+ /* no more free bds */
+ if (state->tx_idx >= NUM_TX_BDS || state->rx_idx >= NUM_RX_BDS
+ || state->tx_space < 2)
+ return I2CERR_NO_BUFFERS;
+
+ rxbd = (I2C_BD *)state->rxbd;
+ txbd = (I2C_BD *)state->txbd;
+
+ PRINTD(("[I2C] rxbd = %08x\n", (int)rxbd));
+ PRINTD(("[I2C] txbd = %08x\n", (int)txbd));
+
+ txbd->addr = state->tx_buf;
+
+ /* set up TXBD for destination address */
+ if (flags & I2CF_ENABLE_SECONDARY)
+ {
+ txbd->length = 2;
+ txbd->addr[0] = address << 1; /* Write data */
+ txbd->addr[1] = secondary_address; /* Internal address */
+ txbd->status = BD_SC_READY;
+ }
+ else
+ {
+ txbd->length = 1 + size_to_expect;
+ txbd->addr[0] = (address << 1) | 0x01;
+ txbd->status = BD_SC_READY;
+ memset(&txbd->addr[1], 0, txbd->length);
+ }
+
+ /* set up rxbd for reception */
+ rxbd->status = BD_SC_EMPTY;
+ rxbd->length = size_to_expect;
+ rxbd->addr = datain;
+
+ txbd->status |= BD_I2C_TX_START;
+ if (flags & I2CF_STOP_COND)
+ {
+ txbd->status |= BD_SC_LAST | BD_SC_WRAP;
+ rxbd->status |= BD_SC_WRAP;
+ }
+
+ PRINTD(("[I2C] txbd: length=0x%04x status=0x%04x addr[0]=0x%02x addr[1]=0x%02x\n",
+ txbd->length,
+ txbd->status,
+ txbd->addr[0],
+ txbd->addr[1]));
+ PRINTD(("[I2C] rxbd: length=0x%04x status=0x%04x addr[0]=0x%02x addr[1]=0x%02x\n",
+ rxbd->length,
+ rxbd->status,
+ rxbd->addr[0],
+ rxbd->addr[1]));
+
+ /* advance state */
+ state->tx_buf += txbd->length;
+ state->tx_space -= txbd->length;
+ state->tx_idx++;
+ state->txbd = (void*)(txbd + 1);
+ state->rx_idx++;
+ state->rxbd = (void*)(rxbd + 1);
+
+ return 0;
+}
+
+
+static
+int i2c_doio(i2c_state_t *state)
+{
+ volatile immap_t *immap = (immap_t *)CFG_IMMR ;
+ volatile iic_t *iip;
+ volatile i2c8260_t *i2c = (i2c8260_t *)&immap->im_i2c;
+ volatile I2C_BD *txbd, *rxbd;
+ int j;
+ int timeout;
+ uint dpaddr;
+
+ PRINTD(("[I2C] i2c_doio\n"));
+
+ timeout = TOUT_LOOP * 256; /* arbitrarily long */
+
+ if (state->tx_idx <= 0 && state->rx_idx <= 0) {
+ PRINTD(("[I2C] No I/O is queued\n"));
+ return I2CERR_QUEUE_EMPTY;
+ }
+
+ dpaddr = *((unsigned short*)(&immap->im_dprambase[PROFF_I2C_BASE]));
+ iip = (iic_t *)&immap->im_dprambase[dpaddr];
+ iip->iic_rbptr = iip->iic_rbase;
+ iip->iic_tbptr = iip->iic_tbase;
+
+ /* Enable I2C */
+ PRINTD(("[I2C] Enabling I2C...\n"));
+ i2c->i2c_i2mod |= 0x01;
+
+ /* Begin transmission */
+ i2c->i2c_i2com |= 0x80;
+
+ /* Loop until transmit & receive completed */
+
+ txbd = ((I2C_BD*)state->txbd) - 1;
+ j = 0;
+ if (state->tx_idx > 0) {
+ timeout = TOUT_LOOP * txbd->length;
+
+ PRINTD(("[I2C] Transmitting...(txbd=0x%08lx)\n", (ulong)txbd));
+ udelay(START_DELAY_US); /* give it time to start */
+ while((txbd->status & BD_SC_READY) && (j++ < timeout)) {
+ udelay(DELAY_US);
+ if (ctrlc())
+ return (-1);
+ __asm__ __volatile__ ("eieio");
+ }
+ }
+
+ rxbd = ((I2C_BD*)state->rxbd) - 1;
+ j = 0;
+ if ((state->rx_idx > 0) && (j < timeout)) {
+ timeout = TOUT_LOOP * rxbd->length;
+ PRINTD(("[I2C] Receiving...(rxbd=0x%08lx)\n", (ulong)rxbd));
+ udelay(START_DELAY_US); /* give it time to start */
+ while((rxbd->status & BD_SC_EMPTY) && (j++ < timeout)) {
+ udelay(DELAY_US);
+ if (ctrlc())
+ return (-1);
+ __asm__ __volatile__ ("eieio");
+ }
+ }
+
+ /* Turn off I2C */
+ i2c->i2c_i2mod &= ~0x01;
+
+ if (state->err_cb != NULL) {
+ int n, i, b;
+
+ /*
+ * if we have an error callback function, look at the
+ * error bits in the bd status and pass them back
+ */
+
+ if ((n = state->tx_idx) > 0) {
+ for (i = 0; i < n; i++) {
+ txbd = ((I2C_BD*)state->txbd) - (n - i);
+ if ((b = txbd->status & BD_I2C_TX_ERR) != 0)
+ (*state->err_cb)(I2CECB_TX_ERR|b, i);
+ }
+ }
+
+ if ((n = state->rx_idx) > 0) {
+ for (i = 0; i < n; i++) {
+ rxbd = ((I2C_BD*)state->rxbd) - (n - i);
+ if ((b = rxbd->status & BD_I2C_RX_ERR) != 0)
+ (*state->err_cb)(I2CECB_RX_ERR|b, i);
+ }
+ }
+
+ if (j >= timeout)
+ (*state->err_cb)(I2CECB_TIMEOUT, 0);
+ }
+
+ /* sort out errors and return appropriate good/error status */
+ if(j >= timeout)
+ return(I2CERR_TIMEOUT);
+ if((txbd->status & BD_I2C_TX_ERR) != 0)
+ return(I2CECB_TX_ERR | (txbd->status & I2CECB_TX_MASK));
+ if((rxbd->status & BD_I2C_RX_ERR) != 0)
+ return(I2CECB_RX_ERR | (rxbd->status & I2CECB_RX_MASK));
+
+ return(0);
+}
+
+static int had_tx_nak;
+
+static void
+i2c_test_callback(int flags, int xnum)
+{
+ if ((flags & I2CECB_TX_ERR) && (flags & I2CECB_TX_NAK))
+ had_tx_nak = 1;
+}
+
+int i2c_probe(uchar chip)
+{
+ i2c_state_t state;
+ int rc;
+ uchar buf[1];
+
+ i2c_newio(&state);
+
+ state.err_cb = i2c_test_callback;
+ had_tx_nak = 0;
+
+ rc = i2c_receive(&state, chip, 0, I2CF_START_COND|I2CF_STOP_COND, 1, buf);
+
+ if (rc != 0)
+ return (rc);
+
+ rc = i2c_doio(&state);
+
+ if ((rc != 0) && (rc != I2CERR_TIMEOUT))
+ return (rc);
+
+ return (had_tx_nak);
+}
+
+
+int
+i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len)
+{
+ i2c_state_t state;
+ uchar xaddr[4];
+ int rc;
+
+ xaddr[0] = (addr >> 24) & 0xFF;
+ xaddr[1] = (addr >> 16) & 0xFF;
+ xaddr[2] = (addr >> 8) & 0xFF;
+ xaddr[3] = addr & 0xFF;
+
+#ifdef CFG_I2C_EEPROM_ADDR_OVERFLOW
+ /*
+ * EEPROM chips that implement "address overflow" are ones
+ * like Catalyst 24WC04/08/16 which has 9/10/11 bits of address
+ * and the extra bits end up in the "chip address" bit slots.
+ * This makes a 24WC08 (1Kbyte) chip look like four 256 byte
+ * chips.
+ *
+ * Note that we consider the length of the address field to still
+ * be one byte because the extra address bits are hidden in the
+ * chip address.
+ */
+ chip |= ((addr >> (alen * 8)) & CFG_I2C_EEPROM_ADDR_OVERFLOW);
+#endif
+
+ i2c_newio(&state);
+
+ rc = i2c_send(&state, chip, 0, I2CF_START_COND, alen, &xaddr[4-alen]);
+ if (rc != 0) {
+ printf("i2c_read: i2c_send failed (%d)\n", rc);
+ return 1;
+ }
+
+ rc = i2c_receive(&state, chip, 0, I2CF_STOP_COND, len, buffer);
+ if (rc != 0) {
+ printf("i2c_read: i2c_receive failed (%d)\n", rc);
+ return 1;
+ }
+
+ rc = i2c_doio(&state);
+ if (rc != 0) {
+ printf("i2c_read: i2c_doio failed (%d)\n", rc);
+ return 1;
+ }
+ return 0;
+}
+
+int
+i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len)
+{
+ i2c_state_t state;
+ uchar xaddr[4];
+ int rc;
+
+ xaddr[0] = (addr >> 24) & 0xFF;
+ xaddr[1] = (addr >> 16) & 0xFF;
+ xaddr[2] = (addr >> 8) & 0xFF;
+ xaddr[3] = addr & 0xFF;
+
+#ifdef CFG_I2C_EEPROM_ADDR_OVERFLOW
+ /*
+ * EEPROM chips that implement "address overflow" are ones
+ * like Catalyst 24WC04/08/16 which has 9/10/11 bits of address
+ * and the extra bits end up in the "chip address" bit slots.
+ * This makes a 24WC08 (1Kbyte) chip look like four 256 byte
+ * chips.
+ *
+ * Note that we consider the length of the address field to still
+ * be one byte because the extra address bits are hidden in the
+ * chip address.
+ */
+ chip |= ((addr >> (alen * 8)) & CFG_I2C_EEPROM_ADDR_OVERFLOW);
+#endif
+
+ i2c_newio(&state);
+
+ rc = i2c_send(&state, chip, 0, I2CF_START_COND, alen, &xaddr[4-alen]);
+ if (rc != 0) {
+ printf("i2c_write: first i2c_send failed (%d)\n", rc);
+ return 1;
+ }
+
+ rc = i2c_send(&state, 0, 0, I2CF_STOP_COND, len, buffer);
+ if (rc != 0) {
+ printf("i2c_write: second i2c_send failed (%d)\n", rc);
+ return 1;
+ }
+
+ rc = i2c_doio(&state);
+ if (rc != 0) {
+ printf("i2c_write: i2c_doio failed (%d)\n", rc);
+ return 1;
+ }
+ return 0;
+}
+
+uchar
+i2c_reg_read(uchar chip, uchar reg)
+{
+ char buf;
+
+ i2c_read(chip, reg, 1, &buf, 1);
+
+ return (buf);
+}
+
+void
+i2c_reg_write(uchar chip, uchar reg, uchar val)
+{
+ i2c_write(chip, reg, 1, &val, 1);
+}
+
+#endif /* CONFIG_HARD_I2C */
--- /dev/null
+/*
+ * (C) Copyright 2000-2002
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/*
+ * m8xx.c
+ *
+ * CPU specific code
+ *
+ * written or collected and sometimes rewritten by
+ * Magnus Damm <damm@bitsmart.com>
+ *
+ * minor modifications by
+ * Wolfgang Denk <wd@denx.de>
+ */
+
+#include <common.h>
+#include <watchdog.h>
+#include <command.h>
+#include <mpc8xx.h>
+#include <asm/cache.h>
+
+static char *cpu_warning = "\n " \
+ "*** Warning: CPU Core has Silicon Bugs -- Check the Errata ***";
+
+#if ((defined(CONFIG_MPC860) || defined(CONFIG_MPC855)) && \
+ !defined(CONFIG_MPC862))
+# ifdef CONFIG_MPC855
+# define ID_STR "PC855"
+# else
+# define ID_STR "PC860"
+# endif
+
+static int check_CPU (long clock, uint pvr, uint immr)
+{
+ volatile immap_t *immap = (immap_t *) (immr & 0xFFFF0000);
+ uint k, m;
+ char buf[32];
+ char pre = 'X';
+ char *mid = "xx";
+ char *suf;
+
+ /* the highest 16 bits should be 0x0050 for a 860 */
+
+ if ((pvr >> 16) != 0x0050)
+ return -1;
+
+ k = (immr << 16) | *((ushort *) & immap->im_cpm.cp_dparam[0xB0]);
+ m = 0;
+
+ switch (k) {
+ case 0x00020001: pre = 'p'; suf = ""; break;
+ case 0x00030001: suf = ""; break;
+ case 0x00120003: suf = "A"; break;
+ case 0x00130003: suf = "A3"; break;
+
+ case 0x00200004: suf = "B"; break;
+
+ case 0x00300004: suf = "C"; break;
+ case 0x00310004: suf = "C1"; m = 1;
+ break;
+
+ case 0x00200064: mid = "SR"; suf = "B"; break;
+ case 0x00300065: mid = "SR"; suf = "C"; break;
+ case 0x00310065: mid = "SR"; suf = "C1"; m = 1; break;
+ case 0x05010000: suf = "D3"; m = 1; break;
+ case 0x05020000: suf = "D4"; m = 1; break;
+
+ /* this value is not documented anywhere */
+ case 0x40000000: pre = 'P'; suf = "D"; m = 1; break;
+
+ default: suf = NULL; break;
+ }
+
+ if (suf)
+ printf ("%c" ID_STR "%sZPnn%s", pre, mid, suf);
+ else
+ printf ("unknown M" ID_STR " (0x%08x)", k);
+
+ printf (" at %s MHz:", strmhz (buf, clock));
+
+ printf (" %u kB I-Cache", checkicache () >> 10);
+ printf (" %u kB D-Cache", checkdcache () >> 10);
+
+ /* lets check and see if we're running on a 860T (or P?) */
+
+ immap->im_cpm.cp_fec.fec_addr_low = 0x12345678;
+ if (immap->im_cpm.cp_fec.fec_addr_low == 0x12345678) {
+ printf (" FEC present");
+ }
+
+ if (!m) {
+ puts (cpu_warning);
+ }
+
+ putc ('\n');
+
+ return 0;
+}
+
+#elif defined(CONFIG_MPC862)
+
+static int check_CPU (long clock, uint pvr, uint immr)
+{
+ volatile immap_t *immap = (immap_t *) (immr & 0xFFFF0000);
+ uint k, m;
+ char buf[32];
+ char pre = 'X';
+ char *mid = "xx";
+ char *suf;
+
+ /* the highest 16 bits should be 0x0050 for a 8xx */
+
+ if ((pvr >> 16) != 0x0050)
+ return -1;
+
+ k = (immr << 16) | *((ushort *) & immap->im_cpm.cp_dparam[0xB0]);
+ m = 0;
+
+ switch (k) {
+
+ /* this value is not documented anywhere */
+ case 0x06000000: mid = "P"; suf = "0"; break;
+ case 0x06010001: mid = "P"; suf = "A"; m = 1; break;
+ case 0x07000003: mid = "P"; suf = "B"; m = 1; break;
+ default: suf = NULL; break;
+ }
+
+ if (suf)
+ printf ("%cPC862%sZPnn%s", pre, mid, suf);
+ else
+ printf ("unknown MPC862 (0x%08x)", k);
+
+ printf (" at %s MHz:", strmhz (buf, clock));
+
+ printf (" %u kB I-Cache", checkicache () >> 10);
+ printf (" %u kB D-Cache", checkdcache () >> 10);
+
+ /* lets check and see if we're running on a 862T (or P?) */
+
+ immap->im_cpm.cp_fec.fec_addr_low = 0x12345678;
+ if (immap->im_cpm.cp_fec.fec_addr_low == 0x12345678) {
+ printf (" FEC present");
+ }
+
+ if (!m) {
+ puts (cpu_warning);
+ }
+
+ putc ('\n');
+
+ return 0;
+}
+
+#elif defined(CONFIG_MPC823)
+
+static int check_CPU (long clock, uint pvr, uint immr)
+{
+ volatile immap_t *immap = (immap_t *) (immr & 0xFFFF0000);
+ uint k, m;
+ char buf[32];
+ char *suf;
+
+ /* the highest 16 bits should be 0x0050 for a 8xx */
+
+ if ((pvr >> 16) != 0x0050)
+ return -1;
+
+ k = (immr << 16) | *((ushort *) & immap->im_cpm.cp_dparam[0xB0]);
+ m = 0;
+
+ switch (k) {
+ /* MPC823 */
+ case 0x20000000: suf = "0"; break;
+ case 0x20010000: suf = "0.1"; break;
+ case 0x20020000: suf = "Z2/3"; break;
+ case 0x20020001: suf = "Z3"; break;
+ case 0x21000000: suf = "A"; break;
+ case 0x21010000: suf = "B"; m = 1; break;
+ case 0x21010001: suf = "B2"; m = 1; break;
+ /* MPC823E */
+ case 0x24010000: suf = NULL;
+ puts ("PPC823EZTnnB2");
+ m = 1;
+ break;
+ default:
+ suf = NULL;
+ printf ("unknown MPC823 (0x%08x)", k);
+ break;
+ }
+ if (suf)
+ printf ("PPC823ZTnn%s", suf);
+
+ printf (" at %s MHz:", strmhz (buf, clock));
+
+ printf (" %u kB I-Cache", checkicache () >> 10);
+ printf (" %u kB D-Cache", checkdcache () >> 10);
+
+ /* lets check and see if we're running on a 860T (or P?) */
+
+ immap->im_cpm.cp_fec.fec_addr_low = 0x12345678;
+ if (immap->im_cpm.cp_fec.fec_addr_low == 0x12345678) {
+ puts (" FEC present");
+ }
+
+ if (!m) {
+ puts (cpu_warning);
+ }
+
+ putc ('\n');
+
+ return 0;
+}
+
+#elif defined(CONFIG_MPC850)
+
+static int check_CPU (long clock, uint pvr, uint immr)
+{
+ volatile immap_t *immap = (immap_t *) (immr & 0xFFFF0000);
+ uint k, m;
+ char buf[32];
+
+ /* the highest 16 bits should be 0x0050 for a 8xx */
+
+ if ((pvr >> 16) != 0x0050)
+ return -1;
+
+ k = (immr << 16) | *((ushort *) & immap->im_cpm.cp_dparam[0xB0]);
+ m = 0;
+
+ switch (k) {
+ case 0x20020001:
+ printf ("XPC850xxZT");
+ break;
+ case 0x21000065:
+ printf ("XPC850xxZTA");
+ break;
+ case 0x21010067:
+ printf ("XPC850xxZTB");
+ m = 1;
+ break;
+ case 0x21020068:
+ printf ("XPC850xxZTC");
+ m = 1;
+ break;
+ default:
+ printf ("unknown MPC850 (0x%08x)", k);
+ }
+ printf (" at %s MHz:", strmhz (buf, clock));
+
+ printf (" %u kB I-Cache", checkicache () >> 10);
+ printf (" %u kB D-Cache", checkdcache () >> 10);
+
+ /* lets check and see if we're running on a 850T (or P?) */
+
+ immap->im_cpm.cp_fec.fec_addr_low = 0x12345678;
+ if (immap->im_cpm.cp_fec.fec_addr_low == 0x12345678) {
+ printf (" FEC present");
+ }
+
+ if (!m) {
+ puts (cpu_warning);
+ }
+
+ putc ('\n');
+
+ return 0;
+}
+#else
+#error CPU undefined
+#endif
+/* ------------------------------------------------------------------------- */
+
+int checkcpu (void)
+{
+ DECLARE_GLOBAL_DATA_PTR;
+
+ ulong clock = gd->cpu_clk;
+ uint immr = get_immr (0); /* Return full IMMR contents */
+ uint pvr = get_pvr ();
+
+ puts ("CPU: ");
+
+ /* 850 has PARTNUM 20 */
+ /* 801 has PARTNUM 10 */
+ return check_CPU (clock, pvr, immr);
+}
+
+/* ------------------------------------------------------------------------- */
+/* L1 i-cache */
+/* the standard 860 has 128 sets of 16 bytes in 2 ways (= 4 kB) */
+/* the 860 P (plus) has 256 sets of 16 bytes in 4 ways (= 16 kB) */
+
+int checkicache (void)
+{
+ volatile immap_t *immap = (immap_t *) CFG_IMMR;
+ volatile memctl8xx_t *memctl = &immap->im_memctl;
+ u32 cacheon = rd_ic_cst () & IDC_ENABLED;
+
+#ifdef CONFIG_IP860
+ u32 k = memctl->memc_br1 & ~0x00007fff; /* probe in flash memoryarea */
+#else
+ u32 k = memctl->memc_br0 & ~0x00007fff; /* probe in flash memoryarea */
+#endif
+ u32 m;
+ u32 lines = -1;
+
+ wr_ic_cst (IDC_UNALL);
+ wr_ic_cst (IDC_INVALL);
+ wr_ic_cst (IDC_DISABLE);
+ __asm__ volatile ("isync");
+
+ while (!((m = rd_ic_cst ()) & IDC_CERR2)) {
+ wr_ic_adr (k);
+ wr_ic_cst (IDC_LDLCK);
+ __asm__ volatile ("isync");
+
+ lines++;
+ k += 0x10; /* the number of bytes in a cacheline */
+ }
+
+ wr_ic_cst (IDC_UNALL);
+ wr_ic_cst (IDC_INVALL);
+
+ if (cacheon)
+ wr_ic_cst (IDC_ENABLE);
+ else
+ wr_ic_cst (IDC_DISABLE);
+
+ __asm__ volatile ("isync");
+
+ return lines << 4;
+};
+
+/* ------------------------------------------------------------------------- */
+/* L1 d-cache */
+/* the standard 860 has 128 sets of 16 bytes in 2 ways (= 4 kB) */
+/* the 860 P (plus) has 256 sets of 16 bytes in 2 ways (= 8 kB) */
+/* call with cache disabled */
+
+int checkdcache (void)
+{
+ volatile immap_t *immap = (immap_t *) CFG_IMMR;
+ volatile memctl8xx_t *memctl = &immap->im_memctl;
+ u32 cacheon = rd_dc_cst () & IDC_ENABLED;
+
+#ifdef CONFIG_IP860
+ u32 k = memctl->memc_br1 & ~0x00007fff; /* probe in flash memoryarea */
+#else
+ u32 k = memctl->memc_br0 & ~0x00007fff; /* probe in flash memoryarea */
+#endif
+ u32 m;
+ u32 lines = -1;
+
+ wr_dc_cst (IDC_UNALL);
+ wr_dc_cst (IDC_INVALL);
+ wr_dc_cst (IDC_DISABLE);
+
+ while (!((m = rd_dc_cst ()) & IDC_CERR2)) {
+ wr_dc_adr (k);
+ wr_dc_cst (IDC_LDLCK);
+ lines++;
+ k += 0x10; /* the number of bytes in a cacheline */
+ }
+
+ wr_dc_cst (IDC_UNALL);
+ wr_dc_cst (IDC_INVALL);
+
+ if (cacheon)
+ wr_dc_cst (IDC_ENABLE);
+ else
+ wr_dc_cst (IDC_DISABLE);
+
+ return lines << 4;
+};
+
+/* ------------------------------------------------------------------------- */
+
+void upmconfig (uint upm, uint * table, uint size)
+{
+ uint i;
+ uint addr = 0;
+ volatile immap_t *immap = (immap_t *) CFG_IMMR;
+ volatile memctl8xx_t *memctl = &immap->im_memctl;
+
+ for (i = 0; i < size; i++) {
+ memctl->memc_mdr = table[i]; /* (16-15) */
+ memctl->memc_mcr = addr | upm; /* (16-16) */
+ addr++;
+ }
+}
+
+/* ------------------------------------------------------------------------- */
+
+int do_reset (cmd_tbl_t * cmdtp, bd_t * bd, int flag, int argc,
+ char *argv[])
+{
+ ulong msr, addr;
+
+ volatile immap_t *immap = (immap_t *) CFG_IMMR;
+
+ immap->im_clkrst.car_plprcr |= PLPRCR_CSR; /* Checkstop Reset enable */
+
+ /* Interrupts and MMU off */
+ __asm__ volatile ("mtspr 81, 0");
+ __asm__ volatile ("mfmsr %0":"=r" (msr));
+
+ msr &= ~0x1030;
+ __asm__ volatile ("mtmsr %0"::"r" (msr));
+
+ /*
+ * Trying to execute the next instruction at a non-existing address
+ * should cause a machine check, resulting in reset
+ */
+#ifdef CFG_RESET_ADDRESS
+ addr = CFG_RESET_ADDRESS;
+#else
+ /*
+ * note: when CFG_MONITOR_BASE points to a RAM address, CFG_MONITOR_BASE
+ * - sizeof (ulong) is usually a valid address. Better pick an address
+ * known to be invalid on your system and assign it to CFG_RESET_ADDRESS.
+ * "(ulong)-1" used to be a good choice for many systems...
+ */
+ addr = CFG_MONITOR_BASE - sizeof (ulong);
+#endif
+ ((void (*)(void)) addr) ();
+ return 1;
+}
+
+/* ------------------------------------------------------------------------- */
+
+/*
+ * Get timebase clock frequency (like cpu_clk in Hz)
+ *
+ * See table 15-5 pp. 15-16, and SCCR[RTSEL] pp. 15-27.
+ */
+unsigned long get_tbclk (void)
+{
+ DECLARE_GLOBAL_DATA_PTR;
+
+ volatile immap_t *immr = (volatile immap_t *) CFG_IMMR;
+ ulong oscclk, factor;
+
+ if (immr->im_clkrst.car_sccr & SCCR_TBS) {
+ return (gd->cpu_clk / 16);
+ }
+
+ factor = (((CFG_PLPRCR) & PLPRCR_MF_MSK) >> PLPRCR_MF_SHIFT) + 1;
+
+ oscclk = gd->cpu_clk / factor;
+
+ if ((immr->im_clkrst.car_sccr & SCCR_RTSEL) == 0 || factor > 2) {
+ return (oscclk / 4);
+ }
+ return (oscclk / 16);
+}
+
+/* ------------------------------------------------------------------------- */
+
+#if defined(CONFIG_WATCHDOG)
+void watchdog_reset (void)
+{
+ int re_enable = disable_interrupts ();
+
+ reset_8xx_watchdog ((immap_t *) CFG_IMMR);
+ if (re_enable)
+ enable_interrupts ();
+}
+
+void reset_8xx_watchdog (volatile immap_t * immr)
+{
+# if defined(CONFIG_LWMON)
+ /*
+ * The LWMON board uses a MAX6301 Watchdog
+ * with the trigger pin connected to port PA.7
+ *
+ * (The old board version used a MAX706TESA Watchdog, which
+ * had to be handled exactly the same.)
+ */
+# define WATCHDOG_BIT 0x0100
+ immr->im_ioport.iop_papar &= ~(WATCHDOG_BIT); /* GPIO */
+ immr->im_ioport.iop_padir |= WATCHDOG_BIT; /* Output */
+ immr->im_ioport.iop_paodr &= ~(WATCHDOG_BIT); /* active output */
+
+ immr->im_ioport.iop_padat ^= WATCHDOG_BIT; /* Toggle WDI */
+# else
+ /*
+ * All other boards use the MPC8xx Internal Watchdog
+ */
+ immr->im_siu_conf.sc_swsr = 0x556c; /* write magic1 */
+ immr->im_siu_conf.sc_swsr = 0xaa39; /* write magic2 */
+# endif /* CONFIG_LWMON */
+}
+
+#endif /* CONFIG_WATCHDOG */
+
+/* ------------------------------------------------------------------------- */
--- /dev/null
+/*
+ * (C) Copyright 2000
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <malloc.h>
+#include <commproc.h>
+#include <net.h>
+#include <command.h>
+
+#undef ET_DEBUG
+
+#if (CONFIG_COMMANDS & CFG_CMD_NET) && defined(FEC_ENET)
+
+#ifdef CFG_DISCOVER_PHY
+#include <miiphy.h>
+static void mii_discover_phy(void);
+#endif
+
+/* Ethernet Transmit and Receive Buffers */
+#define DBUF_LENGTH 1520
+
+#define TX_BUF_CNT 2
+
+#define TOUT_LOOP 100
+
+#define PKT_MAXBUF_SIZE 1518
+#define PKT_MINBUF_SIZE 64
+#define PKT_MAXBLR_SIZE 1520
+
+
+static char txbuf[DBUF_LENGTH];
+
+static uint rxIdx; /* index of the current RX buffer */
+static uint txIdx; /* index of the current TX buffer */
+
+/*
+ * FEC Ethernet Tx and Rx buffer descriptors allocated at the
+ * immr->udata_bd address on Dual-Port RAM
+ * Provide for Double Buffering
+ */
+
+typedef volatile struct CommonBufferDescriptor {
+ cbd_t rxbd[PKTBUFSRX]; /* Rx BD */
+ cbd_t txbd[TX_BUF_CNT]; /* Tx BD */
+} RTXBD;
+
+static RTXBD *rtx = NULL;
+
+static int fec_send(struct eth_device* dev, volatile void *packet, int length);
+static int fec_recv(struct eth_device* dev);
+static int fec_init(struct eth_device* dev, bd_t * bd);
+static void fec_halt(struct eth_device* dev);
+
+int fec_initialize(bd_t *bis)
+{
+ struct eth_device* dev;
+
+ dev = (struct eth_device*) malloc(sizeof *dev);
+
+ 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;
+
+ 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);
+
+ /* section 16.9.23.3
+ * Wait for ready
+ */
+ j = 0;
+ while ((rtx->txbd[txIdx].cbd_sc & BD_ENET_TX_READY) && (j<TOUT_LOOP)) {
+ udelay(1);
+ j++;
+ }
+ if (j>=TOUT_LOOP) {
+ printf("TX not ready\n");
+ }
+
+ rtx->txbd[txIdx].cbd_bufaddr = (uint)packet;
+ rtx->txbd[txIdx].cbd_datlen = length;
+ rtx->txbd[txIdx].cbd_sc |= BD_ENET_TX_READY | BD_ENET_TX_LAST;
+ __asm__ ("eieio");
+
+ /* Activate transmit Buffer Descriptor polling */
+ fecp->fec_x_des_active = 0x01000000; /* Descriptor polling active */
+
+ j = 0;
+ while ((rtx->txbd[txIdx].cbd_sc & BD_ENET_TX_READY) && (j<TOUT_LOOP)) {
+#if defined(CONFIG_ICU862)
+ udelay(10);
+#else
+ udelay(1);
+#endif
+ j++;
+ }
+ if (j>=TOUT_LOOP) {
+ printf("TX timeout\n");
+ }
+#ifdef ET_DEBUG
+ printf("%s[%d] %s: cycles: %d status: %x retry cnt: %d\n",
+ __FILE__,__LINE__,__FUNCTION__,j,rtx->txbd[txIdx].cbd_sc,
+ (rtx->txbd[txIdx].cbd_sc & 0x003C)>>2);
+#endif
+ /* return only status bits */;
+ rc = (rtx->txbd[txIdx].cbd_sc & BD_ENET_TX_STATS);
+
+ txIdx = (txIdx + 1) % TX_BUF_CNT;
+
+ return rc;
+}
+
+static int fec_recv(struct eth_device* dev)
+{
+ 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 */
+ }
+
+ length = rtx->rxbd[rxIdx].cbd_datlen;
+
+ if (rtx->rxbd[rxIdx].cbd_sc & 0x003f) {
+#ifdef ET_DEBUG
+ 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);
+ }
+
+ /* 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;
+}
+
+/**************************************************************
+ *
+ * FEC Ethernet Initialization Routine
+ *
+ *************************************************************/
+
+#define FEC_ECNTRL_PINMUX 0x00000004
+#define FEC_ECNTRL_ETHER_EN 0x00000002
+#define FEC_ECNTRL_RESET 0x00000001
+
+#define FEC_RCNTRL_BC_REJ 0x00000010
+#define FEC_RCNTRL_PROM 0x00000008
+#define FEC_RCNTRL_MII_MODE 0x00000004
+#define FEC_RCNTRL_DRT 0x00000002
+#define FEC_RCNTRL_LOOP 0x00000001
+
+#define FEC_TCNTRL_FDEN 0x00000004
+#define FEC_TCNTRL_HBC 0x00000002
+#define FEC_TCNTRL_GTS 0x00000001
+
+#define FEC_RESET_DELAY 50
+
+static int fec_init(struct eth_device* dev, bd_t * bd)
+{
+
+ int i;
+ volatile immap_t *immr = (immap_t *) CFG_IMMR;
+ volatile fec_t *fecp = &(immr->im_cpm.cp_fec);
+
+#if defined(CONFIG_FADS) && defined(CONFIG_MPC860T)
+ /* 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
+ /* 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 0;
+ }
+
+ /* We use strictly polling mode only
+ */
+ fecp->fec_imask = 0;
+
+ /* Clear any pending interrupt
+ */
+ fecp->fec_ievent = 0xffc0;
+
+ /* No need to set the IVEC register */
+
+ /* 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] ) ;
+#undef ea
+
+ /* Clear multicast address hash table
+ */
+ fecp->fec_hash_table_high = 0;
+ fecp->fec_hash_table_low = 0;
+
+ /* Set maximum receive buffer size.
+ */
+ fecp->fec_r_buff_size = PKT_MAXBLR_SIZE;
+
+ /* Set maximum frame length
+ */
+ fecp->fec_r_hash = PKT_MAXBUF_SIZE;
+
+ /*
+ * Setup Buffers and Buffer Desriptors
+ */
+ rxIdx = 0;
+ txIdx = 0;
+
+ if (!rtx) {
+#ifdef CFG_ALLOC_DPRAM
+ rtx = (RTXBD *) (immr->im_cpm.cp_dpmem + dpram_alloc_align(sizeof(RTXBD),8));
+#else
+ rtx = (RTXBD *) (immr->im_cpm.cp_dpmem + CPM_FEC_BASE);
+#endif
+ }
+ /*
+ * Setup Receiver Buffer Descriptors (13.14.24.18)
+ * Settings:
+ * 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_bufaddr = (uint) NetRxPackets[i];
+ }
+ rtx->rxbd[PKTBUFSRX - 1].cbd_sc |= BD_ENET_RX_WRAP;
+
+ /*
+ * Setup Ethernet Transmitter Buffer Descriptors (13.14.24.19)
+ * Settings:
+ * 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_bufaddr = (uint) (&txbuf[0]);
+ }
+ rtx->txbd[TX_BUF_CNT - 1].cbd_sc |= BD_ENET_TX_WRAP;
+
+ /* Set receive and transmit descriptor base
+ */
+ fecp->fec_r_des_start = (unsigned int) (&rtx->rxbd[0]);
+ fecp->fec_x_des_start = (unsigned int) (&rtx->txbd[0]);
+
+ /* Enable MII 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 */
+ fecp->fec_r_cntrl = FEC_RCNTRL_MII_MODE | FEC_RCNTRL_DRT;
+ fecp->fec_x_cntrl = 0;
+#endif
+
+ /* Enable big endian and don't care about SDMA FC.
+ */
+ 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.
+ */
+ fecp->fec_mii_speed = ((bd->bi_busfreq + 4999999) / 5000000) << 1;
+
+#if !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) */
+
+ rxIdx = 0;
+ txIdx = 0;
+
+ /* Now enable the transmit and receive processing
+ */
+ fecp->fec_ecntrl = FEC_ECNTRL_PINMUX | FEC_ECNTRL_ETHER_EN;
+
+#ifdef CFG_DISCOVER_PHY
+ /* wait for the PHY to wake up after reset
+ */
+ mii_discover_phy();
+#endif
+
+ /* And last, try to fill Rx Buffer Descriptors */
+ fecp->fec_r_des_active = 0x01000000; /* Descriptor polling active */
+
+ return 1;
+}
+
+
+
+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
+}
+
+#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;
+
+/* Make MII read/write commands for the FEC.
+*/
+
+#define mk_mii_read(ADDR, REG) (0x60020000 | ((ADDR << 23) | \
+ (REG & 0x1f) << 18))
+
+#define mk_mii_write(ADDR, REG, VAL) (0x50020000 | ((ADDR << 23) | \
+ (REG & 0x1f) << 18) | \
+ (VAL & 0xffff))
+
+/* Interrupt events/masks.
+*/
+#define FEC_ENET_HBERR ((uint)0x80000000) /* Heartbeat error */
+#define FEC_ENET_BABR ((uint)0x40000000) /* Babbling receiver */
+#define FEC_ENET_BABT ((uint)0x20000000) /* Babbling transmitter */
+#define FEC_ENET_GRA ((uint)0x10000000) /* Graceful stop complete */
+#define FEC_ENET_TXF ((uint)0x08000000) /* Full frame transmitted */
+#define FEC_ENET_TXB ((uint)0x04000000) /* A buffer was transmitted */
+#define FEC_ENET_RXF ((uint)0x02000000) /* Full frame received */
+#define FEC_ENET_RXB ((uint)0x01000000) /* A buffer was received */
+#define FEC_ENET_MII ((uint)0x00800000) /* MII interrupt */
+#define FEC_ENET_EBERR ((uint)0x00400000) /* SDMA bus error */
+
+/* PHY identification
+ */
+#define PHY_ID_LXT970 0x78100000 /* LXT970 */
+#define PHY_ID_LXT971 0x001378e0 /* LXT971 and 972 */
+#define PHY_ID_82555 0x02a80150 /* Intel 82555 */
+#define PHY_ID_QS6612 0x01814400 /* QS6612 */
+#define PHY_ID_AMD79C784 0x00225610 /* AMD 79C784 */
+#define PHY_ID_LSI80225 0x0016f870 /* LSI 80225 */
+#define PHY_ID_LSI80225B 0x0016f880 /* LSI 80225/B */
+
+
+/* send command to phy using mii, wait for result */
+static uint
+mii_send(uint mii_cmd)
+{
+ uint mii_reply;
+ volatile fec_t *ep;
+
+ 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 */
+ mii_reply = ep->fec_mii_data; /* result from phy */
+ ep->fec_ievent = FEC_ENET_MII; /* clear MII complete */
+#if 0
+ printf("%s[%d] %s: sent=0x%8.8x, reply=0x%8.8x\n",
+ __FILE__,__LINE__,__FUNCTION__,mii_cmd,mii_reply);
+#endif
+ return (mii_reply & 0xffff); /* data read from phy */
+}
+#endif /* CFG_DISCOVER_PHY || (CONFIG_COMMANDS & CFG_CMD_MII) */
+
+#if defined(CFG_DISCOVER_PHY)
+static void
+mii_discover_phy(void)
+{
+#define MAX_PHY_PASSES 11
+ uint phyno;
+ int pass;
+
+ phyaddr = -1; /* didn't find a PHY yet */
+ for (pass = 1; pass <= MAX_PHY_PASSES && phyaddr < 0; ++pass) {
+ if (pass > 1) {
+ /* PHY may need more time to recover from reset.
+ * The LXT970 needs 50ms typical, no maximum is
+ * specified, so wait 10ms before try again.
+ * With 11 passes this gives it 100ms to wake up.
+ */
+ udelay(10000); /* wait 10ms */
+ }
+ for (phyno = 0; phyno < 32 && phyaddr < 0; ++phyno) {
+ phytype = mii_send(mk_mii_read(phyno, PHY_PHYIDR1));
+#ifdef ET_DEBUG
+ printf("PHY type 0x%x pass %d type ", phytype, pass);
+#endif
+ if (phytype != 0xffff) {
+ phyaddr = phyno;
+ phytype <<= 16;
+ phytype |= mii_send(mk_mii_read(phyno,
+ PHY_PHYIDR2));
+
+#ifdef ET_DEBUG
+ printf("PHY @ 0x%x pass %d type ",phyno,pass);
+ switch (phytype & 0xfffffff0) {
+ case PHY_ID_LXT970:
+ printf("LXT970\n");
+ break;
+ case PHY_ID_LXT971:
+ printf("LXT971\n");
+ break;
+ case PHY_ID_82555:
+ printf("82555\n");
+ break;
+ case PHY_ID_QS6612:
+ printf("QS6612\n");
+ break;
+ case PHY_ID_AMD79C784:
+ printf("AMD79C784\n");
+ break;
+ case PHY_ID_LSI80225B:
+ printf("LSI L80225/B\n");
+ break;
+ default:
+ printf("0x%08x\n", phytype);
+ break;
+ }
+#endif
+ }
+ }
+ }
+ if (phyaddr < 0) {
+ printf("No PHY device found.\n");
+ }
+}
+#endif /* CFG_DISCOVER_PHY */
+
+#if (CONFIG_COMMANDS & CFG_CMD_MII) && !defined(CONFIG_BITBANGMII)
+
+static int mii_init_done = 0;
+
+/****************************************************************************
+ * mii_init -- Initialize the MII for MII command without ethernet
+ * This function is a subset of eth_init
+ ****************************************************************************
+ */
+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;
+
+ if (mii_init_done != 0) {
+ 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;
+ }
+
+ /* We use strictly polling mode only
+ */
+ fecp->fec_imask = 0;
+
+ /* Clear any pending interrupt
+ */
+ 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_busfreq + 4999999) / 5000000) << 1;
+
+#if !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)
+
+ /* 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
+ *
+ * FIXME: These routines are expected to return 0 on success, but mii_send
+ * does _not_ return an error code. Maybe 0xFFFF means error, i.e.
+ * no PHY connected...
+ * For now always return 0.
+ * FIXME: These routines only work after calling eth_init() at least once!
+ * Otherwise they hang in mii_send() !!! Sorry!
+ *****************************************************************************/
+
+int miiphy_read(unsigned char addr, unsigned char reg, unsigned short *value)
+{
+ short rdreg; /* register working value */
+
+#ifdef MII_DEBUG
+ printf ("miiphy_read(0x%x) @ 0x%x = ", reg, addr);
+#endif
+ 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)*/
+
+#endif /* CFG_CMD_NET, FEC_ENET */
--- /dev/null
+/*
+ * Copyright (c) 2001 Navin Boppuri / Prashant Patel
+ * <nboppuri@trinetcommunication.com>,
+ * <pmpatel@trinetcommunication.com>
+ * Copyright (c) 2001 Gerd Mennchen <Gerd.Mennchen@icn.siemens.de>
+ * Copyright (c) 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
+ */
+
+/*
+ * MPC8xx CPM SPI interface.
+ *
+ * Parts of this code are probably not portable and/or specific to
+ * the board which I used for the tests. Please send fixes/complaints
+ * to wd@denx.de
+ *
+ */
+
+#include <common.h>
+#include <mpc8xx.h>
+#include <commproc.h>
+#include <linux/ctype.h>
+#include <malloc.h>
+#include <post.h>
+#include <net.h>
+
+#if (defined(CONFIG_SPI)) || (CONFIG_POST & CFG_POST_SPI)
+
+/* Warning:
+ * You cannot enable DEBUG for early system initalization, i. e. when
+ * this driver is used to read environment parameters like "baudrate"
+ * from EEPROM which are used to initialize the serial port which is
+ * needed to print the debug messages...
+ */
+#undef DEBUG
+
+#define SPI_EEPROM_WREN 0x06
+#define SPI_EEPROM_RDSR 0x05
+#define SPI_EEPROM_READ 0x03
+#define SPI_EEPROM_WRITE 0x02
+
+/* ---------------------------------------------------------------
+ * Offset for initial SPI buffers in DPRAM:
+ * We need a 520 byte scratch DPRAM area to use at an early stage.
+ * It is used between the two initialization calls (spi_init_f()
+ * and spi_init_r()).
+ * The value 0xb00 makes it far enough from the start of the data
+ * area (as well as from the stack pointer).
+ * --------------------------------------------------------------- */
+#ifndef CFG_SPI_INIT_OFFSET
+#define CFG_SPI_INIT_OFFSET 0xB00
+#endif
+
+#ifdef DEBUG
+
+#define DPRINT(a) printf a;
+/* -----------------------------------------------
+ * Helper functions to peek into tx and rx buffers
+ * ----------------------------------------------- */
+static const char * const hex_digit = "0123456789ABCDEF";
+
+static char quickhex (int i)
+{
+ return hex_digit[i];
+}
+
+static void memdump (void *pv, int num)
+{
+ int i;
+ unsigned char *pc = (unsigned char *) pv;
+
+ for (i = 0; i < num; i++)
+ printf ("%c%c ", quickhex (pc[i] >> 4), quickhex (pc[i] & 0x0f));
+ printf ("\t");
+ for (i = 0; i < num; i++)
+ printf ("%c", isprint (pc[i]) ? pc[i] : '.');
+ printf ("\n");
+}
+#else /* !DEBUG */
+
+#define DPRINT(a)
+
+#endif /* DEBUG */
+
+/* -------------------
+ * Function prototypes
+ * ------------------- */
+void spi_init (void);
+
+ssize_t spi_read (uchar *, int, uchar *, int);
+ssize_t spi_write (uchar *, int, uchar *, int);
+ssize_t spi_xfer (size_t);
+
+/* -------------------
+ * Variables
+ * ------------------- */
+
+#define MAX_BUFFER 0x104
+
+/* ----------------------------------------------------------------------
+ * Initially we place the RX and TX buffers at a fixed location in DPRAM!
+ * ---------------------------------------------------------------------- */
+static uchar *rxbuf =
+ (uchar *)&((cpm8xx_t *)&((immap_t *)CFG_IMMR)->im_cpm)->cp_dpmem
+ [CFG_SPI_INIT_OFFSET];
+static uchar *txbuf =
+ (uchar *)&((cpm8xx_t *)&((immap_t *)CFG_IMMR)->im_cpm)->cp_dpmem
+ [CFG_SPI_INIT_OFFSET+MAX_BUFFER];
+
+/* **************************************************************************
+ *
+ * Function: spi_init_f
+ *
+ * Description: Init SPI-Controller (ROM part)
+ *
+ * return: ---
+ *
+ * *********************************************************************** */
+void spi_init_f (void)
+{
+ unsigned int dpaddr;
+
+ volatile spi_t *spi;
+ volatile immap_t *immr;
+ volatile cpic8xx_t *cpi;
+ volatile cpm8xx_t *cp;
+ volatile iop8xx_t *iop;
+ volatile cbd_t *tbdf, *rbdf;
+
+ immr = (immap_t *) CFG_IMMR;
+ cpi = (cpic8xx_t *)&immr->im_cpic;
+ iop = (iop8xx_t *) &immr->im_ioport;
+ cp = (cpm8xx_t *) &immr->im_cpm;
+
+#ifdef CFG_SPI_UCODE_PATCH
+ spi = (spi_t *)&cp->cp_dpmem[spi->spi_rpbase];
+#else
+ spi = (spi_t *)&cp->cp_dparam[PROFF_SPI];
+ /* Disable relocation */
+ spi->spi_rpbase = 0;
+#endif
+
+/* 1 */
+ /* ------------------------------------------------
+ * Initialize Port B SPI pins -> page 34-8 MPC860UM
+ * (we are only in Master Mode !)
+ * ------------------------------------------------ */
+
+ /* --------------------------------------------
+ * GPIO or per. Function
+ * PBPAR[28] = 1 [0x00000008] -> PERI: (SPIMISO)
+ * PBPAR[29] = 1 [0x00000004] -> PERI: (SPIMOSI)
+ * PBPAR[30] = 1 [0x00000002] -> PERI: (SPICLK)
+ * PBPAR[31] = 0 [0x00000001] -> GPIO: (CS for PCUE/CCM-EEPROM)
+ * -------------------------------------------- */
+ cp->cp_pbpar |= 0x0000000E; /* set bits */
+ cp->cp_pbpar &= ~0x00000001; /* reset bit */
+
+ /* ----------------------------------------------
+ * In/Out or per. Function 0/1
+ * PBDIR[28] = 1 [0x00000008] -> PERI1: SPIMISO
+ * PBDIR[29] = 1 [0x00000004] -> PERI1: SPIMOSI
+ * PBDIR[30] = 1 [0x00000002] -> PERI1: SPICLK
+ * PBDIR[31] = 1 [0x00000001] -> GPIO OUT: CS for PCUE/CCM-EEPROM
+ * ---------------------------------------------- */
+ cp->cp_pbdir |= 0x0000000F;
+
+ /* ----------------------------------------------
+ * open drain or active output
+ * PBODR[28] = 1 [0x00000008] -> open drain: SPIMISO
+ * PBODR[29] = 0 [0x00000004] -> active output SPIMOSI
+ * PBODR[30] = 0 [0x00000002] -> active output: SPICLK
+ * PBODR[31] = 0 [0x00000001] -> active output: GPIO OUT: CS for PCUE/CCM
+ * ---------------------------------------------- */
+
+ cp->cp_pbodr |= 0x00000008;
+ cp->cp_pbodr &= ~0x00000007;
+
+ /* Initialize the parameter ram.
+ * We need to make sure many things are initialized to zero
+ */
+ spi->spi_rstate = 0;
+ spi->spi_rdp = 0;
+ spi->spi_rbptr = 0;
+ spi->spi_rbc = 0;
+ spi->spi_rxtmp = 0;
+ spi->spi_tstate = 0;
+ spi->spi_tdp = 0;
+ spi->spi_tbptr = 0;
+ spi->spi_tbc = 0;
+ spi->spi_txtmp = 0;
+
+ /* Allocate space for one transmit and one receive buffer
+ * descriptor in the DP ram
+ */
+#ifdef CFG_ALLOC_DPRAM
+ dpaddr = dpram_alloc_align (sizeof(cbd_t)*2, 8);
+#else
+ dpaddr = CPM_SPI_BASE;
+#endif
+
+/* 3 */
+ /* Set up the SPI parameters in the parameter ram */
+ spi->spi_rbase = dpaddr;
+ spi->spi_tbase = dpaddr + sizeof (cbd_t);
+
+ /***********IMPORTANT******************/
+
+ /*
+ * Setting transmit and receive buffer descriptor pointers
+ * initially to rbase and tbase. Only the microcode patches
+ * documentation talks about initializing this pointer. This
+ * is missing from the sample I2C driver. If you dont
+ * initialize these pointers, the kernel hangs.
+ */
+ spi->spi_rbptr = spi->spi_rbase;
+ spi->spi_tbptr = spi->spi_tbase;
+
+/* 4 */
+#ifdef CFG_SPI_UCODE_PATCH
+ /*
+ * Initialize required parameters if using microcode patch.
+ */
+ spi->spi_rstate = 0;
+ spi->spi_tstate = 0;
+#else
+ /* Init SPI Tx + Rx Parameters */
+ while (cp->cp_cpcr & CPM_CR_FLG)
+ ;
+ cp->cp_cpcr = mk_cr_cmd(CPM_CR_CH_SPI, CPM_CR_INIT_TRX) | CPM_CR_FLG;
+ while (cp->cp_cpcr & CPM_CR_FLG)
+ ;
+#endif /* CFG_SPI_UCODE_PATCH */
+
+/* 5 */
+ /* Set SDMA configuration register */
+ immr->im_siu_conf.sc_sdcr = 0x0001;
+
+/* 6 */
+ /* Set to big endian. */
+ spi->spi_tfcr = SMC_EB;
+ spi->spi_rfcr = SMC_EB;
+
+/* 7 */
+ /* Set maximum receive size. */
+ spi->spi_mrblr = MAX_BUFFER;
+
+/* 8 + 9 */
+ /* tx and rx buffer descriptors */
+ tbdf = (cbd_t *) & cp->cp_dpmem[spi->spi_tbase];
+ rbdf = (cbd_t *) & cp->cp_dpmem[spi->spi_rbase];
+
+ tbdf->cbd_sc &= ~BD_SC_READY;
+ rbdf->cbd_sc &= ~BD_SC_EMPTY;
+
+ /* Set the bd's rx and tx buffer address pointers */
+ rbdf->cbd_bufaddr = (ulong) rxbuf;
+ tbdf->cbd_bufaddr = (ulong) txbuf;
+
+/* 10 + 11 */
+ cp->cp_spim = 0; /* Mask all SPI events */
+ cp->cp_spie = SPI_EMASK; /* Clear all SPI events */
+
+ return;
+}
+
+/* **************************************************************************
+ *
+ * Function: spi_init_r
+ *
+ * Description: Init SPI-Controller (RAM part) -
+ * The malloc engine is ready and we can move our buffers to
+ * normal RAM
+ *
+ * return: ---
+ *
+ * *********************************************************************** */
+void spi_init_r (void)
+{
+ volatile cpm8xx_t *cp;
+ volatile spi_t *spi;
+ volatile immap_t *immr;
+ volatile cbd_t *tbdf, *rbdf;
+
+ immr = (immap_t *) CFG_IMMR;
+ cp = (cpm8xx_t *) &immr->im_cpm;
+
+#ifdef CFG_SPI_UCODE_PATCH
+ spi = (spi_t *)&cp->cp_dpmem[spi->spi_rpbase];
+#else
+ spi = (spi_t *)&cp->cp_dparam[PROFF_SPI];
+ /* Disable relocation */
+ spi->spi_rpbase = 0;
+#endif
+
+ /* tx and rx buffer descriptors */
+ tbdf = (cbd_t *) & cp->cp_dpmem[spi->spi_tbase];
+ rbdf = (cbd_t *) & cp->cp_dpmem[spi->spi_rbase];
+
+ /* Allocate memory for RX and TX buffers */
+ rxbuf = (uchar *) malloc (MAX_BUFFER);
+ txbuf = (uchar *) malloc (MAX_BUFFER);
+
+ rbdf->cbd_bufaddr = (ulong) rxbuf;
+ tbdf->cbd_bufaddr = (ulong) txbuf;
+
+ return;
+}
+
+/****************************************************************************
+ * Function: spi_write
+ **************************************************************************** */
+ssize_t spi_write (uchar *addr, int alen, uchar *buffer, int len)
+{
+ int i;
+
+ memset(rxbuf, 0, MAX_BUFFER);
+ memset(txbuf, 0, MAX_BUFFER);
+ *txbuf = SPI_EEPROM_WREN; /* write enable */
+ spi_xfer(1);
+ memcpy(txbuf, addr, alen);
+ *txbuf = SPI_EEPROM_WRITE; /* WRITE memory array */
+ memcpy(alen + txbuf, buffer, len);
+ spi_xfer(alen + len);
+ /* ignore received data */
+ for (i = 0; i < 1000; i++) {
+ *txbuf = SPI_EEPROM_RDSR; /* read status */
+ txbuf[1] = 0;
+ spi_xfer(2);
+ if (!(rxbuf[1] & 1)) {
+ break;
+ }
+ udelay(1000);
+ }
+ if (i >= 1000) {
+ printf ("*** spi_write: Time out while writing!\n");
+ }
+
+ return len;
+}
+
+/****************************************************************************
+ * Function: spi_read
+ **************************************************************************** */
+ssize_t spi_read (uchar *addr, int alen, uchar *buffer, int len)
+{
+ memset(rxbuf, 0, MAX_BUFFER);
+ memset(txbuf, 0, MAX_BUFFER);
+ memcpy(txbuf, addr, alen);
+ *txbuf = SPI_EEPROM_READ; /* READ memory array */
+
+ /*
+ * There is a bug in 860T (?) that cuts the last byte of input
+ * if we're reading into DPRAM. The solution we choose here is
+ * to always read len+1 bytes (we have one extra byte at the
+ * end of the buffer).
+ */
+ spi_xfer(alen + len + 1);
+ memcpy(buffer, alen + rxbuf, len);
+
+ return len;
+}
+
+/****************************************************************************
+ * Function: spi_xfer
+ **************************************************************************** */
+ssize_t spi_xfer (size_t count)
+{
+ volatile immap_t *immr;
+ volatile cpm8xx_t *cp;
+ volatile spi_t *spi;
+ cbd_t *tbdf, *rbdf;
+ ushort loop;
+ int tm;
+
+ DPRINT (("*** spi_xfer entered ***\n"));
+
+ immr = (immap_t *) CFG_IMMR;
+ cp = (cpm8xx_t *) &immr->im_cpm;
+
+#ifdef CFG_SPI_UCODE_PATCH
+ spi = (spi_t *)&cp->cp_dpmem[spi->spi_rpbase];
+#else
+ spi = (spi_t *)&cp->cp_dparam[PROFF_SPI];
+ /* Disable relocation */
+ spi->spi_rpbase = 0;
+#endif
+
+ tbdf = (cbd_t *) & cp->cp_dpmem[spi->spi_tbase];
+ rbdf = (cbd_t *) & cp->cp_dpmem[spi->spi_rbase];
+
+ /* Set CS for device */
+ cp->cp_pbdat &= ~0x0001;
+
+ /* Setting tx bd status and data length */
+ tbdf->cbd_sc = BD_SC_READY | BD_SC_LAST | BD_SC_WRAP;
+ tbdf->cbd_datlen = count;
+
+ DPRINT (("*** spi_xfer: Bytes to be xferred: %d ***\n",
+ tbdf->cbd_datlen));
+
+ /* Setting rx bd status and data length */
+ rbdf->cbd_sc = BD_SC_EMPTY | BD_SC_WRAP;
+ rbdf->cbd_datlen = 0; /* rx length has no significance */
+
+ loop = cp->cp_spmode & SPMODE_LOOP;
+ cp->cp_spmode = /*SPMODE_DIV16 |*/ /* BRG/16 mode not used here */
+ loop |
+ SPMODE_REV |
+ SPMODE_MSTR |
+ SPMODE_EN |
+ SPMODE_LEN(8) | /* 8 Bits per char */
+ SPMODE_PM(0x8) ; /* medium speed */
+ cp->cp_spim = 0; /* Mask all SPI events */
+ cp->cp_spie = SPI_EMASK; /* Clear all SPI events */
+
+ /* start spi transfer */
+ DPRINT (("*** spi_xfer: Performing transfer ...\n"));
+ cp->cp_spcom |= SPI_STR; /* Start transmit */
+
+ /* --------------------------------
+ * Wait for SPI transmit to get out
+ * or time out (1 second = 1000 ms)
+ * -------------------------------- */
+ for (tm=0; tm<1000; ++tm) {
+ if (cp->cp_spie & SPI_TXB) { /* Tx Buffer Empty */
+ DPRINT (("*** spi_xfer: Tx buffer empty\n"));
+ break;
+ }
+ if ((tbdf->cbd_sc & BD_SC_READY) == 0) {
+ DPRINT (("*** spi_xfer: Tx BD done\n"));
+ break;
+ }
+ udelay (1000);
+ }
+ if (tm >= 1000) {
+ printf ("*** spi_xfer: Time out while xferring to/from SPI!\n");
+ }
+ DPRINT (("*** spi_xfer: ... transfer ended\n"));
+
+#ifdef DEBUG
+ printf ("\nspi_xfer: txbuf after xfer\n");
+ memdump ((void *) txbuf, 16); /* dump of txbuf before transmit */
+ printf ("spi_xfer: rxbuf after xfer\n");
+ memdump ((void *) rxbuf, 16); /* dump of rxbuf after transmit */
+ printf ("\n");
+#endif
+
+ /* Clear CS for device */
+ cp->cp_pbdat |= 0x0001;
+
+ return count;
+}
+#endif /* CONFIG_SPI || (CONFIG_POST & CFG_POST_SPI) */
+
+/*
+ * SPI test
+ *
+ * The Serial Peripheral Interface (SPI) is tested in the local loopback mode.
+ * The interface is configured accordingly and several packets
+ * are transfered. The configurable test parameters are:
+ * TEST_MIN_LENGTH - minimum size of packet to transfer
+ * TEST_MAX_LENGTH - maximum size of packet to transfer
+ * TEST_NUM - number of tests
+ */
+
+#if CONFIG_POST & CFG_POST_SPI
+
+#define TEST_MIN_LENGTH 1
+#define TEST_MAX_LENGTH MAX_BUFFER
+#define TEST_NUM 1
+
+static void packet_fill (char * packet, int length)
+{
+ char c = (char) length;
+ int i;
+
+ for (i = 0; i < length; i++)
+ {
+ packet[i] = c++;
+ }
+}
+
+static int packet_check (char * packet, int length)
+{
+ char c = (char) length;
+ int i;
+
+ for (i = 0; i < length; i++)
+ {
+ if (packet[i] != c++) return -1;
+ }
+
+ return 0;
+}
+
+int spi_post_test (int flags)
+{
+ DECLARE_GLOBAL_DATA_PTR;
+
+ int res = -1;
+ volatile immap_t *immr = (immap_t *) CFG_IMMR;
+ volatile cpm8xx_t *cp = (cpm8xx_t *) &immr->im_cpm;
+ int i;
+ int l;
+
+ spi_init_f();
+ spi_init_r();
+
+ cp->cp_spmode |= SPMODE_LOOP;
+
+ for (i = 0; i < TEST_NUM; i++)
+ {
+ for (l = TEST_MIN_LENGTH; l <= TEST_MAX_LENGTH; l += 8)
+ {
+ packet_fill(txbuf, l);
+
+ spi_xfer(l);
+
+ if (packet_check(rxbuf, l) < 0)
+ {
+ goto Done;
+ }
+ }
+ }
+
+ res = 0;
+
+ Done:
+
+ cp->cp_spmode &= ~SPMODE_LOOP;
+
+ /*
+ * SCC2 Ethernet parameter RAM space overlaps
+ * the SPI parameter RAM space. So we need to restore
+ * the SCC2 configuration if it is used by UART or Ethernet.
+ */
+
+#if defined(CONFIG_8xx_CONS_SCC2)
+ serial_init();
+#endif
+
+#if defined(SCC_ENET) && (SCC_ENET == 1)
+ eth_init(gd->bd);
+#endif
+
+ if (res != 0)
+ {
+ post_log("SPI test failed\n");
+ }
+
+ return res;
+}
+#endif /* CONFIG_POST & CFG_POST_SPI */
--- /dev/null
+/*-----------------------------------------------------------------------------+
+ *
+ * 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
+ *-----------------------------------------------------------------------------*/
+/*-----------------------------------------------------------------------------+
+ *
+ * File Name: enetemac.c
+ *
+ * Function: Device driver for the ethernet EMAC3 macro on the 405GP.
+ *
+ * Author: Mark Wisner
+ *
+ * Change Activity-
+ *
+ * Date Description of Change BY
+ * --------- --------------------- ---
+ * 05-May-99 Created MKW
+ * 27-Jun-99 Clean up JWB
+ * 16-Jul-99 Added MAL error recovery and better IP packet handling MKW
+ * 29-Jul-99 Added Full duplex support MKW
+ * 06-Aug-99 Changed names for Mal CR reg MKW
+ * 23-Aug-99 Turned off SYE when running at 10Mbs MKW
+ * 24-Aug-99 Marked descriptor empty after call_xlc MKW
+ * 07-Sep-99 Set MAL RX buffer size reg to ENET_MAX_MTU_ALIGNED / 16 MCG
+ * to avoid chaining maximum sized packets. Push starting
+ * RX descriptor address up to the next cache line boundary.
+ * 16-Jan-00 Added support for booting with IP of 0x0 MKW
+ * 15-Mar-00 Updated enetInit() to enable broadcast addresses in the
+ * EMAC_RXM register. JWB
+ * 12-Mar-01 anne-sophie.harnois@nextream.fr
+ * - Variables are compatible with those already defined in
+ * include/net.h
+ * - Receive buffer descriptor ring is used to send buffers
+ * to the user
+ * - Info print about send/received/handled packet number if
+ * INFO_405_ENET is set
+ * 17-Apr-01 stefan.roese@esd-electronics.com
+ * - MAL reset in "eth_halt" included
+ * - Enet speed and duplex output now in one line
+ * 08-May-01 stefan.roese@esd-electronics.com
+ * - MAL error handling added (eth_init called again)
+ * 13-Nov-01 stefan.roese@esd-electronics.com
+ * - Set IST bit in EMAC_M1 reg upon 100MBit or full duplex
+ * 04-Jan-02 stefan.roese@esd-electronics.com
+ * - Wait for PHY auto negotiation to complete added
+ * 06-Feb-02 stefan.roese@esd-electronics.com
+ * - Bug fixed in waiting for auto negotiation to complete
+ * 26-Feb-02 stefan.roese@esd-electronics.com
+ * - rx and tx buffer descriptors now allocated (no fixed address
+ * used anymore)
+ * 17-Jun-02 stefan.roese@esd-electronics.com
+ * - MAL error debug printf 'M' removed (rx de interrupt may
+ * occur upon many incoming packets with only 4 rx buffers).
+ *-----------------------------------------------------------------------------*/
+
+#include <common.h>
+#include <asm/processor.h>
+#include <ppc4xx.h>
+#include <commproc.h>
+#include <405gp_enet.h>
+#include <405_mal.h>
+#include <miiphy.h>
+#include <net.h>
+#include <malloc.h>
+#include "vecnum.h"
+
+#if defined(CONFIG_405GP) || defined(CONFIG_440)
+
+#define EMAC_RESET_TIMEOUT 1000 /* 1000 ms reset timeout */
+#define PHY_AUTONEGOTIATE_TIMEOUT 2000 /* 2000 ms autonegotiate timeout */
+
+#define NUM_TX_BUFF 1
+/* AS.HARNOIS
+ * Use PKTBUFSRX (include/net.h) instead of setting NUM_RX_BUFF again
+ * These both variables are used to define the same thing!
+ * #define NUM_RX_BUFF 4
+ */
+#define NUM_RX_BUFF PKTBUFSRX
+
+/* Ethernet Transmit and Receive Buffers */
+/* AS.HARNOIS
+ * In the same way ENET_MAX_MTU and ENET_MAX_MTU_ALIGNED are set from
+ * PKTSIZE and PKTSIZE_ALIGN (include/net.h)
+ */
+#define ENET_MAX_MTU PKTSIZE
+#define ENET_MAX_MTU_ALIGNED PKTSIZE_ALIGN
+
+static char *txbuf_ptr;
+
+/* define the number of channels implemented */
+#define EMAC_RXCHL 1
+#define EMAC_TXCHL 1
+
+/*-----------------------------------------------------------------------------+
+ * Defines for MAL/EMAC interrupt conditions as reported in the UIC (Universal
+ * Interrupt Controller).
+ *-----------------------------------------------------------------------------*/
+#define MAL_UIC_ERR ( UIC_MAL_SERR | UIC_MAL_TXDE | UIC_MAL_RXDE)
+#define MAL_UIC_DEF (UIC_MAL_RXEOB | MAL_UIC_ERR)
+#define EMAC_UIC_DEF UIC_ENET
+
+/*-----------------------------------------------------------------------------+
+ * Global variables. TX and RX descriptors and buffers.
+ *-----------------------------------------------------------------------------*/
+static volatile mal_desc_t *tx;
+static volatile mal_desc_t *rx;
+static mal_desc_t *alloc_tx_buf = NULL;
+static mal_desc_t *alloc_rx_buf = NULL;
+
+/* IER globals */
+static unsigned long emac_ier;
+static unsigned long mal_ier;
+
+
+/* Statistic Areas */
+#define MAX_ERR_LOG 10
+struct emac_stats {
+ int data_len_err;
+ int rx_frames;
+ int rx;
+ int rx_prot_err;
+};
+
+static struct stats { /* Statistic Block */
+ struct emac_stats emac;
+ int int_err;
+ short tx_err_log[MAX_ERR_LOG];
+ short rx_err_log[MAX_ERR_LOG];
+} stats;
+
+static int first_init = 0;
+
+static int tx_err_index = 0; /* Transmit Error Index for tx_err_log */
+static int rx_err_index = 0; /* Receive Error Index for rx_err_log */
+
+static int rx_slot = 0; /* MAL Receive Slot */
+static int rx_i_index = 0; /* Receive Interrupt Queue Index */
+static int rx_u_index = 0; /* Receive User Queue Index */
+static int rx_ready[NUM_RX_BUFF]; /* Receive Ready Queue */
+
+static int tx_slot = 0; /* MAL Transmit Slot */
+static int tx_i_index = 0; /* Transmit Interrupt Queue Index */
+static int tx_u_index = 0; /* Transmit User Queue Index */
+static int tx_run[NUM_TX_BUFF]; /* Transmit Running Queue */
+
+#undef INFO_405_ENET 1
+#ifdef INFO_405_ENET
+static int packetSent = 0;
+static int packetReceived = 0;
+static int packetHandled = 0;
+#endif
+
+static char emac_hwd_addr[ENET_ADDR_LENGTH];
+
+static bd_t *bis_save = NULL; /* for eth_init upon mal error */
+
+static int is_receiving = 0; /* sync with eth interrupt */
+static int print_speed = 1; /* print speed message upon start */
+
+static void enet_rcv (unsigned long malisr);
+
+/*-----------------------------------------------------------------------------+
+ * Prototypes and externals.
+ *-----------------------------------------------------------------------------*/
+void mal_err (unsigned long isr, unsigned long uic, unsigned long mal_def,
+ unsigned long mal_errr);
+void emac_err (unsigned long isr);
+
+
+void eth_halt (void)
+{
+ mtdcr (malier, 0x00000000); /* disable mal interrupts */
+ out32 (EMAC_IER, 0x00000000); /* disable emac interrupts */
+
+ /* 1st reset MAL */
+ mtdcr (malmcr, MAL_CR_MMSR);
+
+ /* wait for reset */
+ while (mfdcr (malmcr) & MAL_CR_MMSR) {
+ };
+
+ /* EMAC RESET */
+ out32 (EMAC_M0, EMAC_M0_SRST);
+
+ print_speed = 1; /* print speed message again next time */
+}
+
+
+int eth_init (bd_t * bis)
+{
+ int i;
+ unsigned long reg;
+ unsigned long msr;
+ unsigned long speed;
+ unsigned long duplex;
+ unsigned mode_reg;
+ unsigned short reg_short;
+
+ msr = mfmsr ();
+ mtmsr (msr & ~(MSR_EE)); /* disable interrupts */
+
+#ifdef INFO_405_ENET
+ /* AS.HARNOIS
+ * We should have :
+ * packetHandled <= packetReceived <= packetHandled+PKTBUFSRX
+ * In the most cases packetHandled = packetReceived, but it
+ * is possible that new packets (without relationship with
+ * current transfer) have got the time to arrived before
+ * netloop calls eth_halt
+ */
+ printf ("About preceeding transfer:\n"
+ "- Sent packet number %d\n"
+ "- Received packet number %d\n"
+ "- Handled packet number %d\n",
+ packetSent, packetReceived, packetHandled);
+ packetSent = 0;
+ packetReceived = 0;
+ packetHandled = 0;
+#endif
+
+ /* MAL RESET */
+ mtdcr (malmcr, MAL_CR_MMSR);
+ /* wait for reset */
+ while (mfdcr (malmcr) & MAL_CR_MMSR) {
+ };
+
+ tx_err_index = 0; /* Transmit Error Index for tx_err_log */
+ rx_err_index = 0; /* Receive Error Index for rx_err_log */
+
+ rx_slot = 0; /* MAL Receive Slot */
+ rx_i_index = 0; /* Receive Interrupt Queue Index */
+ rx_u_index = 0; /* Receive User Queue Index */
+
+ tx_slot = 0; /* MAL Transmit Slot */
+ tx_i_index = 0; /* Transmit Interrupt Queue Index */
+ tx_u_index = 0; /* Transmit User Queue Index */
+
+#if defined(CONFIG_440)
+ /* set RMII mode */
+ out32 (ZMII_FER, ZMII_RMII | ZMII_MDI0);
+#endif /* CONFIG_440 */
+
+ /* EMAC RESET */
+ out32 (EMAC_M0, EMAC_M0_SRST);
+
+ /* wait for PHY to complete auto negotiation */
+ reg_short = 0;
+#ifndef CONFIG_CS8952_PHY
+ miiphy_read (CONFIG_PHY_ADDR, PHY_BMSR, ®_short);
+
+ /*
+ * Wait if PHY is able of autonegotiation and autonegotiation is not complete
+ */
+ if ((reg_short & PHY_BMSR_AUTN_ABLE)
+ && !(reg_short & PHY_BMSR_AUTN_COMP)) {
+ puts ("Waiting for PHY auto negotiation to complete");
+ i = 0;
+ while (!(reg_short & PHY_BMSR_AUTN_COMP)) {
+ if ((i++ % 100) == 0)
+ putc ('.');
+ udelay (10000); /* 10 ms */
+ miiphy_read (CONFIG_PHY_ADDR, PHY_BMSR, ®_short);
+
+ /*
+ * Timeout reached ?
+ */
+ if (i * 10 > PHY_AUTONEGOTIATE_TIMEOUT) {
+ puts (" TIMEOUT !\n");
+ break;
+ }
+ }
+ puts (" done\n");
+ udelay (500000); /* another 500 ms (results in faster booting) */
+ }
+#endif
+ speed = miiphy_speed (CONFIG_PHY_ADDR);
+ duplex = miiphy_duplex (CONFIG_PHY_ADDR);
+ if (print_speed) {
+ print_speed = 0;
+ printf ("ENET Speed is %d Mbps - %s duplex connection\n",
+ (int) speed, (duplex == HALF) ? "HALF" : "FULL");
+ }
+
+ /* set the Mal configuration reg */
+#if defined(CONFIG_440)
+ /* Errata 1.12: MAL_1 -- Disable MAL bursting */
+ if( get_pvr() == PVR_440GP_RB )
+ mtdcr (malmcr, MAL_CR_OPBBL | MAL_CR_LEA | MAL_CR_PLBLT_DEFAULT);
+ else
+#else
+ mtdcr (malmcr, MAL_CR_PLBB | MAL_CR_OPBBL | MAL_CR_LEA | MAL_CR_PLBLT_DEFAULT);
+#endif
+
+ /* Free "old" buffers */
+ if (alloc_tx_buf) free(alloc_tx_buf);
+ if (alloc_rx_buf) free(alloc_rx_buf);
+
+ /*
+ * Malloc MAL buffer desciptors, make sure they are
+ * aligned on cache line boundary size
+ * (401/403/IOP480 = 16, 405 = 32)
+ * and doesn't cross cache block boundaries.
+ */
+ alloc_tx_buf = (mal_desc_t *)malloc((sizeof(mal_desc_t) * NUM_TX_BUFF) +
+ ((2 * CFG_CACHELINE_SIZE) - 2));
+ if (((int)alloc_tx_buf & CACHELINE_MASK) != 0) {
+ tx = (mal_desc_t *)((int)alloc_tx_buf + CFG_CACHELINE_SIZE -
+ ((int)alloc_tx_buf & CACHELINE_MASK));
+ } else {
+ tx = alloc_tx_buf;
+ }
+
+ alloc_rx_buf = (mal_desc_t *)malloc((sizeof(mal_desc_t) * NUM_RX_BUFF) +
+ ((2 * CFG_CACHELINE_SIZE) - 2));
+ if (((int)alloc_rx_buf & CACHELINE_MASK) != 0) {
+ rx = (mal_desc_t *)((int)alloc_rx_buf + CFG_CACHELINE_SIZE -
+ ((int)alloc_rx_buf & CACHELINE_MASK));
+ } else {
+ rx = alloc_rx_buf;
+ }
+
+ for (i = 0; i < NUM_TX_BUFF; i++) {
+ tx[i].ctrl = 0;
+ tx[i].data_len = 0;
+ if (first_init == 0)
+ txbuf_ptr = (char *) malloc (ENET_MAX_MTU_ALIGNED);
+ tx[i].data_ptr = txbuf_ptr;
+ if ((NUM_TX_BUFF - 1) == i)
+ tx[i].ctrl |= MAL_TX_CTRL_WRAP;
+ tx_run[i] = -1;
+#if 0
+ printf ("TX_BUFF %d @ 0x%08lx\n", i, (ulong) tx[i].data_ptr);
+#endif
+ }
+
+ for (i = 0; i < NUM_RX_BUFF; i++) {
+ rx[i].ctrl = 0;
+ rx[i].data_len = 0;
+ /* rx[i].data_ptr = (char *) &rx_buff[i]; */
+ rx[i].data_ptr = (char *) NetRxPackets[i];
+ if ((NUM_RX_BUFF - 1) == i)
+ rx[i].ctrl |= MAL_RX_CTRL_WRAP;
+ rx[i].ctrl |= MAL_RX_CTRL_EMPTY | MAL_RX_CTRL_INTR;
+ rx_ready[i] = -1;
+#if 0
+ printf ("RX_BUFF %d @ 0x%08lx\n", i, (ulong) rx[i].data_ptr);
+#endif
+ }
+
+ memcpy (emac_hwd_addr, bis->bi_enetaddr, ENET_ADDR_LENGTH);
+
+ reg = 0x00000000;
+
+ reg |= emac_hwd_addr[0]; /* set high address */
+ reg = reg << 8;
+ reg |= emac_hwd_addr[1];
+
+ out32 (EMAC_IAH, reg);
+
+ reg = 0x00000000;
+ reg |= emac_hwd_addr[2]; /* set low address */
+ reg = reg << 8;
+ reg |= emac_hwd_addr[3];
+ reg = reg << 8;
+ reg |= emac_hwd_addr[4];
+ reg = reg << 8;
+ reg |= emac_hwd_addr[5];
+
+ out32 (EMAC_IAL, reg);
+
+ /* setup MAL tx & rx channel pointers */
+ mtdcr (maltxctp0r, tx);
+ mtdcr (malrxctp0r, rx);
+
+ /* Reset transmit and receive channels */
+ mtdcr (malrxcarr, 0x80000000); /* 2 channels */
+ mtdcr (maltxcarr, 0x80000000); /* 2 channels */
+
+ /* Enable MAL transmit and receive channels */
+ mtdcr (maltxcasr, 0x80000000); /* 1 channel */
+ mtdcr (malrxcasr, 0x80000000); /* 1 channel */
+
+ /* set RX buffer size */
+ mtdcr (malrcbs0, ENET_MAX_MTU_ALIGNED / 16);
+
+ /* set transmit enable & receive enable */
+ out32 (EMAC_M0, EMAC_M0_TXE | EMAC_M0_RXE);
+
+ /* set receive fifo to 4k and tx fifo to 2k */
+ mode_reg = EMAC_M1_RFS_4K | EMAC_M1_TX_FIFO_2K;
+
+ /* set speed */
+ if (speed == _100BASET)
+ mode_reg = mode_reg | EMAC_M1_MF_100MBPS | EMAC_M1_IST;
+ else
+ mode_reg = mode_reg & ~0x00C00000; /* 10 MBPS */
+ if (duplex == FULL)
+ mode_reg = mode_reg | 0x80000000 | EMAC_M1_IST;
+
+ out32 (EMAC_M1, mode_reg);
+
+ /* Enable broadcast and indvidual address */
+ out32 (EMAC_RXM, EMAC_RMR_BAE | EMAC_RMR_IAE
+ /*| EMAC_RMR_ARRP| EMAC_RMR_SFCS | EMAC_RMR_SP */ );
+
+ /* we probably need to set the tx mode1 reg? maybe at tx time */
+
+ /* set transmit request threshold register */
+ out32 (EMAC_TRTR, 0x18000000); /* 256 byte threshold */
+
+ /* set receive low/high water mark register */
+#if defined(CONFIG_440)
+ /* 440GP has a 64 byte burst length */
+ out32 (EMAC_RX_HI_LO_WMARK, 0x80009000);
+ out32 (EMAC_TXM1, 0xf8640000);
+#else /* CONFIG_440 */
+ /* 405s have a 16 byte burst length */
+ out32 (EMAC_RX_HI_LO_WMARK, 0x0f002000);
+#endif /* CONFIG_440 */
+
+ /* Frame gap set */
+ out32 (EMAC_I_FRAME_GAP_REG, 0x00000008);
+
+ if (first_init == 0) {
+ /*
+ * Connect interrupt service routines
+ */
+ irq_install_handler (VECNUM_EWU0, (interrupt_handler_t *) enetInt, NULL);
+ irq_install_handler (VECNUM_MS, (interrupt_handler_t *) enetInt, NULL);
+ irq_install_handler (VECNUM_MTE, (interrupt_handler_t *) enetInt, NULL);
+ irq_install_handler (VECNUM_MRE, (interrupt_handler_t *) enetInt, NULL);
+ irq_install_handler (VECNUM_TXDE, (interrupt_handler_t *) enetInt, NULL);
+ irq_install_handler (VECNUM_RXDE, (interrupt_handler_t *) enetInt, NULL);
+ irq_install_handler (VECNUM_ETH0, (interrupt_handler_t *) enetInt, NULL);
+ }
+
+ /* set up interrupt handler */
+ /* setup interrupt controler to take interrupts from the MAL &
+ EMAC */
+ mtdcr (uicsr, 0xffffffff); /* clear pending interrupts */
+ mtdcr (uicer, mfdcr (uicer) | MAL_UIC_DEF | EMAC_UIC_DEF);
+
+ /* set the MAL IER ??? names may change with new spec ??? */
+ mal_ier = MAL_IER_DE | MAL_IER_NE | MAL_IER_TE | MAL_IER_OPBE |
+ MAL_IER_PLBE;
+ mtdcr (malesr, 0xffffffff); /* clear pending interrupts */
+ mtdcr (maltxdeir, 0xffffffff); /* clear pending interrupts */
+ mtdcr (malrxdeir, 0xffffffff); /* clear pending interrupts */
+ mtdcr (malier, mal_ier);
+
+ /* Set EMAC IER */
+ emac_ier = EMAC_ISR_PTLE | EMAC_ISR_BFCS |
+ EMAC_ISR_PTLE | EMAC_ISR_ORE | EMAC_ISR_IRE;
+ if (speed == _100BASET)
+ emac_ier = emac_ier | EMAC_ISR_SYE;
+
+ out32 (EMAC_ISR, 0xffffffff); /* clear pending interrupts */
+ out32 (EMAC_IER, emac_ier);
+
+ mtmsr (msr); /* enable interrupts again */
+
+ bis_save = bis;
+ first_init = 1;
+
+ return (0);
+}
+
+
+int eth_send (volatile void *ptr, int len)
+{
+ struct enet_frame *ef_ptr;
+ ulong time_start, time_now;
+ unsigned long temp_txm0;
+
+ ef_ptr = (struct enet_frame *) ptr;
+
+ /*-----------------------------------------------------------------------+
+ * Copy in our address into the frame.
+ *-----------------------------------------------------------------------*/
+ (void) memcpy (ef_ptr->source_addr, emac_hwd_addr, ENET_ADDR_LENGTH);
+
+ /*-----------------------------------------------------------------------+
+ * If frame is too long or too short, modify length.
+ *-----------------------------------------------------------------------*/
+ if (len > ENET_MAX_MTU)
+ len = ENET_MAX_MTU;
+
+ /* memcpy ((void *) &tx_buff[tx_slot], (const void *) ptr, len); */
+ memcpy ((void *) txbuf_ptr, (const void *) ptr, len);
+
+ /*-----------------------------------------------------------------------+
+ * set TX Buffer busy, and send it
+ *-----------------------------------------------------------------------*/
+ tx[tx_slot].ctrl = (MAL_TX_CTRL_LAST |
+ EMAC_TX_CTRL_GFCS | EMAC_TX_CTRL_GP) &
+ ~(EMAC_TX_CTRL_ISA | EMAC_TX_CTRL_RSA);
+ if ((NUM_TX_BUFF - 1) == tx_slot)
+ tx[tx_slot].ctrl |= MAL_TX_CTRL_WRAP;
+
+ tx[tx_slot].data_len = (short) len;
+ tx[tx_slot].ctrl |= MAL_TX_CTRL_READY;
+
+ __asm__ volatile ("eieio");
+ out32 (EMAC_TXM0, in32 (EMAC_TXM0) | EMAC_TXM0_GNP0);
+#ifdef INFO_405_ENET
+ packetSent++;
+#endif
+
+ /*-----------------------------------------------------------------------+
+ * poll unitl the packet is sent and then make sure it is OK
+ *-----------------------------------------------------------------------*/
+ time_start = get_timer (0);
+ while (1) {
+ temp_txm0 = in32 (EMAC_TXM0);
+ /* loop until either TINT turns on or 3 seconds elapse */
+ if ((temp_txm0 & EMAC_TXM0_GNP0) != 0) {
+ /* transmit is done, so now check for errors
+ * If there is an error, an interrupt should
+ * happen when we return
+ */
+ time_now = get_timer (0);
+ if ((time_now - time_start) > 3000) {
+ return (-1);
+ }
+ } else {
+ return (0);
+ }
+ }
+}
+
+
+#if defined(CONFIG_440)
+/*-----------------------------------------------------------------------------+
+| EnetInt.
+| EnetInt is the interrupt handler. It will determine the
+| cause of the interrupt and call the apporpriate servive
+| routine.
++-----------------------------------------------------------------------------*/
+int enetInt ()
+{
+ int serviced;
+ int rc = -1; /* default to not us */
+ unsigned long mal_isr;
+ unsigned long emac_isr = 0;
+ unsigned long mal_rx_eob;
+ unsigned long my_uic0msr, my_uic1msr;
+
+ /* enter loop that stays in interrupt code until nothing to service */
+ do {
+ serviced = 0;
+
+ my_uic0msr = mfdcr (uic0msr);
+ my_uic1msr = mfdcr (uic1msr);
+
+ if (!(my_uic0msr & UIC_MRE)
+ && !(my_uic1msr & (UIC_ETH0 | UIC_MS | UIC_MTDE | UIC_MRDE))) {
+ /* not for us */
+ return (rc);
+ }
+
+ /* get and clear controller status interrupts */
+ /* look at Mal and EMAC interrupts */
+ if ((my_uic0msr & UIC_MRE)
+ || (my_uic1msr & (UIC_MS | UIC_MTDE | UIC_MRDE))) {
+ /* we have a MAL interrupt */
+ mal_isr = mfdcr (malesr);
+ /* look for mal error */
+ if (my_uic1msr & (UIC_MS | UIC_MTDE | UIC_MRDE)) {
+ mal_err (mal_isr, my_uic0msr, MAL_UIC_DEF, MAL_UIC_ERR);
+ serviced = 1;
+ rc = 0;
+ }
+ }
+ if (UIC_ETH0 & my_uic1msr) { /* look for EMAC errors */
+ emac_isr = in32 (EMAC_ISR);
+ if ((emac_ier & emac_isr) != 0) {
+ emac_err (emac_isr);
+ serviced = 1;
+ rc = 0;
+ }
+ }
+ if ((emac_ier & emac_isr)
+ || (my_uic1msr & (UIC_MS | UIC_MTDE | UIC_MRDE))) {
+ mtdcr (uic0sr, UIC_MRE); /* Clear */
+ mtdcr (uic1sr, UIC_ETH0 | UIC_MS | UIC_MTDE | UIC_MRDE); /* Clear */
+ return (rc); /* we had errors so get out */
+ }
+
+ /* handle MAL RX EOB interupt from a receive */
+ /* check for EOB on valid channels */
+ if (my_uic0msr & UIC_MRE) {
+ mal_rx_eob = mfdcr (malrxeobisr);
+ if ((mal_rx_eob & 0x80000000) != 0) { /* call emac routine for channel 0 */
+ /* clear EOB
+ mtdcr(malrxeobisr, mal_rx_eob); */
+ enet_rcv (emac_isr);
+ /* indicate that we serviced an interrupt */
+ serviced = 1;
+ rc = 0;
+ }
+ }
+ mtdcr (uic0sr, UIC_MRE); /* Clear */
+ mtdcr (uic1sr, UIC_ETH0 | UIC_MS | UIC_MTDE | UIC_MRDE); /* Clear */
+ } while (serviced);
+
+ return (rc);
+}
+#else /* CONFIG_440 */
+/*-----------------------------------------------------------------------------+
+ * EnetInt.
+ * EnetInt is the interrupt handler. It will determine the
+ * cause of the interrupt and call the apporpriate servive
+ * routine.
+ *-----------------------------------------------------------------------------*/
+int enetInt ()
+{
+ int serviced;
+ int rc = -1; /* default to not us */
+ unsigned long mal_isr;
+ unsigned long emac_isr = 0;
+ unsigned long mal_rx_eob;
+ unsigned long my_uicmsr;
+
+ /* enter loop that stays in interrupt code until nothing to service */
+ do {
+ serviced = 0;
+
+ my_uicmsr = mfdcr (uicmsr);
+ if ((my_uicmsr & (MAL_UIC_DEF | EMAC_UIC_DEF)) == 0) { /* not for us */
+ return (rc);
+ }
+
+
+ /* get and clear controller status interrupts */
+ /* look at Mal and EMAC interrupts */
+ if ((MAL_UIC_DEF & my_uicmsr) != 0) { /* we have a MAL interrupt */
+ mal_isr = mfdcr (malesr);
+ /* look for mal error */
+ if ((my_uicmsr & MAL_UIC_ERR) != 0) {
+ mal_err (mal_isr, my_uicmsr, MAL_UIC_DEF, MAL_UIC_ERR);
+ serviced = 1;
+ rc = 0;
+ }
+ }
+ if ((EMAC_UIC_DEF & my_uicmsr) != 0) { /* look for EMAC errors */
+ emac_isr = in32 (EMAC_ISR);
+ if ((emac_ier & emac_isr) != 0) {
+ emac_err (emac_isr);
+ serviced = 1;
+ rc = 0;
+ }
+ }
+ if (((emac_ier & emac_isr) != 0) | ((MAL_UIC_ERR & my_uicmsr) != 0)) {
+ mtdcr (uicsr, MAL_UIC_DEF | EMAC_UIC_DEF); /* Clear */
+ return (rc); /* we had errors so get out */
+ }
+
+
+ /* handle MAL RX EOB interupt from a receive */
+ /* check for EOB on valid channels */
+ if ((my_uicmsr & UIC_MAL_RXEOB) != 0) {
+ mal_rx_eob = mfdcr (malrxeobisr);
+ if ((mal_rx_eob & 0x80000000) != 0) { /* call emac routine for channel 0 */
+ /* clear EOB
+ mtdcr(malrxeobisr, mal_rx_eob); */
+ enet_rcv (emac_isr);
+ /* indicate that we serviced an interrupt */
+ serviced = 1;
+ rc = 0;
+ }
+ }
+ mtdcr (uicsr, MAL_UIC_DEF | EMAC_UIC_DEF); /* Clear */
+ }
+ while (serviced);
+
+ return (rc);
+}
+#endif /* CONFIG_440 */
+
+/*-----------------------------------------------------------------------------+
+ * MAL Error Routine
+ *-----------------------------------------------------------------------------*/
+void mal_err (unsigned long isr, unsigned long uic, unsigned long maldef,
+ unsigned long mal_errr)
+{
+ mtdcr (malesr, isr); /* clear interrupt */
+
+ /* clear DE interrupt */
+ mtdcr (maltxdeir, 0xC0000000);
+ mtdcr (malrxdeir, 0x80000000);
+
+#if 1 /*sr */
+ printf ("\nMAL error occured.... ISR = %lx UIC = = %lx MAL_DEF = %lx MAL_ERR= %lx \n",
+ isr, uic, maldef, mal_errr);
+#else
+#if 0
+ /*
+ * MAL error is RX DE error (out of rx buffers)! This is OK here, upon
+ * many incoming packets with only 4 rx buffers.
+ */
+ printf ("M"); /* just to see something upon mal error */
+#endif
+#endif /*sr */
+
+ eth_init (bis_save); /* start again... */
+}
+
+/*-----------------------------------------------------------------------------+
+ * EMAC Error Routine
+ *-----------------------------------------------------------------------------*/
+void emac_err (unsigned long isr)
+{
+ printf ("EMAC error occured.... ISR = %lx\n", isr);
+ out32 (EMAC_ISR, isr);
+}
+
+/*-----------------------------------------------------------------------------+
+ * enet_rcv() handles the ethernet receive data
+ *-----------------------------------------------------------------------------*/
+static void enet_rcv (unsigned long malisr)
+{
+ struct enet_frame *ef_ptr;
+ unsigned long data_len;
+ unsigned long rx_eob_isr;
+
+ int handled = 0;
+ int i;
+ int loop_count = 0;
+
+ rx_eob_isr = mfdcr (malrxeobisr);
+ if ((0x80000000 >> (EMAC_RXCHL - 1)) & rx_eob_isr) {
+ /* clear EOB */
+ mtdcr (malrxeobisr, rx_eob_isr);
+
+ /* EMAC RX done */
+ while (1) { /* do all */
+ i = rx_slot;
+
+ if ((MAL_RX_CTRL_EMPTY & rx[i].ctrl)
+ || (loop_count >= NUM_RX_BUFF))
+ break;
+ loop_count++;
+ rx_slot++;
+ if (NUM_RX_BUFF == rx_slot)
+ rx_slot = 0;
+ handled++;
+ data_len = (unsigned long) rx[i].data_len; /* Get len */
+ if (data_len) {
+ if (data_len > ENET_MAX_MTU) /* Check len */
+ data_len = 0;
+ else {
+ if (EMAC_RX_ERRORS & rx[i].ctrl) { /* Check Errors */
+ data_len = 0;
+ stats.rx_err_log[rx_err_index] = rx[i].ctrl;
+ rx_err_index++;
+ if (rx_err_index == MAX_ERR_LOG)
+ rx_err_index = 0;
+ } /* emac_erros */
+ } /* data_len < max mtu */
+ } /* if data_len */
+ if (!data_len) { /* no data */
+ rx[i].ctrl |= MAL_RX_CTRL_EMPTY; /* Free Recv Buffer */
+
+ stats.emac.data_len_err++; /* Error at Rx */
+ }
+
+ /* !data_len */
+ /* AS.HARNOIS */
+ /* Check if user has already eaten buffer */
+ /* if not => ERROR */
+ else if (rx_ready[rx_i_index] != -1) {
+ if (is_receiving)
+ printf ("ERROR : Receive buffers are full!\n");
+ break;
+ } else {
+ stats.emac.rx_frames++;
+ stats.emac.rx += data_len;
+ ef_ptr = (struct enet_frame *) rx[i].data_ptr;
+#ifdef INFO_405_ENET
+ packetReceived++;
+#endif
+ /* AS.HARNOIS
+ * use ring buffer
+ */
+ rx_ready[rx_i_index] = i;
+ rx_i_index++;
+ if (NUM_RX_BUFF == rx_i_index)
+ rx_i_index = 0;
+
+ /* printf("X"); /|* test-only *|/ */
+
+ /* AS.HARNOIS
+ * free receive buffer only when
+ * buffer has been handled (eth_rx)
+ rx[i].ctrl |= MAL_RX_CTRL_EMPTY;
+ */
+ } /* if data_len */
+ } /* while */
+ } /* if EMACK_RXCHL */
+}
+
+
+int eth_rx (void)
+{
+ int length;
+ int user_index;
+ unsigned long msr;
+
+ is_receiving = 1; /* tell driver */
+
+ for (;;) {
+ /* AS.HARNOIS
+ * use ring buffer and
+ * get index from rx buffer desciptor queue
+ */
+ user_index = rx_ready[rx_u_index];
+ if (user_index == -1) {
+ length = -1;
+ break; /* nothing received - leave for() loop */
+ }
+
+ msr = mfmsr ();
+ mtmsr (msr & ~(MSR_EE));
+
+ length = rx[user_index].data_len;
+
+ /* Pass the packet up to the protocol layers. */
+ /* NetReceive(NetRxPackets[rxIdx], length - 4); */
+ /* NetReceive(NetRxPackets[i], length); */
+ NetReceive (NetRxPackets[user_index], length - 4);
+ /* Free Recv Buffer */
+ rx[user_index].ctrl |= MAL_RX_CTRL_EMPTY;
+ /* Free rx buffer descriptor queue */
+ rx_ready[rx_u_index] = -1;
+ rx_u_index++;
+ if (NUM_RX_BUFF == rx_u_index)
+ rx_u_index = 0;
+
+#ifdef INFO_405_ENET
+ packetHandled++;
+#endif
+
+ mtmsr (msr); /* Enable IRQ's */
+ }
+
+ is_receiving = 0; /* tell driver */
+
+ return length;
+}
+
+#endif /* CONFIG_405GP */
--- /dev/null
+/*-----------------------------------------------------------------------------+
+ *
+ * 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
+ *-----------------------------------------------------------------------------*/
+/*----------------------------------------------------------------------------+
+ *
+ * File Name: 405gp_pci.c
+ *
+ * Function: Initialization code for the 405GP PCI Configuration regs.
+ *
+ * Author: Mark Game
+ *
+ * Change Activity-
+ *
+ * Date Description of Change BY
+ * --------- --------------------- ---
+ * 09-Sep-98 Created MCG
+ * 02-Nov-98 Removed External arbiter selected message JWB
+ * 27-Nov-98 Zero out PTMBAR2 and disable in PTM2MS JWB
+ * 04-Jan-99 Zero out other unused PMM and PTM regs. Change bus scan MCG
+ * from (0 to n) to (1 to n).
+ * 17-May-99 Port to Walnut JWB
+ * 17-Jun-99 Updated for VGA support JWB
+ * 21-Jun-99 Updated to allow SRAM region to be a target from PCI bus JWB
+ * 19-Jul-99 Updated for 405GP pass 1 errata #26 (Low PCI subsequent MCG
+ * target latency timer values are not supported).
+ * Should be fixed in pass 2.
+ * 09-Sep-99 Removed use of PTM2 since the SRAM region no longer needs JWB
+ * to be a PCI target. Zero out PTMBAR2 and disable in PTM2MS.
+ * 10-Dec-99 Updated PCI_Write_CFG_Reg for pass2 errata #6 JWB
+ * 11-Jan-00 Ensure PMMxMAs disabled before setting PMMxLAs. This is not
+ * really required after a reset since PMMxMAs are already
+ * disabled but is a good practice nonetheless. JWB
+ * 12-Jun-01 stefan.roese@esd-electronics.com
+ * - PCI host/adapter handling reworked
+ * 09-Jul-01 stefan.roese@esd-electronics.com
+ * - PCI host now configures from device 0 (not 1) to max_dev,
+ * (host configures itself)
+ * - On CPCI-405 pci base address and size is generated from
+ * SDRAM and FLASH size (CFG regs not used anymore)
+ * - Some minor changes for CPCI-405-A (adapter version)
+ * 14-Sep-01 stefan.roese@esd-electronics.com
+ * - CONFIG_PCI_SCAN_SHOW added to print pci devices upon startup
+ * 28-Sep-01 stefan.roese@esd-electronics.com
+ * - Changed pci master configuration for linux compatibility
+ * (no need for bios_fixup() anymore)
+ * 26-Feb-02 stefan.roese@esd-electronics.com
+ * - Bug fixed in pci configuration (Andrew May)
+ * - Removed pci class code init for CPCI405 board
+ * 15-May-02 stefan.roese@esd-electronics.com
+ * - New vga device handling
+ * 29-May-02 stefan.roese@esd-electronics.com
+ * - PCI class code init added (if defined)
+ *----------------------------------------------------------------------------*/
+
+#include <common.h>
+#include <command.h>
+#include <cmd_boot.h>
+#if !defined(CONFIG_440)
+#include <405gp_pci.h>
+#endif
+#include <asm/processor.h>
+#include <pci.h>
+
+#if defined(CONFIG_405GP)
+
+#ifdef CONFIG_PCI
+
+/*#define DEBUG*/
+
+/*-----------------------------------------------------------------------------+
+ * pci_init. Initializes the 405GP PCI Configuration regs.
+ *-----------------------------------------------------------------------------*/
+void pci_405gp_init(struct pci_controller *hose)
+{
+ DECLARE_GLOBAL_DATA_PTR;
+
+ int i, reg_num = 0;
+ bd_t *bd = gd->bd;
+
+ unsigned short temp_short;
+ unsigned long ptmpcila[2] = {CFG_PCI_PTM1PCI, CFG_PCI_PTM2PCI};
+#if defined(CONFIG_CPCI405)
+ unsigned long ptmla[2] = {bd->bi_memstart, bd->bi_flashstart};
+ unsigned long ptmms[2] = {~(bd->bi_memsize - 1) | 1, ~(bd->bi_flashsize - 1) | 1};
+#else
+ unsigned long ptmla[2] = {CFG_PCI_PTM1LA, CFG_PCI_PTM2LA};
+ unsigned long ptmms[2] = {CFG_PCI_PTM1MS, CFG_PCI_PTM2MS};
+#endif
+#if defined(CONFIG_PIP405) || defined (CONFIG_MIP405)
+ unsigned long pmmla[3] = {0x80000000, 0xA0000000, 0};
+ unsigned long pmmma[3] = {0xE0000001, 0xE0000001, 0};
+ unsigned long pmmpcila[3] = {0x80000000, 0x00000000, 0};
+ unsigned long pmmpciha[3] = {0x00000000, 0x00000000, 0};
+#else
+ unsigned long pmmla[3] = {0x80000000, 0,0};
+ unsigned long pmmma[3] = {0xC0000001, 0,0};
+ unsigned long pmmpcila[3] = {0x80000000, 0,0};
+ unsigned long pmmpciha[3] = {0x00000000, 0,0};
+#endif
+
+ /*
+ * Register the hose
+ */
+ hose->first_busno = 0;
+ hose->last_busno = 0xff;
+
+ /* ISA/PCI I/O space */
+ pci_set_region(hose->regions + reg_num++,
+ MIN_PCI_PCI_IOADDR,
+ MIN_PLB_PCI_IOADDR,
+ 0x10000,
+ PCI_REGION_IO);
+
+ /* PCI I/O space */
+ pci_set_region(hose->regions + reg_num++,
+ 0x00800000,
+ 0xe8800000,
+ 0x03800000,
+ PCI_REGION_IO);
+
+ reg_num = 2;
+
+ /* Memory spaces */
+ for (i=0; i<2; i++)
+ if (ptmms[i] & 1)
+ {
+ if (!i) hose->pci_fb = hose->regions + reg_num;
+
+ pci_set_region(hose->regions + reg_num++,
+ ptmpcila[i], ptmla[i],
+ ~(ptmms[i] & 0xfffff000) + 1,
+ PCI_REGION_MEM |
+ PCI_REGION_MEMORY);
+ }
+
+ /* PCI memory spaces */
+ for (i=0; i<3; i++)
+ if (pmmma[i] & 1)
+ {
+ pci_set_region(hose->regions + reg_num++,
+ pmmpcila[i], pmmla[i],
+ ~(pmmma[i] & 0xfffff000) + 1,
+ PCI_REGION_MEM);
+ }
+
+ hose->region_count = reg_num;
+
+ pci_setup_indirect(hose,
+ PCICFGADR,
+ PCICFGDATA);
+
+ if (hose->pci_fb)
+ pciauto_region_init(hose->pci_fb);
+
+ pci_register_hose(hose);
+
+ /*--------------------------------------------------------------------------+
+ * 405GP PCI Master configuration.
+ * Map one 512 MB range of PLB/processor addresses to PCI memory space.
+ * PLB address 0x80000000-0xBFFFFFFF ==> PCI address 0x80000000-0xBFFFFFFF
+ * Use byte reversed out routines to handle endianess.
+ *--------------------------------------------------------------------------*/
+ out32r(PMM0MA, pmmma[0]); /* ensure disabled b4 setting PMM0LA */
+ out32r(PMM0LA, pmmla[0]);
+ out32r(PMM0PCILA, pmmpcila[0]);
+ out32r(PMM0PCIHA, pmmpciha[0]);
+ out32r(PMM0MA, pmmma[0]);
+
+ /*--------------------------------------------------------------------------+
+ * PMM1 is not used. Initialize them to zero.
+ *--------------------------------------------------------------------------*/
+ out32r(PMM1MA, pmmma[1]); /* ensure disabled b4 setting PMM2LA */
+ out32r(PMM1LA, pmmla[1]);
+ out32r(PMM1PCILA, pmmpcila[1]);
+ out32r(PMM1PCIHA, pmmpciha[1]);
+ out32r(PMM1MA, pmmma[1]);
+
+ /*--------------------------------------------------------------------------+
+ * PMM2 is not used. Initialize them to zero.
+ *--------------------------------------------------------------------------*/
+ out32r(PMM2MA, pmmma[2]); /* ensure disabled b4 setting PMM2LA */
+ out32r(PMM2LA, pmmla[2]);
+ out32r(PMM2PCILA, pmmpcila[2]);
+ out32r(PMM2PCIHA, pmmpciha[2]);
+ out32r(PMM2MA, pmmma[2]);
+
+ /*--------------------------------------------------------------------------+
+ * 405GP PCI Target configuration. (PTM1)
+ * Note: PTM1MS is hardwire enabled but we set the enable bit anyway.
+ *--------------------------------------------------------------------------*/
+ out32r(PTM1LA, ptmla[0]); /* insert address */
+ out32r(PTM1MS, ptmms[0]); /* insert size, enable bit is 1 */
+
+ /*--------------------------------------------------------------------------+
+ * 405GP PCI Target configuration. (PTM2)
+ *--------------------------------------------------------------------------*/
+ out32r(PTM2LA, ptmla[1]); /* insert address */
+ if (ptmms[1] == 0)
+ {
+ out32r(PTM2MS, 0x00000001); /* set enable bit */
+ pci_write_config_dword(PCIDEVID_405GP, PCI_BASE_ADDRESS_2, 0x00000000);
+ out32r(PTM2MS, 0x00000000); /* disable */
+ }
+ else
+ {
+ out32r(PTM2MS, ptmms[1]); /* insert size, enable bit is 1 */
+ }
+
+ /*
+ * Insert Subsystem Vendor and Device ID
+ */
+ pci_write_config_word(PCIDEVID_405GP, PCI_SUBSYSTEM_VENDOR_ID, CFG_PCI_SUBSYS_VENDORID);
+#ifdef CONFIG_CPCI405
+ if (mfdcr(strap) & PSR_PCI_ARBIT_EN)
+ pci_write_config_word(PCIDEVID_405GP, PCI_SUBSYSTEM_ID, CFG_PCI_SUBSYS_DEVICEID);
+ else
+ pci_write_config_word(PCIDEVID_405GP, PCI_SUBSYSTEM_ID, CFG_PCI_SUBSYS_DEVICEID2);
+#else
+ pci_write_config_word(PCIDEVID_405GP, PCI_SUBSYSTEM_ID, CFG_PCI_SUBSYS_DEVICEID);
+#endif
+
+ /*
+ * Insert Class-code
+ */
+#ifdef CFG_PCI_CLASSCODE
+ pci_write_config_word(PCIDEVID_405GP, PCI_CLASS_SUB_CODE, CFG_PCI_CLASSCODE);
+#endif /* CFG_PCI_CLASSCODE */
+
+ /*--------------------------------------------------------------------------+
+ * If PCI speed = 66Mhz, set 66Mhz capable bit.
+ *--------------------------------------------------------------------------*/
+ if (bd->bi_pci_busfreq >= 66000000) {
+ pci_read_config_word(PCIDEVID_405GP, PCI_STATUS, &temp_short);
+ pci_write_config_word(PCIDEVID_405GP,PCI_STATUS,(temp_short|PCI_STATUS_66MHZ));
+ }
+
+#if (CONFIG_PCI_HOST != PCI_HOST_ADAPTER)
+#if (CONFIG_PCI_HOSE == PCI_HOST_AUTO)
+ if (mfdcr(strap) & PSR_PCI_ARBIT_EN)
+#endif
+ {
+ /*--------------------------------------------------------------------------+
+ * Write the 405GP PCI Configuration regs.
+ * Enable 405GP to be a master on the PCI bus (PMM).
+ * Enable 405GP to act as a PCI memory target (PTM).
+ *--------------------------------------------------------------------------*/
+ pci_read_config_word(PCIDEVID_405GP, PCI_COMMAND, &temp_short);
+ pci_write_config_word(PCIDEVID_405GP, PCI_COMMAND, temp_short |
+ PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY);
+ }
+#endif
+
+ /*
+ * Set HCE bit (Host Configuration Enabled)
+ */
+ pci_read_config_word(PCIDEVID_405GP, PCIBRDGOPT2, &temp_short);
+ pci_write_config_word(PCIDEVID_405GP, PCIBRDGOPT2, (temp_short | 0x0001));
+
+#ifdef CONFIG_PCI_PNP
+ /*--------------------------------------------------------------------------+
+ * Scan the PCI bus and configure devices found.
+ *--------------------------------------------------------------------------*/
+#if (CONFIG_PCI_HOST == PCI_HOST_AUTO)
+ if (mfdcr(strap) & PSR_PCI_ARBIT_EN)
+#endif
+ {
+#ifdef CONFIG_PCI_SCAN_SHOW
+ printf("PCI: Bus Dev VenId DevId Class Int\n");
+#endif
+
+ hose->last_busno = pci_hose_scan(hose);
+ }
+#endif /* CONFIG_PCI_PNP */
+
+}
+
+/*
+ * drivers/pci.c skips every host bridge but the 405GP since it could
+ * be set as an Adapter.
+ *
+ * I (Andrew May) don't know what we should do here, but I don't want
+ * the auto setup of a PCI device disabling what is done pci_405gp_init
+ * as has happened before.
+ */
+void pci_405gp_setup_bridge(struct pci_controller *hose, pci_dev_t dev,
+ struct pci_config_table *entry)
+{
+#ifdef DEBUG
+ printf("405gp_setup_bridge\n");
+#endif
+}
+
+/*
+ *
+ */
+
+void pci_405gp_fixup_irq(struct pci_controller *hose, pci_dev_t dev)
+{
+ unsigned char int_line = 0xff;
+
+ /*
+ * Write pci interrupt line register (cpci405 specific)
+ */
+ switch (PCI_DEV(dev) & 0x03)
+ {
+ case 0:
+ int_line = 27 + 2;
+ break;
+ case 1:
+ int_line = 27 + 3;
+ break;
+ case 2:
+ int_line = 27 + 0;
+ break;
+ case 3:
+ int_line = 27 + 1;
+ break;
+ }
+
+ pci_hose_write_config_byte(hose, dev, PCI_INTERRUPT_LINE, int_line);
+}
+
+void pci_405gp_setup_vga(struct pci_controller *hose, pci_dev_t dev,
+ struct pci_config_table *entry)
+{
+ unsigned int cmdstat = 0;
+
+ pciauto_setup_device(hose, dev, 6, hose->pci_mem, hose->pci_io);
+
+ /* always enable io space on vga boards */
+ pci_hose_read_config_dword(hose, dev, PCI_COMMAND, &cmdstat);
+ cmdstat |= PCI_COMMAND_IO;
+ pci_hose_write_config_dword(hose, dev, PCI_COMMAND, cmdstat);
+}
+
+#if !(defined(CONFIG_PIP405) || defined (CONFIG_MIP405))
+
+/*
+ *As is these functs get called out of flash Not a horrible
+ *thing, but something to keep in mind. (no statics?)
+ */
+static struct pci_config_table pci_405gp_config_table[] = {
+/*if VendID is 0 it terminates the table search (ie Walnut)*/
+#if CFG_PCI_SUBSYS_VENDORID
+ {CFG_PCI_SUBSYS_VENDORID, PCI_ANY_ID, PCI_CLASS_BRIDGE_HOST,
+ PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, pci_405gp_setup_bridge},
+#endif
+ {PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA,
+ PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, pci_405gp_setup_vga},
+
+ {PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_NOT_DEFINED_VGA,
+ PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, pci_405gp_setup_vga},
+
+ { }
+};
+
+static struct pci_controller hose = {
+ fixup_irq: pci_405gp_fixup_irq,
+ config_table: pci_405gp_config_table,
+};
+
+void pci_init(void)
+{
+ /*we want the ptrs to RAM not flash (ie don't use init list)*/
+ hose.fixup_irq = pci_405gp_fixup_irq;
+ hose.config_table = pci_405gp_config_table;
+ pci_405gp_init(&hose);
+}
+
+#endif
+
+#endif /* CONFIG_PCI */
+
+#endif /* CONFIG_405GP */
+
+/*-----------------------------------------------------------------------------+
+ * CONFIG_440
+ *-----------------------------------------------------------------------------*/
+#if defined(CONFIG_440) && defined(CONFIG_PCI)
+
+static struct pci_controller ppc440_hose = {0};
+
+
+void pci_440_init (struct pci_controller *hose)
+{
+ int reg_num = 0;
+ unsigned long strap;
+
+ /*--------------------------------------------------------------------------+
+ * The PCI initialization sequence enable bit must be set ... if not abort
+ * pci setup since updating the bit requires chip reset.
+ *--------------------------------------------------------------------------*/
+ strap = mfdcr(cpc0_strp1);
+ if( (strap & 0x00040000) == 0 ){
+ printf("PCI: CPC0_STRP1[PISE] not set.\n");
+ printf("PCI: Configuration aborted.\n");
+ return;
+ }
+
+ /*--------------------------------------------------------------------------+
+ * PCI controller init
+ *--------------------------------------------------------------------------*/
+ hose->first_busno = 0;
+ hose->last_busno = 0xff;
+
+ pci_set_region(hose->regions + reg_num++,
+ 0x00000000,
+ PCIX0_IOBASE,
+ 0x10000,
+ PCI_REGION_IO);
+
+ pci_set_region(hose->regions + reg_num++,
+ CFG_PCI_TARGBASE,
+ CFG_PCI_MEMBASE,
+ 0x10000000,
+ PCI_REGION_MEM );
+ hose->region_count = reg_num;
+
+ pci_setup_indirect(hose, PCIX0_CFGADR, PCIX0_CFGDATA);
+
+#if defined(CFG_PCI_PRE_INIT)
+ /* Let board change/modify hose & do initial checks */
+ if( pci_pre_init (hose) == 0 ){
+ printf("PCI: Board-specific initialization failed.\n");
+ printf("PCI: Configuration aborted.\n");
+ return;
+ }
+#endif
+
+ pci_register_hose( hose );
+
+ /*--------------------------------------------------------------------------+
+ * PCI target init
+ *--------------------------------------------------------------------------*/
+#if defined(CFG_PCI_TARGET_INIT)
+ pci_target_init(hose); /* Let board setup pci target */
+#else
+ out16r( PCIX0_SBSYSVID, CFG_PCI_SUBSYS_VENDORID );
+ out16r( PCIX0_SBSYSID, CFG_PCI_SUBSYS_ID );
+ out16r( PCIX0_CLS, 0x00060000 ); /* Bridge, host bridge */
+#endif
+
+ out32r( PCIX0_BRDGOPT1, 0x10000060 ); /* PLB Rq pri highest */
+ out32r( PCIX0_BRDGOPT2, in32(PCIX0_BRDGOPT2) | 1 ); /* Enable host config */
+
+ /*--------------------------------------------------------------------------+
+ * PCI master init: default is one 256MB region for PCI memory:
+ * 0x3_00000000 - 0x3_0FFFFFFF ==> CFG_PCI_MEMBASE
+ *--------------------------------------------------------------------------*/
+#if defined(CFG_PCI_MASTER_INIT)
+ pci_master_init(hose); /* Let board setup pci master */
+#else
+ out32r( PCIX0_POM0SA, 0 ); /* disable */
+ out32r( PCIX0_POM1SA, 0 ); /* disable */
+ out32r( PCIX0_POM2SA, 0 ); /* disable */
+ out32r( PCIX0_POM0LAL, 0x00000000 );
+ out32r( PCIX0_POM0LAH, 0x00000003 );
+ out32r( PCIX0_POM0PCIAL, CFG_PCI_MEMBASE );
+ out32r( PCIX0_POM0PCIAH, 0x00000000 );
+ out32r( PCIX0_POM0SA, 0xf0000001 ); /* 256MB, enabled */
+ out32r( PCIX0_STS, in32r( PCIX0_STS ) & ~0x0000fff8 );
+#endif
+
+ /*--------------------------------------------------------------------------+
+ * PCI host configuration -- we don't make any assumptions here ... the
+ * _board_must_indicate_ what to do -- there's just too many runtime
+ * scenarios in environments like cPCI, PPMC, etc. to make a determination
+ * based on hard-coded values or state of arbiter enable.
+ *--------------------------------------------------------------------------*/
+ if( is_pci_host(hose) ){
+#ifdef CONFIG_PCI_SCAN_SHOW
+ printf("PCI: Bus Dev VenId DevId Class Int\n");
+#endif
+ out16r( PCIX0_CMD, in16r( PCIX0_CMD ) | PCI_COMMAND_MASTER);
+ hose->last_busno = pci_hose_scan(hose);
+ }
+}
+
+
+void pci_init(void)
+{
+ pci_440_init (&ppc440_hose);
+}
+
+#endif /* CONFIG_440 & CONFIG_PCI */
--- /dev/null
+/*
+ * (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
+ */
+
+/*
+ * m8xx.c
+ *
+ * CPU specific code
+ *
+ * written or collected and sometimes rewritten by
+ * Magnus Damm <damm@bitsmart.com>
+ *
+ * minor modifications by
+ * Wolfgang Denk <wd@denx.de>
+ */
+
+#include <common.h>
+#include <watchdog.h>
+#include <command.h>
+#include <asm/cache.h>
+#include <ppc4xx.h>
+
+
+#if defined(CONFIG_440)
+static int do_chip_reset( unsigned long sys0, unsigned long sys1 );
+#endif
+
+/* ------------------------------------------------------------------------- */
+
+int checkcpu (void)
+{
+#if defined(CONFIG_405GP) || defined(CONFIG_405CR) || defined(CONFIG_IOP480) || defined(CONFIG_440)
+ uint pvr = get_pvr();
+#endif
+#if defined(CONFIG_405GP) || defined(CONFIG_405CR) || defined(CONFIG_IOP480)
+ DECLARE_GLOBAL_DATA_PTR;
+
+ ulong clock = gd->cpu_clk;
+ char buf[32];
+#endif
+
+#if defined(CONFIG_405GP) || defined(CONFIG_405CR)
+ PPC405_SYS_INFO sys_info;
+
+ puts ("CPU: ");
+
+ get_sys_info(&sys_info);
+
+#if CONFIG_405GP
+ puts("IBM PowerPC 405GP");
+ if (pvr == PVR_405GPR_RA) {
+ putc('r');
+ }
+ puts(" Rev. ");
+#endif
+#if CONFIG_405CR
+ puts("IBM PowerPC 405CR Rev. ");
+#endif
+ switch (pvr) {
+ case PVR_405GP_RB:
+ putc('B');
+ break;
+ case PVR_405GP_RC:
+#if CONFIG_405CR
+ case PVR_405CR_RC:
+#endif
+ putc('C');
+ break;
+ case PVR_405GP_RD:
+ putc('D');
+ break;
+#if CONFIG_405GP
+ case PVR_405GP_RE:
+ putc('E');
+ break;
+#endif
+ case PVR_405CR_RA:
+ case PVR_405GPR_RA:
+ putc('A');
+ break;
+ case PVR_405CR_RB:
+ putc('B');
+ break;
+ default:
+ printf("? (PVR=%08x)", pvr);
+ break;
+ }
+
+ printf(" at %s MHz (PLB=%lu, OPB=%lu, EBC=%lu MHz)\n", strmhz(buf, clock),
+ sys_info.freqPLB / 1000000,
+ sys_info.freqPLB / sys_info.pllOpbDiv / 1000000,
+ sys_info.freqPLB / sys_info.pllExtBusDiv / 1000000);
+
+#if CONFIG_405GP
+ if (mfdcr(strap) & PSR_PCI_ASYNC_EN)
+ printf(" PCI async ext clock used, ");
+ else
+ printf(" PCI sync clock at %lu MHz, ",
+ sys_info.freqPLB / sys_info.pllPciDiv / 1000000);
+ if (mfdcr(strap) & PSR_PCI_ARBIT_EN)
+ printf("internal PCI arbiter enabled\n");
+ else
+ printf("external PCI arbiter enabled\n");
+#endif
+
+ if ((pvr | 0x00000001) == PVR_405GPR_RA) {
+ printf(" 16 kB I-Cache 16 kB D-Cache");
+ } else {
+ printf(" 16 kB I-Cache 8 kB D-Cache");
+ }
+
+
+#endif /* defined(CONFIG_405GP) || defined(CONFIG_405CR) */
+
+#ifdef CONFIG_IOP480
+ printf("PLX IOP480 (PVR=%08x)", pvr);
+ printf(" at %s MHz:", strmhz(buf, clock));
+ printf(" %u kB I-Cache", 4);
+ printf(" %u kB D-Cache", 2);
+#endif
+
+#if defined(CONFIG_440)
+ puts("IBM PowerPC 440 Rev. ");
+ switch(pvr)
+ {
+ case PVR_440GP_RB:
+ putc('B');
+ /* See errata 1.12: CHIP_4 */
+ if( ( mfdcr(cpc0_sys0) != mfdcr(cpc0_strp0) )
+ ||( mfdcr(cpc0_sys1) != mfdcr(cpc0_strp1) ) ){
+ puts("\n\t CPC0_SYSx DCRs corrupted. Resetting chip ...\n");
+ udelay( 1000 * 1000 ); /* Give time for serial buf to clear */
+ do_chip_reset( mfdcr(cpc0_strp0), mfdcr(cpc0_strp1) );
+ }
+ break;
+ case PVR_440GP_RC:
+ putc('C');
+ break;
+ default:
+ printf("UNKNOWN (PVR=%08x)", pvr);
+ break;
+ }
+#endif
+
+ printf("\n");
+
+ return 0;
+}
+
+
+/* ------------------------------------------------------------------------- */
+
+int do_reset (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[])
+{
+ /*
+ * Initiate system reset in debug control register DBCR
+ */
+ __asm__ __volatile__("lis 3, 0x3000" ::: "r3");
+#if defined(CONFIG_440)
+ __asm__ __volatile__("mtspr 0x134, 3");
+#else
+ __asm__ __volatile__("mtspr 0x3f2, 3");
+#endif
+ return 1;
+}
+
+#if defined(CONFIG_440)
+static
+int do_chip_reset( unsigned long sys0, unsigned long sys1 )
+{
+ /* Changes to cpc0_sys0 and cpc0_sys1 require chip
+ * reset.
+ */
+ mtdcr( cntrl0, mfdcr(cntrl0) | 0x80000000 ); /* Set SWE */
+ mtdcr( cpc0_sys0, sys0 );
+ mtdcr( cpc0_sys1, sys1 );
+ mtdcr( cntrl0, mfdcr(cntrl0) & ~0x80000000 ); /* Clr SWE */
+ mtspr( dbcr0, 0x20000000); /* Reset the chip */
+
+ return 1;
+}
+#endif
+
+
+/*
+ * Get timebase clock frequency
+ */
+unsigned long get_tbclk (void)
+{
+#if defined(CONFIG_440)
+
+ sys_info_t sys_info;
+
+ get_sys_info(&sys_info);
+ return (sys_info.freqProcessor);
+
+#elif defined(CONFIG_405GP) || defined(CONFIG_405CR) || defined(CONFIG_405)
+
+ PPC405_SYS_INFO sys_info;
+
+ get_sys_info(&sys_info);
+ return (sys_info.freqProcessor);
+
+#elif defined(CONFIG_IOP480)
+
+ return (66000000);
+
+#else
+
+# error get_tbclk() not implemented
+
+#endif
+
+}
+
+
+#if defined(CONFIG_WATCHDOG)
+void
+watchdog_reset(void)
+{
+ int re_enable = disable_interrupts();
+ reset_4xx_watchdog();
+ if (re_enable) enable_interrupts();
+}
+
+void
+reset_4xx_watchdog(void)
+{
+ /*
+ * Clear TSR(WIS) bit
+ */
+ mtspr(tsr, 0x40000000);
+}
+#endif /* CONFIG_WATCHDOG */
--- /dev/null
+/*****************************************************************************/
+/* I2C Bus interface initialisation and I2C Commands */
+/* for PPC405GP */
+/* Author : AS HARNOIS */
+/* Date : 13.Dec.00 */
+/*****************************************************************************/
+
+#include <common.h>
+#include <ppc4xx.h>
+#if defined(CONFIG_440)
+# include <440_i2c.h>
+#else
+# include <405gp_i2c.h>
+#endif
+#include <i2c.h>
+
+#ifdef CONFIG_HARD_I2C
+
+#define IIC_OK 0
+#define IIC_NOK 1
+#define IIC_NOK_LA 2 /* Lost arbitration */
+#define IIC_NOK_ICT 3 /* Incomplete transfer */
+#define IIC_NOK_XFRA 4 /* Transfer aborted */
+#define IIC_NOK_DATA 5 /* No data in buffer */
+#define IIC_NOK_TOUT 6 /* Transfer timeout */
+
+#define IIC_TIMEOUT 1 /* 1 seconde */
+
+
+static void _i2c_bus_reset (void)
+{
+ int i, status;
+
+ /* Reset status register */
+ /* write 1 in SCMP and IRQA to clear these fields */
+ out8 (IIC_STS, 0x0A);
+
+ /* write 1 in IRQP IRQD LA ICT XFRA to clear these fields */
+ out8 (IIC_EXTSTS, 0x8F);
+ __asm__ volatile ("eieio");
+
+ /*
+ * Get current state, reset bus
+ * only if no transfers are pending.
+ */
+ i = 10;
+ do {
+ /* Get status */
+ status = in8 (IIC_STS);
+ udelay (500); /* 500us */
+ i--;
+ } while ((status & IIC_STS_PT) && (i > 0));
+ /* Soft reset controller */
+ status = in8 (IIC_XTCNTLSS);
+ out8 (IIC_XTCNTLSS, (status | IIC_XTCNTLSS_SRST));
+ __asm__ volatile ("eieio");
+
+ /* make sure where in initial state, data hi, clock hi */
+ out8 (IIC_DIRECTCNTL, 0xC);
+ for (i = 0; i < 10; i++) {
+ if ((in8 (IIC_DIRECTCNTL) & 0x3) != 0x3) {
+ /* clock until we get to known state */
+ out8 (IIC_DIRECTCNTL, 0x8); /* clock lo */
+ udelay (100); /* 100us */
+ out8 (IIC_DIRECTCNTL, 0xC); /* clock hi */
+ udelay (100); /* 100us */
+ } else {
+ break;
+ }
+ }
+ /* send start condition */
+ out8 (IIC_DIRECTCNTL, 0x4);
+ udelay (1000); /* 1ms */
+ /* send stop condition */
+ out8 (IIC_DIRECTCNTL, 0xC);
+ udelay (1000); /* 1ms */
+ /* Unreset controller */
+ out8 (IIC_XTCNTLSS, (status & ~IIC_XTCNTLSS_SRST));
+ udelay (1000); /* 1ms */
+}
+
+void i2c_init (int speed, int slaveadd)
+{
+ sys_info_t sysInfo;
+ unsigned long freqOPB;
+ int val, divisor;
+
+ /* Handle possible failed I2C state */
+ _i2c_bus_reset ();
+
+ /* clear lo master address */
+ out8 (IIC_LMADR, 0);
+
+ /* clear hi master address */
+ out8 (IIC_HMADR, 0);
+
+ /* clear lo slave address */
+ out8 (IIC_LSADR, 0);
+
+ /* clear hi slave address */
+ out8 (IIC_HSADR, 0);
+
+ /* Clock divide Register */
+ /* get OPB frequency */
+ get_sys_info (&sysInfo);
+ freqOPB = sysInfo.freqPLB / sysInfo.pllOpbDiv;
+ /* set divisor according to freqOPB */
+ divisor = (freqOPB - 1) / 10000000;
+ if (divisor == 0)
+ divisor = 1;
+ out8 (IIC_CLKDIV, divisor);
+
+ /* no interrupts */
+ out8 (IIC_INTRMSK, 0);
+
+ /* clear transfer count */
+ out8 (IIC_XFRCNT, 0);
+
+ /* clear extended control & stat */
+ /* write 1 in SRC SRS SWC SWS to clear these fields */
+ out8 (IIC_XTCNTLSS, 0xF0);
+
+ /* Mode Control Register
+ Flush Slave/Master data buffer */
+ out8 (IIC_MDCNTL, IIC_MDCNTL_FSDB | IIC_MDCNTL_FMDB);
+ __asm__ volatile ("eieio");
+
+
+ val = in8(IIC_MDCNTL);
+ __asm__ volatile ("eieio");
+
+ /* Ignore General Call, slave transfers are ignored,
+ disable interrupts, exit unknown bus state, enable hold
+ SCL
+ 100kHz normaly or FastMode for 400kHz and above
+ */
+
+ val |= IIC_MDCNTL_EUBS|IIC_MDCNTL_HSCL;
+ if( speed >= 400000 ){
+ val |= IIC_MDCNTL_FSM;
+ }
+ out8 (IIC_MDCNTL, val);
+
+ /* clear control reg */
+ out8 (IIC_CNTL, 0x00);
+ __asm__ volatile ("eieio");
+
+}
+
+/*
+ This code tries to use the features of the 405GP i2c
+ controller. It will transfer up to 4 bytes in one pass
+ on the loop. It only does out8(lbz) to the buffer when it
+ is possible to do out16(lhz) transfers.
+
+ cmd_type is 0 for write 1 for read.
+
+ addr_len can take any value from 0-255, it is only limited
+ by the char, we could make it larger if needed. If it is
+ 0 we skip the address write cycle.
+
+ Typical case is a Write of an addr followd by a Read. The
+ IBM FAQ does not cover this. On the last byte of the write
+ we don't set the creg CHT bit, and on the first bytes of the
+ read we set the RPST bit.
+
+ It does not support address only transfers, there must be
+ a data part. If you want to write the address yourself, put
+ it in the data pointer.
+
+ It does not support transfer to/from address 0.
+
+ It does not check XFRCNT.
+*/
+static
+int i2c_transfer(unsigned char cmd_type,
+ unsigned char chip,
+ unsigned char addr[],
+ unsigned char addr_len,
+ unsigned char data[],
+ unsigned short data_len )
+{
+ unsigned char* ptr;
+ int reading;
+ int tran,cnt;
+ int result;
+ int status;
+ int i;
+ uchar creg;
+
+ if( data == 0 || data_len == 0 ){
+ /*Don't support data transfer of no length or to address 0*/
+ printf( "i2c_transfer: bad call\n" );
+ return IIC_NOK;
+ }
+ if( addr && addr_len ){
+ ptr = addr;
+ cnt = addr_len;
+ reading = 0;
+ }else{
+ ptr = data;
+ cnt = data_len;
+ reading = cmd_type;
+ }
+
+ /*Clear Stop Complete Bit*/
+ out8(IIC_STS,IIC_STS_SCMP);
+ /* Check init */
+ i=10;
+ do {
+ /* Get status */
+ status = in8(IIC_STS);
+ __asm__ volatile("eieio");
+ i--;
+ } while ((status & IIC_STS_PT) && (i>0));
+
+ if (status & IIC_STS_PT) {
+ result = IIC_NOK_TOUT;
+ return(result);
+ }
+ /*flush the Master/Slave Databuffers*/
+ out8(IIC_MDCNTL, ((in8(IIC_MDCNTL))|IIC_MDCNTL_FMDB|IIC_MDCNTL_FSDB));
+ /*need to wait 4 OPB clocks? code below should take that long*/
+
+ /* 7-bit adressing */
+ out8(IIC_HMADR,0);
+ out8(IIC_LMADR, chip);
+ __asm__ volatile("eieio");
+
+ tran = 0;
+ result = IIC_OK;
+ creg = 0;
+
+ while ( tran != cnt && (result == IIC_OK)) {
+ int bc,j;
+
+ /* Control register =
+ Normal transfer, 7-bits adressing, Transfer up to bc bytes, Normal start,
+ Transfer is a sequence of transfers
+ */
+ creg |= IIC_CNTL_PT;
+
+ bc = (cnt - tran) > 4 ? 4 :
+ cnt - tran;
+ creg |= (bc-1)<<4;
+ /* if the real cmd type is write continue trans*/
+ if ( (!cmd_type && (ptr == addr)) || ((tran+bc) != cnt) )
+ creg |= IIC_CNTL_CHT;
+
+ if (reading)
+ creg |= IIC_CNTL_READ;
+ else {
+ for(j=0; j<bc; j++) {
+ /* Set buffer */
+ out8(IIC_MDBUF,ptr[tran+j]);
+ __asm__ volatile("eieio");
+ }
+ }
+ out8(IIC_CNTL, creg );
+ __asm__ volatile("eieio");
+
+ /* Transfer is in progress
+ we have to wait for upto 5 bytes of data
+ 1 byte chip address+r/w bit then bc bytes
+ of data.
+ udelay(10) is 1 bit time at 100khz
+ Doubled for slop. 20 is too small.
+ */
+ i=2*5*8;
+ do {
+ /* Get status */
+ status = in8(IIC_STS);
+ __asm__ volatile("eieio");
+ udelay (10);
+ i--;
+ } while ((status & IIC_STS_PT) && !(status & IIC_STS_ERR)
+ && (i>0));
+
+ if (status & IIC_STS_ERR) {
+ result = IIC_NOK;
+ status = in8 (IIC_EXTSTS);
+ /* Lost arbitration? */
+ if (status & IIC_EXTSTS_LA)
+ result = IIC_NOK_LA;
+ /* Incomplete transfer? */
+ if (status & IIC_EXTSTS_ICT)
+ result = IIC_NOK_ICT;
+ /* Transfer aborted? */
+ if (status & IIC_EXTSTS_XFRA)
+ result = IIC_NOK_XFRA;
+ } else if ( status & IIC_STS_PT) {
+ result = IIC_NOK_TOUT;
+ }
+ /* Command is reading => get buffer */
+ if ((reading) && (result == IIC_OK)) {
+ /* Are there data in buffer */
+ if (status & IIC_STS_MDBS) {
+ /*
+ even if we have data we have to wait 4OPB clocks
+ for it to hit the front of the FIFO, after that
+ we can just read. We should check XFCNT here and
+ if the FIFO is full there is no need to wait.
+ */
+ udelay (1);
+ for(j=0;j<bc;j++) {
+ ptr[tran+j] = in8(IIC_MDBUF);
+ __asm__ volatile("eieio");
+ }
+ } else
+ result = IIC_NOK_DATA;
+ }
+ creg = 0;
+ tran+=bc;
+ if( ptr == addr && tran == cnt ) {
+ ptr = data;
+ cnt = data_len;
+ tran = 0;
+ reading = cmd_type;
+ if( reading )
+ creg = IIC_CNTL_RPST;
+ }
+ }
+ return (result);
+}
+
+int i2c_probe (uchar chip)
+{
+ uchar buf[1];
+
+ buf[0] = 0;
+
+ /*
+ * What is needed is to send the chip address and verify that the
+ * address was <ACK>ed (i.e. there was a chip at that address which
+ * drove the data line low).
+ */
+ return(i2c_transfer (1, chip << 1, 0,0, buf, 1) != 0);
+}
+
+
+
+int i2c_read (uchar chip, uint addr, int alen, uchar * buffer, int len)
+{
+ uchar xaddr[4];
+ int ret;
+
+ if ( alen > 4 ) {
+ printf ("I2C read: addr len %d not supported\n", alen);
+ return 1;
+ }
+
+ if ( alen > 0 ) {
+ xaddr[0] = (addr >> 24) & 0xFF;
+ xaddr[1] = (addr >> 16) & 0xFF;
+ xaddr[2] = (addr >> 8) & 0xFF;
+ xaddr[3] = addr & 0xFF;
+ }
+
+
+#ifdef CFG_I2C_EEPROM_ADDR_OVERFLOW
+ /*
+ * EEPROM chips that implement "address overflow" are ones
+ * like Catalyst 24WC04/08/16 which has 9/10/11 bits of
+ * address and the extra bits end up in the "chip address"
+ * bit slots. This makes a 24WC08 (1Kbyte) chip look like
+ * four 256 byte chips.
+ *
+ * Note that we consider the length of the address field to
+ * still be one byte because the extra address bits are
+ * hidden in the chip address.
+ */
+ if( alen > 0 )
+ chip |= ((addr >> (alen * 8)) & CFG_I2C_EEPROM_ADDR_OVERFLOW);
+#endif
+ if( (ret = i2c_transfer( 1, chip<<1, &xaddr[4-alen], alen, buffer, len )) != 0) {
+ printf( "I2c read: failed %d\n", ret);
+ return 1;
+ }
+ return 0;
+}
+
+int i2c_write (uchar chip, uint addr, int alen, uchar * buffer, int len)
+{
+ uchar xaddr[4];
+
+ if ( alen > 4 ) {
+ printf ("I2C write: addr len %d not supported\n", alen);
+ return 1;
+
+ }
+ if ( alen > 0 ) {
+ xaddr[0] = (addr >> 24) & 0xFF;
+ xaddr[1] = (addr >> 16) & 0xFF;
+ xaddr[2] = (addr >> 8) & 0xFF;
+ xaddr[3] = addr & 0xFF;
+ }
+
+#ifdef CFG_I2C_EEPROM_ADDR_OVERFLOW
+ /*
+ * EEPROM chips that implement "address overflow" are ones
+ * like Catalyst 24WC04/08/16 which has 9/10/11 bits of
+ * address and the extra bits end up in the "chip address"
+ * bit slots. This makes a 24WC08 (1Kbyte) chip look like
+ * four 256 byte chips.
+ *
+ * Note that we consider the length of the address field to
+ * still be one byte because the extra address bits are
+ * hidden in the chip address.
+ */
+ if( alen > 0 )
+ chip |= ((addr >> (alen * 8)) & CFG_I2C_EEPROM_ADDR_OVERFLOW);
+#endif
+
+ return (i2c_transfer( 0, chip<<1, &xaddr[4-alen], alen, buffer, len ) != 0);
+}
+
+#endif /* CONFIG_HARD_I2C */
--- /dev/null
+/*
+ * (C) Copyright 2002
+ * Stefan Roese, esd gmbh germany, stefan.roese@esd-electronics.com
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <ppc4xx.h>
+#include <asm/processor.h>
+#include <pci.h>
+
+
+#ifdef CONFIG_SDRAM_BANK0
+
+
+#define MAGIC0 0x00000000
+#define MAGIC1 0x11111111
+#define MAGIC2 0x22222222
+#define MAGIC3 0x33333333
+#define MAGIC4 0x44444444
+
+#define ADDR_ZERO 0x00000000
+#define ADDR_400 0x00000400
+#define ADDR_08MB 0x00800000
+#define ADDR_16MB 0x01000000
+#define ADDR_32MB 0x02000000
+#define ADDR_64MB 0x04000000
+
+#define mtsdram0(reg, data) mtdcr(memcfga,reg);mtdcr(memcfgd,data)
+
+
+/*-----------------------------------------------------------------------
+ */
+void sdram_init(void)
+{
+ ulong speed;
+ ulong sdtr1;
+ ulong rtr;
+
+ /*
+ * Determine SDRAM speed
+ */
+ speed = get_bus_freq(0); /* parameter not used on ppc4xx */
+
+ /*
+ * Support for 100MHz and 133MHz SDRAM
+ */
+ if (speed > 100000000) {
+ /*
+ * 133 MHz SDRAM
+ */
+ sdtr1 = 0x01074015;
+ rtr = 0x07f00000;
+ } else {
+ /*
+ * default: 100 MHz SDRAM
+ */
+ sdtr1 = 0x0086400d;
+ rtr = 0x05f00000;
+ }
+
+ /*
+ * Set MB0CF for bank 0. (0-64MB) Address Mode 3 since 13x9(4)
+ */
+ mtsdram0(mem_mb0cf, 0x00084001);
+
+ mtsdram0(mem_sdtr1, sdtr1);
+ mtsdram0(mem_rtr, rtr);
+
+ /*
+ * Wait for 200us
+ */
+ udelay(200);
+
+ /*
+ * Set memory controller options reg, MCOPT1.
+ * Set DC_EN to '1' and BRD_PRF to '01' for 16 byte PLB Burst
+ * read/prefetch.
+ */
+ mtsdram0(mem_mcopt1, 0x80800000);
+
+ /*
+ * Wait for 10ms
+ */
+ udelay(10000);
+
+ /*
+ * Test if 64 MByte are equipped (mirror test)
+ */
+ *(volatile ulong *)ADDR_ZERO = MAGIC0;
+ *(volatile ulong *)ADDR_08MB = MAGIC1;
+ *(volatile ulong *)ADDR_16MB = MAGIC2;
+ *(volatile ulong *)ADDR_32MB = MAGIC3;
+
+ if ((*(volatile ulong *)ADDR_ZERO == MAGIC0) &&
+ (*(volatile ulong *)ADDR_08MB == MAGIC1) &&
+ (*(volatile ulong *)ADDR_16MB == MAGIC2)) {
+ /*
+ * OK, 64MB detected -> all done
+ */
+ return;
+ }
+
+ /*
+ * Now test for 32 MByte...
+ */
+
+ /*
+ * Disable memory controller.
+ */
+ mtsdram0(mem_mcopt1, 0x00000000);
+
+ /*
+ * Set MB0CF for bank 0. (0-32MB) Address Mode 2 since 12x9(4)
+ */
+ mtsdram0(mem_mb0cf, 0x00062001);
+
+ /*
+ * Set memory controller options reg, MCOPT1.
+ * Set DC_EN to '1' and BRD_PRF to '01' for 16 byte PLB Burst
+ * read/prefetch.
+ */
+ mtsdram0(mem_mcopt1, 0x80800000);
+
+ /*
+ * Wait for 10ms
+ */
+ udelay(10000);
+
+ /*
+ * Test if 32 MByte are equipped (mirror test)
+ */
+ *(volatile ulong *)ADDR_ZERO = MAGIC0;
+ *(volatile ulong *)ADDR_400 = MAGIC1;
+ *(volatile ulong *)ADDR_08MB = MAGIC2;
+ *(volatile ulong *)ADDR_16MB = MAGIC3;
+
+ if ((*(volatile ulong *)ADDR_ZERO == MAGIC0) &&
+ (*(volatile ulong *)ADDR_400 == MAGIC1) &&
+ (*(volatile ulong *)ADDR_08MB == MAGIC2)) {
+ /*
+ * OK, 32MB detected -> all done
+ */
+ return;
+ }
+
+ /*
+ * Setup for 16 MByte...
+ */
+
+ /*
+ * Disable memory controller.
+ */
+ mtsdram0(mem_mcopt1, 0x00000000);
+
+ /*
+ * Set MB0CF for bank 0. (0-16MB) Address Mode 4 since 12x8(4)
+ */
+ mtsdram0(mem_mb0cf, 0x00046001);
+
+ /*
+ * Set memory controller options reg, MCOPT1.
+ * Set DC_EN to '1' and BRD_PRF to '01' for 16 byte PLB Burst
+ * read/prefetch.
+ */
+ mtsdram0(mem_mcopt1, 0x80800000);
+
+ /*
+ * Wait for 10ms
+ */
+ udelay(10000);
+}
+
+#endif /* CONFIG_SDRAM_BANK0 */
--- /dev/null
+/*
+ * (C) Copyright 2000
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <ppc_asm.tmpl>
+#include <ppc4xx.h>
+#include <asm/processor.h>
+
+/* ------------------------------------------------------------------------- */
+
+#define ONE_BILLION 1000000000
+
+
+#if defined(CONFIG_405GP) || defined(CONFIG_405CR)
+
+void get_sys_info (PPC405_SYS_INFO * sysInfo)
+{
+ unsigned long pllmr;
+ unsigned long sysClkPeriodPs = ONE_BILLION / (CONFIG_SYS_CLK_FREQ / 1000);
+ uint pvr = get_pvr();
+ unsigned long psr;
+ unsigned long m;
+
+ /*
+ * Read PLL Mode register
+ */
+ pllmr = mfdcr (pllmd);
+
+ /*
+ * Read Pin Strapping register
+ */
+ psr = mfdcr (strap);
+
+ /*
+ * Determine FWD_DIV.
+ */
+ sysInfo->pllFwdDiv = 8 - ((pllmr & PLLMR_FWD_DIV_MASK) >> 29);
+
+ /*
+ * Determine FBK_DIV.
+ */
+ sysInfo->pllFbkDiv = ((pllmr & PLLMR_FB_DIV_MASK) >> 25);
+ if (sysInfo->pllFbkDiv == 0) {
+ sysInfo->pllFbkDiv = 16;
+ }
+
+ /*
+ * Determine PLB_DIV.
+ */
+ sysInfo->pllPlbDiv = ((pllmr & PLLMR_CPU_TO_PLB_MASK) >> 17) + 1;
+
+ /*
+ * Determine PCI_DIV.
+ */
+ sysInfo->pllPciDiv = ((pllmr & PLLMR_PCI_TO_PLB_MASK) >> 13) + 1;
+
+ /*
+ * Determine EXTBUS_DIV.
+ */
+ sysInfo->pllExtBusDiv = ((pllmr & PLLMR_EXB_TO_PLB_MASK) >> 11) + 2;
+
+ /*
+ * Determine OPB_DIV.
+ */
+ sysInfo->pllOpbDiv = ((pllmr & PLLMR_OPB_TO_PLB_MASK) >> 15) + 1;
+
+ /*
+ * Check if PPC405GPr used (mask minor revision field)
+ */
+ if ((pvr & 0xfffffff0) == (PVR_405GPR_RA & 0xfffffff0)) {
+ /*
+ * Determine FWD_DIV B (only PPC405GPr with new mode strapping).
+ */
+ sysInfo->pllFwdDivB = 8 - (pllmr & PLLMR_FWDB_DIV_MASK);
+
+ /*
+ * Determine factor m depending on PLL feedback clock source
+ */
+ if (!(psr & PSR_PCI_ASYNC_EN)) {
+ if (psr & PSR_NEW_MODE_EN) {
+ /*
+ * sync pci clock used as feedback (new mode)
+ */
+ m = 1 * sysInfo->pllFwdDivB * 2 * sysInfo->pllPciDiv;
+ } else {
+ /*
+ * sync pci clock used as feedback (legacy mode)
+ */
+ m = 1 * sysInfo->pllFwdDivB * sysInfo->pllPlbDiv * sysInfo->pllPciDiv;
+ }
+ } else if (psr & PSR_NEW_MODE_EN) {
+ if (psr & PSR_PERCLK_SYNC_MODE_EN) {
+ /*
+ * PerClk used as feedback (new mode)
+ */
+ m = 1 * sysInfo->pllFwdDivB * 2 * sysInfo->pllExtBusDiv;
+ } else {
+ /*
+ * CPU clock used as feedback (new mode)
+ */
+ m = sysInfo->pllFbkDiv * sysInfo->pllFwdDiv;
+ }
+ } else if (sysInfo->pllExtBusDiv == sysInfo->pllFbkDiv) {
+ /*
+ * PerClk used as feedback (legacy mode)
+ */
+ m = 1 * sysInfo->pllFwdDivB * sysInfo->pllPlbDiv * sysInfo->pllExtBusDiv;
+ } else {
+ /*
+ * PLB clock used as feedback (legacy mode)
+ */
+ m = sysInfo->pllFbkDiv * sysInfo->pllFwdDivB * sysInfo->pllPlbDiv;
+ }
+
+ sysInfo->freqVCOMhz = (1000000 * m) / sysClkPeriodPs;
+ sysInfo->freqProcessor = (sysInfo->freqVCOMhz * 1000000) / sysInfo->pllFwdDiv;
+ sysInfo->freqPLB = (sysInfo->freqVCOMhz * 1000000) /
+ (sysInfo->pllFwdDivB * sysInfo->pllPlbDiv);
+ } else {
+ /*
+ * Check pllFwdDiv to see if running in bypass mode where the CPU speed
+ * is equal to the 405GP SYS_CLK_FREQ. If not in bypass mode, check VCO
+ * to make sure it is within the proper range.
+ * spec: VCO = SYS_CLOCK x FBKDIV x PLBDIV x FWDDIV
+ * Note freqVCO is calculated in Mhz to avoid errors introduced by rounding.
+ */
+ if (sysInfo->pllFwdDiv == 1) {
+ sysInfo->freqProcessor = CONFIG_SYS_CLK_FREQ;
+ sysInfo->freqPLB = CONFIG_SYS_CLK_FREQ / sysInfo->pllPlbDiv;
+ } else {
+ sysInfo->freqVCOMhz = ( 1000000 *
+ sysInfo->pllFwdDiv *
+ sysInfo->pllFbkDiv *
+ sysInfo->pllPlbDiv
+ ) / sysClkPeriodPs;
+ if (sysInfo->freqVCOMhz >= VCO_MIN
+ && sysInfo->freqVCOMhz <= VCO_MAX) {
+ sysInfo->freqPLB = (ONE_BILLION /
+ ((sysClkPeriodPs * 10) /
+ sysInfo->pllFbkDiv)) * 10000;
+ sysInfo->freqProcessor = sysInfo->freqPLB * sysInfo->pllPlbDiv;
+ } else {
+ printf ("\nInvalid VCO frequency calculated : %ld MHz \a\n",
+ sysInfo->freqVCOMhz);
+ printf ("It must be between %d-%d MHz \a\n",
+ VCO_MIN, VCO_MAX);
+ printf ("PLL Mode reg : %8.8lx\a\n",
+ pllmr);
+ hang ();
+ }
+ }
+ }
+}
+
+
+/********************************************
+ * get_OPB_freq
+ * return OPB bus freq in Hz
+ *********************************************/
+ulong get_OPB_freq (void)
+{
+ ulong val = 0;
+
+ PPC405_SYS_INFO sys_info;
+
+ get_sys_info (&sys_info);
+ val = sys_info.freqPLB / sys_info.pllOpbDiv;
+
+ return val;
+}
+
+
+/********************************************
+ * get_PCI_freq
+ * return PCI bus freq in Hz
+ *********************************************/
+ulong get_PCI_freq (void)
+{
+ ulong val;
+ PPC405_SYS_INFO sys_info;
+
+ get_sys_info (&sys_info);
+ val = sys_info.freqPLB / sys_info.pllPciDiv;
+ return val;
+}
+
+
+#elif defined(CONFIG_440)
+void get_sys_info (sys_info_t * sysInfo)
+{
+ unsigned long strp0;
+ unsigned long temp;
+ unsigned long m;
+
+ /* Extract configured divisors */
+ strp0 = mfdcr( cpc0_strp0 );
+ sysInfo->pllFwdDivA = 8 - ((strp0 & PLLSYS0_FWD_DIV_A_MASK) >> 15);
+ sysInfo->pllFwdDivB = 8 - ((strp0 & PLLSYS0_FWD_DIV_B_MASK) >> 12);
+ temp = (strp0 & PLLSYS0_FB_DIV_MASK) >> 18;
+ sysInfo->pllFbkDiv = temp ? temp : 16;
+ sysInfo->pllOpbDiv = 1 + ((strp0 & PLLSYS0_OPB_DIV_MASK) >> 10);
+ sysInfo->pllExtBusDiv = 1 + ((strp0 & PLLSYS0_EPB_DIV_MASK) >> 8);
+
+ /* Calculate 'M' based on feedback source */
+ if( strp0 & PLLSYS0_EXTSL_MASK )
+ m = sysInfo->pllExtBusDiv * sysInfo->pllOpbDiv * sysInfo->pllFwdDivB;
+ else
+ m = sysInfo->pllFbkDiv * sysInfo->pllFwdDivA;
+
+ /* Now calculate the individual clocks */
+ sysInfo->freqVCOMhz = (m * CONFIG_SYS_CLK_FREQ) + (m>>1);
+ sysInfo->freqProcessor = sysInfo->freqVCOMhz/sysInfo->pllFwdDivA;
+ sysInfo->freqPLB = sysInfo->freqVCOMhz/sysInfo->pllFwdDivB;
+ if( get_pvr() == PVR_440GP_RB ) /* Rev B divs an extra 2 -- geez! */
+ sysInfo->freqPLB >>= 1;
+ sysInfo->freqOPB = sysInfo->freqPLB/sysInfo->pllOpbDiv;
+ sysInfo->freqEPB = sysInfo->freqOPB/sysInfo->pllExtBusDiv;
+
+}
+
+ulong get_OPB_freq (void)
+{
+
+ sys_info_t sys_info;
+ get_sys_info (&sys_info);
+ return sys_info.freqOPB;
+}
+
+#elif defined(CONFIG_405)
+
+void get_sys_info (sys_info_t * sysInfo) {
+
+ sysInfo->freqVCOMhz=3125000;
+ sysInfo->freqProcessor=12*1000*1000;
+ sysInfo->freqPLB=50*1000*1000;
+ sysInfo->freqPCI=66*1000*1000;
+
+}
+
+#endif
+
+int get_clocks (void)
+{
+#if defined(CONFIG_405GP) || defined(CONFIG_405CR) || defined(CONFIG_440) || defined(CONFIG_405)
+ DECLARE_GLOBAL_DATA_PTR;
+
+ sys_info_t sys_info;
+
+ get_sys_info (&sys_info);
+ gd->cpu_clk = sys_info.freqProcessor;
+ gd->bus_clk = sys_info.freqPLB;
+
+#endif /* defined(CONFIG_405GP) || defined(CONFIG_405CR) */
+
+#ifdef CONFIG_IOP480
+ DECLARE_GLOBAL_DATA_PTR;
+
+ gd->cpu_clk = 66000000;
+ gd->bus_clk = 66000000;
+#endif
+ return (0);
+}
+
+
+/********************************************
+ * get_bus_freq
+ * return PLB bus freq in Hz
+ *********************************************/
+ulong get_bus_freq (ulong dummy)
+{
+ ulong val;
+
+#if defined(CONFIG_405GP) || defined(CONFIG_405CR) || defined(CONFIG_405) || defined(CONFIG_440)
+ sys_info_t sys_info;
+
+ get_sys_info (&sys_info);
+ val = sys_info.freqPLB;
+
+#elif defined(CONFIG_IOP480)
+
+ val = 66;
+
+#else
+# error get_bus_freq() not implemented
+#endif
+
+ return val;
+}
--- /dev/null
+/*
+* Copyright (C) 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
+*/
+
+/*
+ * Interrupt vector number definitions to ease the
+ * 405 -- 440 porting pain ;-)
+ *
+ * NOTE: They're not all here yet ... update as needed.
+ *
+ */
+
+#ifndef _VECNUMS_H_
+#define _VECNUMS_H_
+
+#if defined(CONFIG_440)
+
+/* UIC 0 */
+#define VECNUM_U0 0 /* UART0 */
+#define VECNUM_U1 1 /* UART1 */
+#define VECNUM_IIC0 2 /* IIC0 */
+#define VECNUM_IIC1 3 /* IIC1 */
+#define VECNUM_PIM 4 /* PCI inbound message */
+#define VECNUM_PCRW 5 /* PCI command reg write */
+#define VECNUM_PPM 6 /* PCI power management */
+#define VECNUM_MSI0 7 /* PCI MSI level 0 */
+#define VECNUM_MSI1 8 /* PCI MSI level 0 */
+#define VECNUM_MSI2 9 /* PCI MSI level 0 */
+#define VECNUM_MTE 10 /* MAL TXEOB */
+#define VECNUM_MRE 11 /* MAL RXEOB */
+#define VECNUM_D0 12 /* DMA channel 0 */
+#define VECNUM_D1 13 /* DMA channel 1 */
+#define VECNUM_D2 14 /* DMA channel 2 */
+#define VECNUM_D3 15 /* DMA channel 3 */
+#define VECNUM_CT0 18 /* GPT compare timer 0 */
+#define VECNUM_CT1 19 /* GPT compare timer 1 */
+#define VECNUM_CT2 20 /* GPT compare timer 2 */
+#define VECNUM_CT3 21 /* GPT compare timer 3 */
+#define VECNUM_CT4 22 /* GPT compare timer 4 */
+#define VECNUM_EIR0 23 /* External interrupt 0 */
+#define VECNUM_EIR1 24 /* External interrupt 1 */
+#define VECNUM_EIR2 25 /* External interrupt 2 */
+#define VECNUM_EIR3 26 /* External interrupt 3 */
+#define VECNUM_EIR4 27 /* External interrupt 4 */
+#define VECNUM_EIR5 28 /* External interrupt 5 */
+#define VECNUM_EIR6 29 /* External interrupt 6 */
+#define VECNUM_UIC1NC 30 /* UIC1 non-critical interrupt */
+#define VECNUM_UIC1C 31 /* UIC1 critical interrupt */
+
+/* UIC 1 */
+#define VECNUM_MS (32 + 0 ) /* MAL SERR */
+#define VECNUM_TXDE (32 + 1 ) /* MAL TXDE */
+#define VECNUM_RXDE (32 + 2 ) /* MAL RXDE */
+#define VECNUM_ETH0 (32 + 28) /* Ethernet 0 interrupt status */
+#define VECNUM_EWU0 (32 + 29) /* Ethernet 0 wakeup */
+
+#else /* !defined(CONFIG_440) */
+
+#define VECNUM_U0 0 /* UART0 */
+#define VECNUM_U1 1 /* UART1 */
+#define VECNUM_D0 5 /* DMA channel 0 */
+#define VECNUM_D1 6 /* DMA channel 1 */
+#define VECNUM_D2 7 /* DMA channel 2 */
+#define VECNUM_D3 8 /* DMA channel 3 */
+#define VECNUM_EWU0 9 /* Ethernet wakeup */
+#define VECNUM_MS 10 /* MAL SERR */
+#define VECNUM_MTE 11 /* MAL TXEOB */
+#define VECNUM_MRE 12 /* MAL RXEOB */
+#define VECNUM_TXDE 13 /* MAL TXDE */
+#define VECNUM_RXDE 14 /* MAL RXDE */
+#define VECNUM_ETH0 15 /* Ethernet interrupt status */
+#define VECNUM_EIR0 25 /* External interrupt 0 */
+#define VECNUM_EIR1 26 /* External interrupt 1 */
+#define VECNUM_EIR2 27 /* External interrupt 2 */
+#define VECNUM_EIR3 28 /* External interrupt 3 */
+#define VECNUM_EIR4 29 /* External interrupt 4 */
+#define VECNUM_EIR5 30 /* External interrupt 5 */
+#define VECNUM_EIR6 31 /* External interrupt 6 */
+
+#endif /* defined(CONFIG_440) */
+
+#endif /* _VECNUMS_H_ */
--- /dev/null
+#
+# (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 = serial.o interrupts.o cpu.o
+
+all: .depend $(START) $(LIB)
+
+$(LIB): $(OBJS)
+ $(AR) crv $@ $(OBJS)
+
+#########################################################################
+
+.depend: Makefile $(START:.o=.S) $(OBJS:.o=.c)
+ $(CC) -M $(CFLAGS) $(START:.o=.S) $(OBJS:.o=.c) > $@
+
+sinclude .depend
+
+#########################################################################
--- /dev/null
+/*
+ * (C) Copyright 2002
+ * Wolfgang Denk, DENX Software Engineering, <wd@denx.de>
+ *
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Marius Groeger <mgroeger@sysgo.de>
+ *
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Alex Zuepke <azu@sysgo.de>
+ *
+ * Copyright (C) 1999 2000 2001 Erik Mouw (J.A.K.Mouw@its.tudelft.nl)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <common.h>
+#include <asm/arch/pxa-regs.h>
+
+void serial_setbrg (void)
+{
+ DECLARE_GLOBAL_DATA_PTR;
+
+ unsigned int quot = 0;
+
+ if (gd->baudrate == 1200)
+ quot = 192;
+ else if (gd->baudrate == 9600)
+ quot = 96;
+ else if (gd->baudrate == 19200)
+ quot = 48;
+ else if (gd->baudrate == 38400)
+ quot = 24;
+ else if (gd->baudrate == 57600)
+ quot = 16;
+ else if (gd->baudrate == 115200)
+ quot = 8;
+ else
+ hang ();
+
+#ifdef CONFIG_FFUART
+
+ CKEN |= CKEN6_FFUART;
+
+ FFIER = 0; /* Disable for now */
+ FFFCR = 0; /* No fifos enabled */
+
+ /* set baud rate */
+ FFLCR = LCR_WLS0 | LCR_WLS1 | LCR_DLAB;
+ FFDLL = quot & 0xff;
+ FFDLH = quot >> 8;
+ FFLCR = LCR_WLS0 | LCR_WLS1;
+
+ FFIER = IER_UUE; /* Enable FFUART */
+
+#elif CONFIG_STUART
+#error "Bad: not implemented yet!"
+#else
+#error "Bad: you didn't configured serial ..."
+#endif
+}
+
+
+/*
+ * Initialise the serial port with the given baudrate. The settings
+ * are always 8 data bits, no parity, 1 stop bit, no start bits.
+ *
+ */
+int serial_init (void)
+{
+ serial_setbrg ();
+
+ return (0);
+}
+
+
+/*
+ * Output a single byte to the serial port.
+ */
+void serial_putc (const char c)
+{
+#ifdef CONFIG_FFUART
+ /* wait for room in the tx FIFO on FFUART */
+ while ((FFLSR & LSR_TEMT) == 0);
+
+ FFTHR = c;
+#elif CONFIG_STUART
+#endif
+
+ /* If \n, also do \r */
+ if (c == '\n')
+ serial_putc ('\r');
+}
+
+/*
+ * Read a single byte from the serial port. Returns 1 on success, 0
+ * otherwise. When the function is succesfull, the character read is
+ * written into its argument c.
+ */
+int serial_tstc (void)
+{
+#ifdef CONFIG_FFUART
+ return FFLSR & LSR_DR;
+#elif CONFIG_STUART
+#endif
+}
+
+/*
+ * Read a single byte from the serial port. Returns 1 on success, 0
+ * otherwise. When the function is succesfull, the character read is
+ * written into its argument c.
+ */
+int serial_getc (void)
+{
+#ifdef CONFIG_FFUART
+ while (!(FFLSR & LSR_DR));
+
+ return (char) FFRBR & 0xff;
+#elif CONFIG_STUART
+#endif
+}
+
+void
+serial_puts (const char *s)
+{
+ while (*s) {
+ serial_putc (*s++);
+ }
+}
--- /dev/null
+/*
+ * armboot - Startup Code for XScale
+ *
+ * Copyright (C) 1998 Dan Malek <dmalek@jlc.net>
+ * Copyright (C) 1999 Magnus Damm <kieraypc01.p.y.kie.era.ericsson.se>
+ * Copyright (C) 2000 Wolfgang Denk <wd@denx.de>
+ * Copyright (c) 2001 Alex Züpke <azu@sysgo.de>
+ * Copyright (c) 2002 Kyle Harris <kharris@nexus-tech.net>
+ *
+ * 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>
+
+.globl _start
+_start: b reset
+ ldr pc, _undefined_instruction
+ ldr pc, _software_interrupt
+ ldr pc, _prefetch_abort
+ ldr pc, _data_abort
+ ldr pc, _not_used
+ ldr pc, _irq
+ ldr pc, _fiq
+
+_undefined_instruction: .word undefined_instruction
+_software_interrupt: .word software_interrupt
+_prefetch_abort: .word prefetch_abort
+_data_abort: .word data_abort
+_not_used: .word not_used
+_irq: .word irq
+_fiq: .word fiq
+
+ .balignl 16,0xdeadbeef
+
+
+/*
+ * Startup Code (reset vector)
+ *
+ * do important init only if we don't start from memory!
+ * - relocate armboot to ram
+ * - setup stack
+ * - jump to second stage
+ */
+
+/*
+ * CFG_MEM_END is in the board dependent config-file (configs/config_BOARD.h)
+ */
+_TEXT_BASE:
+ .word TEXT_BASE
+
+.globl _armboot_start
+_armboot_start:
+ .word _start
+
+/*
+ * Note: _armboot_end_data and _armboot_end are defined
+ * by the (board-dependent) linker script.
+ * _armboot_end_data is the first usable FLASH address after armboot
+ */
+.globl _armboot_end_data
+_armboot_end_data:
+ .word armboot_end_data
+.globl _armboot_end
+_armboot_end:
+ .word armboot_end
+
+/*
+ * _armboot_real_end is the first usable RAM address behind armboot
+ * and the various stacks
+ */
+.globl _armboot_real_end
+_armboot_real_end:
+ .word 0x0badc0de
+
+/*
+ * We relocate uboot to this address (end of RAM - 128 KiB)
+ */
+.globl _uboot_reloc
+_uboot_reloc:
+ .word CFG_DRAM_BASE + CFG_DRAM_SIZE - CFG_MONITOR_LEN
+
+#ifdef CONFIG_USE_IRQ
+/* IRQ stack memory (calculated at run-time) */
+.globl IRQ_STACK_START
+IRQ_STACK_START:
+ .word 0x0badc0de
+
+/* IRQ stack memory (calculated at run-time) */
+.globl FIQ_STACK_START
+FIQ_STACK_START:
+ .word 0x0badc0de
+#endif
+
+
+/****************************************************************************/
+/* */
+/* the actual reset code */
+/* */
+/****************************************************************************/
+
+reset:
+ mrs r0,cpsr /* set the cpu to SVC32 mode */
+ bic r0,r0,#0x1f /* (superviser mode, M=10011) */
+ orr r0,r0,#0x13
+ msr cpsr,r0
+
+ bl cpu_init_crit /* we do sys-critical inits */
+
+relocate: /* relocate U-Boot to RAM */
+ adr r0, _start /* r0 <- current position of code */
+ ldr r2, _armboot_start
+ ldr r3, _armboot_end
+ sub r2, r3, r2 /* r2 <- size of armboot */
+/* ldr r1, _uboot_reloc / * r1 <- destination address */
+ ldr r1, _TEXT_BASE
+ add r2, r0, r2 /* r2 <- source end address */
+
+copy_loop:
+ ldmia r0!, {r3-r10} /* copy from source address [r0] */
+ stmia r1!, {r3-r10} /* copy to target address [r1] */
+ cmp r0, r2 /* until source end addreee [r2] */
+ ble copy_loop
+
+ /* Set up the stack */
+ ldr r0, _uboot_reloc /* upper 128 KiB: relocated uboot */
+ sub r0, r0, #CFG_MALLOC_LEN /* malloc area */
+ /* FIXME: bdinfo should be here */
+ sub sp, r0, #12 /* leave 3 words for abort-stack */
+
+ ldr pc, _start_armboot
+
+_start_armboot: .word start_armboot
+
+
+/****************************************************************************/
+/* */
+/* CPU_init_critical registers */
+/* */
+/* - setup important registers */
+/* - setup memory timing */
+/* */
+/****************************************************************************/
+
+ /* Interrupt-Controller base address */
+IC_BASE: .word 0x40d00000
+#define ICMR 0x04
+
+/* Reset-Controller */
+RST_BASE: .word 0x40f00030
+#define RCSR 0x00
+
+
+ /* Clock Manager Registers */
+CC_BASE: .word 0x41300000
+#define CCCR 0x00
+cpuspeed: .word CFG_CPUSPEED
+
+ /* RS: ??? */
+ .macro CPWAIT
+ mrc p15,0,r0,c2,c0,0
+ mov r0,r0
+ sub pc,pc,#4
+ .endm
+
+
+cpu_init_crit:
+
+ /* mask all IRQs */
+ ldr r0, IC_BASE
+ mov r1, #0x00
+ str r1, [r0, #ICMR]
+
+ /* set clock speed */
+ ldr r0, CC_BASE
+ ldr r1, cpuspeed
+ str r1, [r0, #CCCR]
+
+ /*
+ * before relocating, we have to setup RAM timing
+ * because memory timing is board-dependend, you will
+ * find a memsetup.S in your board directory.
+ */
+ mov ip, lr
+ bl memsetup
+ mov lr, ip
+
+ /* Memory interfaces are working. Disable MMU and enable I-cache. */
+
+ ldr r0, =0x2001 /* enable access to all coproc. */
+ mcr p15, 0, r0, c15, c1, 0
+ CPWAIT
+
+ mcr p15, 0, r0, c7, c10, 4 /* drain the write & fill buffers */
+ CPWAIT
+
+ mcr p15, 0, r0, c7, c7, 0 /* flush Icache, Dcache and BTB */
+ CPWAIT
+
+ mcr p15, 0, r0, c8, c7, 0 /* flush instuction and data TLBs */
+ CPWAIT
+
+ /* Enable the Icache */
+/*
+ mrc p15, 0, r0, c1, c0, 0
+ orr r0, r0, #0x1800
+ mcr p15, 0, r0, c1, c0, 0
+ CPWAIT
+*/
+ mov pc, lr
+
+
+/****************************************************************************/
+/* */
+/* Interrupt handling */
+/* */
+/****************************************************************************/
+
+/* IRQ stack frame */
+
+#define S_FRAME_SIZE 72
+
+#define S_OLD_R0 68
+#define S_PSR 64
+#define S_PC 60
+#define S_LR 56
+#define S_SP 52
+
+#define S_IP 48
+#define S_FP 44
+#define S_R10 40
+#define S_R9 36
+#define S_R8 32
+#define S_R7 28
+#define S_R6 24
+#define S_R5 20
+#define S_R4 16
+#define S_R3 12
+#define S_R2 8
+#define S_R1 4
+#define S_R0 0
+
+#define MODE_SVC 0x13
+
+ /* use bad_save_user_regs for abort/prefetch/undef/swi ... */
+
+ .macro bad_save_user_regs
+ sub sp, sp, #S_FRAME_SIZE
+ stmia sp, {r0 - r12} /* Calling r0-r12 */
+ add r8, sp, #S_PC
+
+ ldr r2, _armboot_end
+ add r2, r2, #CONFIG_STACKSIZE
+ sub r2, r2, #8
+ ldmia r2, {r2 - r4} /* get pc, cpsr, old_r0 */
+ add r0, sp, #S_FRAME_SIZE /* restore sp_SVC */
+
+ add r5, sp, #S_SP
+ mov r1, lr
+ stmia r5, {r0 - r4} /* save sp_SVC, lr_SVC, pc, cpsr, old_r */
+ mov r0, sp
+ .endm
+
+
+ /* use irq_save_user_regs / irq_restore_user_regs for */
+ /* IRQ/FIQ handling */
+
+ .macro irq_save_user_regs
+ sub sp, sp, #S_FRAME_SIZE
+ stmia sp, {r0 - r12} /* Calling r0-r12 */
+ add r8, sp, #S_PC
+ stmdb r8, {sp, lr}^ /* Calling SP, LR */
+ str lr, [r8, #0] /* Save calling PC */
+ mrs r6, spsr
+ str r6, [r8, #4] /* Save CPSR */
+ str r0, [r8, #8] /* Save OLD_R0 */
+ mov r0, sp
+ .endm
+
+ .macro irq_restore_user_regs
+ ldmia sp, {r0 - lr}^ @ Calling r0 - lr
+ mov r0, r0
+ ldr lr, [sp, #S_PC] @ Get PC
+ add sp, sp, #S_FRAME_SIZE
+ subs pc, lr, #4 @ return & move spsr_svc into cpsr
+ .endm
+
+ .macro get_bad_stack
+ ldr r13, _armboot_end @ setup our mode stack
+ add r13, r13, #CONFIG_STACKSIZE @ resides at top of normal stack
+ sub r13, r13, #8
+
+ str lr, [r13] @ save caller lr / spsr
+ mrs lr, spsr
+ str lr, [r13, #4]
+
+ mov r13, #MODE_SVC @ prepare SVC-Mode
+ msr spsr_c, r13
+ mov lr, pc
+ movs pc, lr
+ .endm
+
+ .macro get_irq_stack @ setup IRQ stack
+ ldr sp, IRQ_STACK_START
+ .endm
+
+ .macro get_fiq_stack @ setup FIQ stack
+ ldr sp, FIQ_STACK_START
+ .endm
+
+
+/****************************************************************************/
+/* */
+/* exception handlers */
+/* */
+/****************************************************************************/
+
+ .align 5
+undefined_instruction:
+ get_bad_stack
+ bad_save_user_regs
+ bl do_undefined_instruction
+
+ .align 5
+software_interrupt:
+ get_bad_stack
+ bad_save_user_regs
+ bl do_software_interrupt
+
+ .align 5
+prefetch_abort:
+ get_bad_stack
+ bad_save_user_regs
+ bl do_prefetch_abort
+
+ .align 5
+data_abort:
+ get_bad_stack
+ bad_save_user_regs
+ bl do_data_abort
+
+ .align 5
+not_used:
+ get_bad_stack
+ bad_save_user_regs
+ bl do_not_used
+
+#ifdef CONFIG_USE_IRQ
+
+ .align 5
+irq:
+ get_irq_stack
+ irq_save_user_regs
+ bl do_irq
+ irq_restore_user_regs
+
+ .align 5
+fiq:
+ get_fiq_stack
+ irq_save_user_regs /* someone ought to write a more */
+ bl do_fiq /* effiction fiq_save_user_regs */
+ irq_restore_user_regs
+
+#else
+
+ .align 5
+irq:
+ get_bad_stack
+ bad_save_user_regs
+ bl do_irq
+
+ .align 5
+fiq:
+ get_bad_stack
+ bad_save_user_regs
+ bl do_fiq
+
+#endif
+
+/*
+ * FIXME How do we reset??? Watchdog timeout??
+ */
+ .align 5
+.globl reset_cpu
+reset_cpu:
+ /*
+ ldr r0, RST_BASE
+ mov r1, #0x0 @ set bit 3-0 ...
+ str r1, [r0, #RCSR] @ ... to clear in RCSR
+ mov r1, #0x1
+ str r1, [r0, #RCSR] @ and perform reset
+ */
+ b reset_cpu @ silly, but repeat endlessly
+
--- /dev/null
+JFFS2 options and usage.
+-----------------------
+
+JFFS2 in U-Boot is a read only implementation of the file system in
+Linux with the same name. To use JFFS2 define CFG_CMD_JFFS2.
+
+The module adds three new commands.
+fsload - load binary file from a file system image
+fsinfo - print information about file systems
+ls - list files in a directory
+
+
+There is two ways for JFFS2 to find the disk. The default way uses
+the flash_info structure to find the start of a JFFS2 disk (called
+partition in the code) and you can change where the partition is with
+two defines.
+
+CFG_JFFS2_FIRST_BANK
+ defined the first flash bank to use
+
+CFG_JFFS2_FIRST_SECTOR
+ defines the first sector to use
+
+
+The second way is to define CFG_JFFS_CUSTOM_PART and implement the
+jffs2_part_info(int part_num) function in your board specific files.
+In this mode CFG_JFFS2_FIRST_BANK and CFG_JFFS2_FIRST_SECTOR is not
+used.
+
+The input is a partition number starting with 0.
+Return a pointer to struct part_info or NULL for error;
+
+Ex jffs2_part_info() for one partition.
+---
+#if defined CFG_JFFS_CUSTOM_PART
+#include <jffs2/jffs2.h>
+
+static struct part_info part;
+
+struct part_info*
+jffs2_part_info(int part_num)
+{
+ if(part_num==0){
+ if(part.usr_priv==(void*)1)
+ return ∂
+
+ memset(&part, 0, sizeof(part));
+ part.offset=(char*)0xFF800000;
+ part.size=1024*1024*8;
+
+ /* Mark the struct as ready */
+ part.usr_priv=(void*)1;
+
+ return ∂
+ }
+ return 0;
+}
+#endif
+---
+
+TODO.
+
+ Add a new command so it's actually possible to change
+ partition.
+
+ Remove the assumption that JFFS can dereference a pointer
+ into the disk. The current code do not work with memory holes
+ or hardware with a sliding window (PCMCIA).
--- /dev/null
+How to configure modem support in U-Boot :
+
+1. Define modem initialization strings:
+---------------------------------------
+
+The modem initialization strings have following format:
+
+ mdm_init1=<AT-command>
+ mdm_init2=<AT-command>
+ ...
+
+Turning off modem verbose responses with ATV0 or ATQ1 is not allowed;
+U-Boot analyzes only verbose (not numeric) result codes. Modem local
+command echo can be turned off (ATE0).
+
+2. RTS/CTS hardware flow control:
+---------------------------------
+
+You may wish to enable RTS/CTS hardware flow control, if the board's
+UART driver supports it (see CONFIG_HWFLOW compile-time flag in
+config/<board>.h). This is controlled by the 'mdm_flow_control'
+environment variable:
+
+ 'mdm_flow_control=rts/cts' - to enable RTS/CTS flow control.
+ 'mdm_flow_control=none ' - to disable.
+
+
+The following are the examples using a Rockwell OEM modem
+configuration:
+
+SAMSUNG # setenv mdm_init1 ATZ - reset the modem to
+ the factory defaults.
+SAMSUNG # setenv mdm_init2 ATS0=1 - set modem into
+ answer mode.
+SAMSUNG # setenv mdm_flow_control rts/cts - enable serial port
+ flow control
+SAMSUNG # saveenv
+
+The example above initializes modem into answer mode to wait for the
+incoming call. RTS/CTS flow control is enabled for the serial port.
+(The RTS/CTS flow control is enabled by default on the modem).
+
+
+SAMSUNG # setenv mdm_init1 ATZ
+SAMSUNG # setenv mdm_init2 ATS39=0+IFC=0,0 - disable modem
+ RTS/CTS flow control
+SAMSUNG # setenv mdm_init3 ATDT1643973 - dial out the number
+SAMSUNG # setenv mdm_flow_control none
+SAMSUNG # saveenv
+
+The example above initializes modem to dial-up connection on the
+number 1643973. Flow control is disabled.
+
+Note that flow control must be turned both off or both on for the
+board serial port and for the modem.
+
+
+If the connection was set up successfully, the U-Boot prompt appears
+on the terminal console. If not (U-Boot modem was configured for
+originating the call and connection was not established) - the board
+should be reset for another dial-up try.
+
+
+Note on the SMDK2400 board:
+---------------------------
+
+Since the board serial ports does not have DTR signal wired, modem
+should be told to ignore port DTR setting prior to connection to the
+SMDK board, and this setting should be stored in modem NVRAM. For the
+Rockwell OEM modem this can to be done with the following command:
+
+AT&D0&W
+
--- /dev/null
+#
+# The commands in this table are sorted alphabetically by the
+# command name and in descending order by the command name string
+# length. This is to prevent conflicts in command name parsing.
+# Please ensure that new commands are added according to that rule.
+# See $(TOPDIR)/common/command.c
+#
+########################
+#
+# command length
+#
+########################
+askenv 8
+as 2
+autoscr 5
+base 2
+bdinfo 2
+bootelf 7
+bootm 5
+bootp 5
+bootvx 6
+bootd 4
+break 2
+brginfo 3
+carinfo 3
+chpart 6
+cmp 3
+coninfo 5
+continue 4
+cp 2
+crc32 3
+date 3
+dcache 2
+dhcp 4
+dmainfo 3
+ds 2
+dtt 3
+echo 4
+eeprom 3
+erase 3
+fccinfo 3
+fdcboot 4
+flinfo 3
+fpga 4
+fsinfo 5
+fsload 5
+getdcr 6 # IBM 4XX DCR registers
+go 2
+help 1
+i2cinfo 4
+i2c 3
+icache 2
+icinfo 3
+ide 3
+iminfo 3
+iopinfo 3
+irqinfo 3
+kgdb 4
+loadb 5
+loads 5
+loop 4
+ls 2
+mccinfo 3
+md 2
+memcinfo 4
+mii 3
+mm 2
+mtest 5
+muxinfo 3
+mw 2
+next 4
+nm 2
+pciinfo 3
+pinit 4
+printenv 8
+protect 4
+rarpboot 4
+rdump 5
+reginfo 3
+reset 5
+run 3
+saveenv 4
+sccinfo 3
+scsiboot 5
+scsi 4
+siiinfo 3
+sitinfo 3
+siuinfo 3
+setdcr 6 # IBM 4XX DCR registers
+setenv 6
+smcinfo 3
+spiinfo 3
+stack 5
+step 4
+tftpboot 4
+usbboot 5
+usb 4
+version 4
+? 1
--- /dev/null
+ IBM Ebony Board
+
+ Last Update: September 12, 2002
+=======================================================================
+
+This file contains some handy info regarding U-Boot and the IBM
+Ebony evalutation board. See the README.ppc440 for additional
+information.
+
+
+SWITCH SETTINGS & JUMPERS
+==========================
+
+Here's what I've been using successfully. If you feel inclined to
+change things ... please read the docs!
+
+DIPSW U46 U80
+------------------------
+SW 1 off on
+SW 2 on on
+SW 3 on on
+SW 4 off on
+SW 5 on off
+SW 6 on on
+SW 7 on off
+SW 8 on off
+
+J41: strapped
+J42: open
+
+All others are factory default.
+
+
+I2C iprobe
+=====================
+
+The i2c utilities have been tested on both Rev B. and Rev C. and
+look good. The CFG_I2C_NOPROBES macro is defined to prevent
+probing the CDCV850 clock controller at address 0x69 (since reading
+it causes the i2c implementation to misbehave. The output of
+iprobe should look like this (assuming you are only using a single
+SO-DIMM:
+
+=> iprobe
+Valid chip addresses: 50 53 54
+Excluded chip addresses: 69
+
+
+GETTING OUT OF I2C TROUBLE
+===========================
+
+If you're like me ... you may have screwed up your bootstrap serial
+eeprom ... or worse, your SPD eeprom when experimenting with the
+i2c commands. If so, here are some ideas on how to get out of
+trouble:
+
+Serial bootstrap eeprom corruption:
+-----------------------------------
+Power down the board and set the following straps:
+
+J41 - open
+J42 - strapped
+
+This will select the default sys0 and sys1 settings (the serial
+eeproms are not used). Then power up the board and fix the serial
+eeprom using the imm command. Here are the values I currently
+use:
+
+=> imd 50 0 10
+0000: bf a2 04 01 ae 94 11 00 00 00 00 00 00 00 00 00 ................
+
+=> imd 54 0 10
+0000: 8f b3 24 01 4d 14 11 00 00 00 00 00 00 00 00 00 ..$.M...........
+
+Once you have the eeproms set correctly change the
+J41/J42 straps as you desire.
+
+SPD eeprom corruption:
+------------------------
+I've corrupted the SPD eeprom several times ... perhaps too much coffee
+and not enough presence of mind ;-). By default, the ebony code uses
+the SPD to initialize the DDR SDRAM control registers. So if the SPD
+eeprom is corrupted, U-Boot will never get into ram. Here's how I got
+out of this situation:
+
+0. First, _before_ playing with the i2c utilities, do an iprobe, then
+use imd to capture the various device contents to a file. Some day
+you may be glad you did this ... trust me :-). Otherwise try the
+following:
+
+1. In the include/configs/EBONY.h file find the line that defines
+the CONFIG_SPD_EEPROM macro and undefine it. E.g:
+
+#undef CONFIG_SPD_EEPROM
+
+This will make the code use default SDRAM control register
+settings without using the SPD eeprom.
+
+2. Rebuild U-Boot
+
+3. Load the new U-Boot image and reboot ebony.
+
+4. Repair the SPD eeprom using the imm command. Here's the eeprom
+contents that work with the default SO-DIMM that comes with the
+ebony board (micron 8VDDT164AG-265A1). Note: these are probably
+_not_ the factory settings ... but they work.
+
+=> imd 53 0 10 80
+0000: 80 08 07 0c 0a 01 40 00 04 75 75 00 80 08 00 01 ......@..uu.....
+0010: 0e 04 0c 01 02 20 00 a0 75 00 00 50 3c 50 2d 20 ..... ..u..P<P-
+0020: 90 90 50 50 00 00 00 00 00 41 4b 34 32 75 00 00 ..PP.....AK42u..
+0030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 9c ................
+0040: 2c 00 00 00 00 00 00 00 08 38 56 44 44 54 31 36 ,........8VDDT16
+0050: 36 34 41 47 2d 32 36 35 41 31 20 01 00 01 2c 63 64AG-265A1 ...,c
+0060: 22 25 ab 00 00 00 00 00 00 00 00 00 00 00 00 00 "%..............
+0070: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+
+
+PCI DOUBLE-ENUMERATION WOES
+===========================
+
+If you're not using PCI-X cards and are simply using 32-bit and/or
+33 MHz cards via extenders and the like, you may notice that the
+initial pci scan reports various devices twice ... and configuration
+does not succeed (one or more devices are enumerated twice). To correct
+this we replaced the 2K ohm resistor on the IDSEL line(s) with a
+22 ohm resistor and the problem went away. This change hasn't broken
+anything yet -- use at your own risk.
+
+We never tested anything other than 33 MHz/32-bit cards. If you have
+the chance to do this, please let me know how things turn out :-)
+
+
+
+Regards,
+--Scott
+<smcnutt@artesyncp.com>
+
--- /dev/null
+ PowerPC 440
+
+ Last Update: September 11, 2002
+=======================================================================
+
+
+OVERVIEW
+============
+
+Support for the ppc440 is contained in the cpu/ppc44x directory
+and enabled via the CONFIG_440 flag. It is largely based on the
+405gp code. A sample board support implementation is contained
+in the board/ebony directory.
+
+All testing was performed using the IBM Ebony board using both
+Rev B and Rev C silicon. However, since the Rev B. silicon has
+extensive errata, support for Rev B. is minimal (it boots, and
+features such as i2c, pci, tftpboot, etc. seem to work ok).
+The expectation is that all new board designs will be using
+Rev C or later parts -- if not, you may be in for a rough ride ;-)
+
+The ppc440 port does a fair job of keeping "board-specific" code
+out of the "cpu-specific" source. The goal of course was to
+provide mechanisms for each board to customize without having
+to clutter the cpu-specific source with a lot of ifdefs. Most
+of these mechanisms are described in the following sections.
+
+
+MEMORY MANAGEMENT
+=================
+
+The ppc440 doesn't run in "real mode". The MMU must be active
+at all times. Additionally, the 440 implements a 36-bit physical
+memory space that gets mapped into the PowerPC 32-bit virtual
+address space. So things like memory-mapped peripherals, etc must
+all be mapped in. Once this is done, the 32-bit virtual address
+space is then viewed as though it were physical memory.
+
+However, this means that memory, peripherals, etc can be configured
+to appear (mostly) anywhere in the virtual address space. Each board
+must define its own mappings using the tlbtab (see board/ebony/init.S).
+The actual TLB setup is performed by the cpu-specific code.
+
+Although each board is free to define its own mappings, there are
+several definitions to be aware of. These definitions may be used in
+the cpu-specific code (vs. board-specific code), so you should
+at least review these before deciding to make any changes ... it
+will probably save you some headaches ;-)
+
+CFG_SDRAM_BASE - The virtual address where SDRAM is mapped (always 0)
+
+CFG_FLASH_BASE - The virtual address where FLASH is mapped.
+
+CFG_PCI_MEMBASE - The virtual address where PCI-bus memory is mapped.
+ This mapping provides access to PCI-bus memory.
+
+CFG_PERIPHERAL_BASE - The virtual address where the 440 memory-mapped
+ peripherals are mapped. (e.g. -- UART registers, IIC registers, etc).
+
+CFG_ISRAM_BASE - The virtual address where the 440 internal SRAM is
+ mapped. The internal SRAM is equivalent to 405gp OCM and is used
+ for the initial stack.
+
+CFG_PCI_BASE - The virtual address where the 440 PCI-x bridge config
+ registers are mapped.
+
+CFG_PCI_TARGBASE - The PCI address that is mapped to the virtual address
+ defined by CFG_PCI_MEMBASE.
+
+
+UART / SERIAL
+=================
+
+The UART port works fine when an external serial clock is provided
+(like the one on the Ebony board) and when using internal clocking.
+This is controlled with the CFG_EXT_SERIAL_CLOCK flag. When using
+internal clocking, the "ideal baud rate" settings in the 440GP
+user manual are automatically calculated.
+
+CONFIG_SERIAL_SOFTWARE_FIFO enables interrupt-driven serial operation.
+But the last time I checked, interrupts were initialized after the
+serial port causing the interrupt handler to be removed from the
+handler table. This will probably be fixed soon ... or fix it
+yourself and submit a patch :-)
+
+
+I2C
+=================
+
+The i2c utilities have been tested on both Rev B. and Rev C. and
+look good. The iprobe command implementation has been updated to
+allow for 'skipped' addresses. Some i2c slaves are write only and
+cause problems when a probe (read) is performed (for example the
+CDCV850 clock controller at address 0x69 on the ebony board).
+
+To prevent probing certain addresses you can define the
+CFG_I2C_NOPROBES macro in your board-specific header file. When
+defined, all specified addresses are skipped during a probe.
+The addresses that are skipped will be displayed in the output
+of the iprobe command.
+
+For example, to prevent probing address 0x69, define the macro as
+follows:
+
+#define CFG_I2C_NOPROBES {0x69}
+
+Similarly, to prevent probing addresses 0x69 and 0x70, define the
+macro a:
+
+#define CFG_I2C_NOPROBES {0x69, 0x70}
+
+
+DDR SDRAM CONTROLLER
+====================
+
+SDRAM controller intialization using Serial Presence Detect (SPD) is
+now supported (thanks Jun). It is enabled by defining CONFIG_SPD_EEPROM.
+The i2c eeprom addresses are controlled by the SPD_EEPROM_ADDRESS macro.
+
+NOTE: The SPD_EEPROM_ADDRESS macro is defined differently than for other
+processors. Traditionally, it defined a single address. For the 440 it
+defines an array of addresses to support multiple banks. Address order
+is significant: the addresses are used in order to program the BankN
+registers. For example, two banks with i2c addresses of 0x53 (bank 0)
+and 0x52 (bank 1) would be defined as follows:
+
+#define SPD_EEPROM_ADDRESS {0x53,0x52}
+
+
+PCI-X BRIDGE
+====================
+
+PCI is an area that requires lots of flexibility since every board has
+its own set of constraints and configuration. This section describes the
+440 implementation.
+
+CPC0_STRP1[PISE] -- if the PISE strap bit is not asserted, PCI init
+is aborted and an indication is printed. This is NOT considered an
+error -- only an indication that PCI shouldn't be initialized. This
+gives you a chance to edit the i2c bootstrap eeproms using the i2c
+utilities once you get to the U-Boot command prompt. NOTE: the default
+440 bootstrap options (not using i2c eeprom) negates this bit.
+
+The cpu-specific code sets up a default pci_controller structure
+that maps in a single PCI I/O space and PCI memory space. The I/O
+space begins at PCI I/O address 0 and the PCI memory space is
+256 MB starting at PCI address CFG_PCI_TARGBASE. After the
+pci_controller structure is initialized, the cpu-specific code will
+call the routine pci_pre_init() if the CFG_PCI_PRE_INIT flag is
+defined. This routine is implemented by board-specific code & is where
+the board can over-ride/extend the default pci_controller structure
+settings and do other pre-initialization tasks. If pci_pre_init()
+returns a value of zero, PCI initialization is aborted; otherwise the
+controller structure is registered and initialization continues.
+
+The default 440GP PCI target configuration is minimal -- it assumes that
+the strapping registers are set as necessary. Since the strapping bits
+provide very limited flexibility, you may want to customize the boards
+target configuration. If CFG_PCI_TARGET_INIT is defined, the cpu-specific
+code will call the routine pci_target_init() which you must implement
+in your board-specific code.
+
+Target initialization is completed by the cpu-specific code by
+initializing the subsystem id and subsystem vendor id, and then ensuring
+that the 'enable host configuration' bit in the PCIX0_BRDGOPT2 is set.
+
+The default PCI master initialization maps in 256 MB of pci memory
+starting at PCI address CFG_PCI_MEMBASE. To customize this, define
+PCI_MASTER_INIT. This will call the routine pci_master_init() in your
+board-specific code rather than performing the default master
+initialization.
+
+The decision to perform PCI host configuration must often be determined
+at run time. The ppc440 port differs from most other implementations in
+that it requires the board to determine its host configuration at run
+time rather than by using compile-time flags. This shouldn't create a
+large impact on the board-specific code since the board only needs to
+implement a single routine that returns a zero or non-zero value:
+is_pci_host().
+
+Justification for this becomes clear when considering systems running
+in a cPCI environment:
+
+1. Arbiter strapping: Many cPCI boards provide an external arbiter (often
+part of the PCI-to-PCI bridge). Even though the arbiter is external (the
+arbiter strapping is negated), the CPU may still be required to perform
+local PCI bus configuration.
+
+2. Host only: PPMC boards must sample the MONARCH# signal at run-time.
+Depending on the configuration of the carrier boar, the PPMC board must
+determine if it should configure the PCI bus at run-time. And in most
+cases, access to the MONARCH# signal is board-specific (e.g. via
+board-specific FPGA registers, etc).
+
+In any event, the is_pci_host() routine gives each board the opportunity
+to decide at run-time. If your board is always configured a certain way,
+then just hardcode a return of 1 or 0 as appropriate.
+
+
+
+Regards,
+--Scott
+<smcnutt@artesyncp.com>
+
--- /dev/null
+/*
+ * Copyright (c) 1993 Herb Peyerl (hpeyerl@novatel.ca) All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer. 2. The name
+ * of the author may not be used to endorse or promote products derived from
+ * this software without specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+ * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ October 2, 1994
+
+ Modified by: Andres Vega Garcia
+
+ INRIA - Sophia Antipolis, France
+ e-mail: avega@sophia.inria.fr
+ finger: avega@pax.inria.fr
+
+ */
+
+/*
+ * Created from if_epreg.h by Fred Gray (fgray@rice.edu) to support the
+ * 3c590 family.
+ */
+
+/*
+ * Modified by Shusuke Nisiyama <shu@athena.qe.eng.hokudai.ac.jp>
+ * for etherboot
+ * Mar. 14, 2000
+*/
+
+/*
+ * Ethernet software status per interface.
+ */
+
+/*
+ * Some global constants
+ */
+
+#define TX_INIT_RATE 16
+#define TX_INIT_MAX_RATE 64
+#define RX_INIT_LATENCY 64
+#define RX_INIT_EARLY_THRESH 64
+#define MIN_RX_EARLY_THRESHF 16 /* not less than ether_header */
+#define MIN_RX_EARLY_THRESHL 4
+
+#define EEPROMSIZE 0x40
+#define MAX_EEPROMBUSY 1000
+#define VX_LAST_TAG 0xd7
+#define VX_MAX_BOARDS 16
+#define VX_ID_PORT 0x100
+
+/*
+ * some macros to acces long named fields
+ */
+#define BASE (EL_BASE_ADDR)
+
+/*
+ * Commands to read/write EEPROM trough EEPROM command register (Window 0,
+ * Offset 0xa)
+ */
+#define EEPROM_CMD_RD 0x0080 /* Read: Address required (5 bits) */
+#define EEPROM_CMD_WR 0x0040 /* Write: Address required (5 bits) */
+#define EEPROM_CMD_ERASE 0x00c0 /* Erase: Address required (5 bits) */
+#define EEPROM_CMD_EWEN 0x0030 /* Erase/Write Enable: No data required */
+
+#define EEPROM_BUSY (1<<15)
+
+/*
+ * Some short functions, worth to let them be a macro
+ */
+
+/**************************************************************************
+ * *
+ * These define the EEPROM data structure. They are used in the probe
+ * function to verify the existence of the adapter after having sent
+ * the ID_Sequence.
+ *
+ * There are others but only the ones we use are defined here.
+ *
+ **************************************************************************/
+
+#define EEPROM_NODE_ADDR_0 0x0 /* Word */
+#define EEPROM_NODE_ADDR_1 0x1 /* Word */
+#define EEPROM_NODE_ADDR_2 0x2 /* Word */
+#define EEPROM_PROD_ID 0x3 /* 0x9[0-f]50 */
+#define EEPROM_MFG_ID 0x7 /* 0x6d50 */
+#define EEPROM_ADDR_CFG 0x8 /* Base addr */
+#define EEPROM_RESOURCE_CFG 0x9 /* IRQ. Bits 12-15 */
+#define EEPROM_OEM_ADDR_0 0xa /* Word */
+#define EEPROM_OEM_ADDR_1 0xb /* Word */
+#define EEPROM_OEM_ADDR_2 0xc /* Word */
+#define EEPROM_SOFT_INFO_2 0xf /* Software information 2 */
+
+#define NO_RX_OVN_ANOMALY (1<<5)
+
+/**************************************************************************
+ * *
+ * These are the registers for the 3Com 3c509 and their bit patterns when *
+ * applicable. They have been taken out the the "EtherLink III Parallel *
+ * Tasking EISA and ISA Technical Reference" "Beta Draft 10/30/92" manual *
+ * from 3com. *
+ * *
+ **************************************************************************/
+
+#define VX_COMMAND 0x0e /* Write. BASE+0x0e is always a
+ * command reg. */
+#define VX_STATUS 0x0e /* Read. BASE+0x0e is always status
+ * reg. */
+#define VX_WINDOW 0x0f /* Read. BASE+0x0f is always window
+ * reg. */
+/*
+ * Window 0 registers. Setup.
+ */
+/* Write */
+#define VX_W0_EEPROM_DATA 0x0c
+#define VX_W0_EEPROM_COMMAND 0x0a
+#define VX_W0_RESOURCE_CFG 0x08
+#define VX_W0_ADDRESS_CFG 0x06
+#define VX_W0_CONFIG_CTRL 0x04
+ /* Read */
+#define VX_W0_PRODUCT_ID 0x02
+#define VX_W0_MFG_ID 0x00
+
+
+/*
+ * Window 1 registers. Operating Set.
+ */
+/* Write */
+#define VX_W1_TX_PIO_WR_2 0x02
+#define VX_W1_TX_PIO_WR_1 0x00
+/* Read */
+#define VX_W1_FREE_TX 0x0c
+#define VX_W1_TX_STATUS 0x0b /* byte */
+#define VX_W1_TIMER 0x0a /* byte */
+#define VX_W1_RX_STATUS 0x08
+#define VX_W1_RX_PIO_RD_2 0x02
+#define VX_W1_RX_PIO_RD_1 0x00
+
+/*
+ * Window 2 registers. Station Address Setup/Read
+ */
+/* Read/Write */
+#define VX_W2_ADDR_5 0x05
+#define VX_W2_ADDR_4 0x04
+#define VX_W2_ADDR_3 0x03
+#define VX_W2_ADDR_2 0x02
+#define VX_W2_ADDR_1 0x01
+#define VX_W2_ADDR_0 0x00
+
+/*
+ * Window 3 registers. FIFO Management.
+ */
+/* Read */
+#define VX_W3_INTERNAL_CFG 0x00
+#define VX_W3_RESET_OPT 0x08
+#define VX_W3_FREE_TX 0x0c
+#define VX_W3_FREE_RX 0x0a
+
+/*
+ * Window 4 registers. Diagnostics.
+ */
+/* Read/Write */
+#define VX_W4_MEDIA_TYPE 0x0a
+#define VX_W4_CTRLR_STATUS 0x08
+#define VX_W4_NET_DIAG 0x06
+#define VX_W4_FIFO_DIAG 0x04
+#define VX_W4_HOST_DIAG 0x02
+#define VX_W4_TX_DIAG 0x00
+
+/*
+ * Window 5 Registers. Results and Internal status.
+ */
+/* Read */
+#define VX_W5_READ_0_MASK 0x0c
+#define VX_W5_INTR_MASK 0x0a
+#define VX_W5_RX_FILTER 0x08
+#define VX_W5_RX_EARLY_THRESH 0x06
+#define VX_W5_TX_AVAIL_THRESH 0x02
+#define VX_W5_TX_START_THRESH 0x00
+
+/*
+ * Window 6 registers. Statistics.
+ */
+/* Read/Write */
+#define TX_TOTAL_OK 0x0c
+#define RX_TOTAL_OK 0x0a
+#define TX_DEFERRALS 0x08
+#define RX_FRAMES_OK 0x07
+#define TX_FRAMES_OK 0x06
+#define RX_OVERRUNS 0x05
+#define TX_COLLISIONS 0x04
+#define TX_AFTER_1_COLLISION 0x03
+#define TX_AFTER_X_COLLISIONS 0x02
+#define TX_NO_SQE 0x01
+#define TX_CD_LOST 0x00
+
+/****************************************
+ *
+ * Register definitions.
+ *
+ ****************************************/
+
+/*
+ * Command register. All windows.
+ *
+ * 16 bit register.
+ * 15-11: 5-bit code for command to be executed.
+ * 10-0: 11-bit arg if any. For commands with no args;
+ * this can be set to anything.
+ */
+#define GLOBAL_RESET (unsigned short) 0x0000 /* Wait at least 1ms
+ * after issuing */
+#define WINDOW_SELECT (unsigned short) (0x1<<11)
+#define START_TRANSCEIVER (unsigned short) (0x2<<11) /* Read ADDR_CFG reg to
+ * determine whether
+ * this is needed. If
+ * so; wait 800 uSec
+ * before using trans-
+ * ceiver. */
+#define RX_DISABLE (unsigned short) (0x3<<11) /* state disabled on
+ * power-up */
+#define RX_ENABLE (unsigned short) (0x4<<11)
+#define RX_RESET (unsigned short) (0x5<<11)
+#define RX_DISCARD_TOP_PACK (unsigned short) (0x8<<11)
+#define TX_ENABLE (unsigned short) (0x9<<11)
+#define TX_DISABLE (unsigned short) (0xa<<11)
+#define TX_RESET (unsigned short) (0xb<<11)
+#define REQ_INTR (unsigned short) (0xc<<11)
+/*
+ * The following C_* acknowledge the various interrupts. Some of them don't
+ * do anything. See the manual.
+ */
+#define ACK_INTR (unsigned short) (0x6800)
+# define C_INTR_LATCH (unsigned short) (ACK_INTR|0x1)
+# define C_CARD_FAILURE (unsigned short) (ACK_INTR|0x2)
+# define C_TX_COMPLETE (unsigned short) (ACK_INTR|0x4)
+# define C_TX_AVAIL (unsigned short) (ACK_INTR|0x8)
+# define C_RX_COMPLETE (unsigned short) (ACK_INTR|0x10)
+# define C_RX_EARLY (unsigned short) (ACK_INTR|0x20)
+# define C_INT_RQD (unsigned short) (ACK_INTR|0x40)
+# define C_UPD_STATS (unsigned short) (ACK_INTR|0x80)
+#define SET_INTR_MASK (unsigned short) (0xe<<11)
+#define SET_RD_0_MASK (unsigned short) (0xf<<11)
+#define SET_RX_FILTER (unsigned short) (0x10<<11)
+# define FIL_INDIVIDUAL (unsigned short) (0x1)
+# define FIL_MULTICAST (unsigned short) (0x02)
+# define FIL_BRDCST (unsigned short) (0x04)
+# define FIL_PROMISC (unsigned short) (0x08)
+#define SET_RX_EARLY_THRESH (unsigned short) (0x11<<11)
+#define SET_TX_AVAIL_THRESH (unsigned short) (0x12<<11)
+#define SET_TX_START_THRESH (unsigned short) (0x13<<11)
+#define STATS_ENABLE (unsigned short) (0x15<<11)
+#define STATS_DISABLE (unsigned short) (0x16<<11)
+#define STOP_TRANSCEIVER (unsigned short) (0x17<<11)
+
+/*
+ * Status register. All windows.
+ *
+ * 15-13: Window number(0-7).
+ * 12: Command_in_progress.
+ * 11: reserved.
+ * 10: reserved.
+ * 9: reserved.
+ * 8: reserved.
+ * 7: Update Statistics.
+ * 6: Interrupt Requested.
+ * 5: RX Early.
+ * 4: RX Complete.
+ * 3: TX Available.
+ * 2: TX Complete.
+ * 1: Adapter Failure.
+ * 0: Interrupt Latch.
+ */
+#define S_INTR_LATCH (unsigned short) (0x1)
+#define S_CARD_FAILURE (unsigned short) (0x2)
+#define S_TX_COMPLETE (unsigned short) (0x4)
+#define S_TX_AVAIL (unsigned short) (0x8)
+#define S_RX_COMPLETE (unsigned short) (0x10)
+#define S_RX_EARLY (unsigned short) (0x20)
+#define S_INT_RQD (unsigned short) (0x40)
+#define S_UPD_STATS (unsigned short) (0x80)
+#define S_COMMAND_IN_PROGRESS (unsigned short) (0x1000)
+
+#define VX_BUSY_WAIT while (inw(BASE + VX_STATUS) & S_COMMAND_IN_PROGRESS)
+
+/* Address Config. Register.
+ * Window 0/Port 06
+ */
+
+#define ACF_CONNECTOR_BITS 14
+#define ACF_CONNECTOR_UTP 0
+#define ACF_CONNECTOR_AUI 1
+#define ACF_CONNECTOR_BNC 3
+
+#define INTERNAL_CONNECTOR_BITS 20
+#define INTERNAL_CONNECTOR_MASK 0x01700000
+
+/*
+ * FIFO Registers. RX Status.
+ *
+ * 15: Incomplete or FIFO empty.
+ * 14: 1: Error in RX Packet 0: Incomplete or no error.
+ * 13-11: Type of error.
+ * 1000 = Overrun.
+ * 1011 = Run Packet Error.
+ * 1100 = Alignment Error.
+ * 1101 = CRC Error.
+ * 1001 = Oversize Packet Error (>1514 bytes)
+ * 0010 = Dribble Bits.
+ * (all other error codes, no errors.)
+ *
+ * 10-0: RX Bytes (0-1514)
+ */
+#define ERR_INCOMPLETE (unsigned short) (0x8000)
+#define ERR_RX (unsigned short) (0x4000)
+#define ERR_MASK (unsigned short) (0x7800)
+#define ERR_OVERRUN (unsigned short) (0x4000)
+#define ERR_RUNT (unsigned short) (0x5800)
+#define ERR_ALIGNMENT (unsigned short) (0x6000)
+#define ERR_CRC (unsigned short) (0x6800)
+#define ERR_OVERSIZE (unsigned short) (0x4800)
+#define ERR_DRIBBLE (unsigned short) (0x1000)
+
+/*
+ * TX Status.
+ *
+ * Reports the transmit status of a completed transmission. Writing this
+ * register pops the transmit completion stack.
+ *
+ * Window 1/Port 0x0b.
+ *
+ * 7: Complete
+ * 6: Interrupt on successful transmission requested.
+ * 5: Jabber Error (TP Only, TX Reset required. )
+ * 4: Underrun (TX Reset required. )
+ * 3: Maximum Collisions.
+ * 2: TX Status Overflow.
+ * 1-0: Undefined.
+ *
+ */
+#define TXS_COMPLETE 0x80
+#define TXS_INTR_REQ 0x40
+#define TXS_JABBER 0x20
+#define TXS_UNDERRUN 0x10
+#define TXS_MAX_COLLISION 0x8
+#define TXS_STATUS_OVERFLOW 0x4
+
+#define RS_AUI (1<<5)
+#define RS_BNC (1<<4)
+#define RS_UTP (1<<3)
+#define RS_T4 (1<<0)
+#define RS_TX (1<<1)
+#define RS_FX (1<<2)
+#define RS_MII (1<<6)
+
+
+/*
+ * FIFO Status (Window 4)
+ *
+ * Supports FIFO diagnostics
+ *
+ * Window 4/Port 0x04.1
+ *
+ * 15: 1=RX receiving (RO). Set when a packet is being received
+ * into the RX FIFO.
+ * 14: Reserved
+ * 13: 1=RX underrun (RO). Generates Adapter Failure interrupt.
+ * Requires RX Reset or Global Reset command to recover.
+ * It is generated when you read past the end of a packet -
+ * reading past what has been received so far will give bad
+ * data.
+ * 12: 1=RX status overrun (RO). Set when there are already 8
+ * packets in the RX FIFO. While this bit is set, no additional
+ * packets are received. Requires no action on the part of
+ * the host. The condition is cleared once a packet has been
+ * read out of the RX FIFO.
+ * 11: 1=RX overrun (RO). Set when the RX FIFO is full (there
+ * may not be an overrun packet yet). While this bit is set,
+ * no additional packets will be received (some additional
+ * bytes can still be pending between the wire and the RX
+ * FIFO). Requires no action on the part of the host. The
+ * condition is cleared once a few bytes have been read out
+ * from the RX FIFO.
+ * 10: 1=TX overrun (RO). Generates adapter failure interrupt.
+ * Requires TX Reset or Global Reset command to recover.
+ * Disables Transmitter.
+ * 9-8: Unassigned.
+ * 7-0: Built in self test bits for the RX and TX FIFO's.
+ */
+#define FIFOS_RX_RECEIVING (unsigned short) 0x8000
+#define FIFOS_RX_UNDERRUN (unsigned short) 0x2000
+#define FIFOS_RX_STATUS_OVERRUN (unsigned short) 0x1000
+#define FIFOS_RX_OVERRUN (unsigned short) 0x0800
+#define FIFOS_TX_OVERRUN (unsigned short) 0x0400
+
+/*
+ * Misc defines for various things.
+ */
+#define TAG_ADAPTER 0xd0
+#define ACTIVATE_ADAPTER_TO_CONFIG 0xff
+#define ENABLE_DRQ_IRQ 0x0001
+#define MFG_ID 0x506d /* `TCM' */
+#define PROD_ID 0x5090
+#define GO_WINDOW(x) outw(WINDOW_SELECT|(x),BASE+VX_COMMAND)
+#define JABBER_GUARD_ENABLE 0x40
+#define LINKBEAT_ENABLE 0x80
+#define ENABLE_UTP (JABBER_GUARD_ENABLE | LINKBEAT_ENABLE)
+#define DISABLE_UTP 0x0
+#define RX_BYTES_MASK (unsigned short) (0x07ff)
+#define RX_ERROR 0x4000
+#define RX_INCOMPLETE 0x8000
+#define TX_INDICATE 1<<15
+#define is_eeprom_busy(b) (inw((b)+VX_W0_EEPROM_COMMAND)&EEPROM_BUSY)
+
+#define VX_IOSIZE 0x20
+
+#define VX_CONNECTORS 8
+
+/*
+ * Local variables:
+ * c-basic-offset: 8
+ * End:
+ */
--- /dev/null
+/******************************************************************************/
+/* */
+/* Broadcom BCM5700 Linux Network Driver, Copyright (c) 2000 Broadcom */
+/* Corporation. */
+/* All rights reserved. */
+/* */
+/* 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, located in the file LICENSE. */
+/* */
+/* History: */
+/* */
+/******************************************************************************/
+
+#if INCLUDE_5701_AX_FIX
+
+#include "bcm570x_mm.h"
+#include "5701rls.h"
+
+LM_STATUS LM_LoadRlsFirmware(PLM_DEVICE_BLOCK pDevice)
+{
+ T3_FWIMG_INFO FwImgInfo;
+
+ FwImgInfo.StartAddress = t3FwStartAddr;
+ FwImgInfo.Text.Buffer = (PLM_UINT8)t3FwText;
+ FwImgInfo.Text.Offset = t3FwTextAddr;
+ FwImgInfo.Text.Length = t3FwTextLen;
+ FwImgInfo.ROnlyData.Buffer = (PLM_UINT8)t3FwRodata;
+ FwImgInfo.ROnlyData.Offset = t3FwRodataAddr;
+ FwImgInfo.ROnlyData.Length = t3FwRodataLen;
+ FwImgInfo.Data.Buffer = (PLM_UINT8)t3FwData;
+ FwImgInfo.Data.Offset = t3FwDataAddr;
+ FwImgInfo.Data.Length = t3FwDataLen;
+
+ if (LM_LoadFirmware(pDevice,
+ &FwImgInfo,
+ T3_RX_CPU_ID | T3_TX_CPU_ID,
+ T3_RX_CPU_ID) != LM_STATUS_SUCCESS)
+ {
+ return LM_STATUS_FAILURE;
+ }
+
+ return LM_STATUS_SUCCESS;
+}
+
+#endif /* INCLUDE_5701_AX_FIX */
--- /dev/null
+/******************************************************************************/
+/* */
+/* Broadcom BCM5700 Linux Network Driver, Copyright (c) 2000 Broadcom */
+/* Corporation. */
+/* All rights reserved. */
+/* */
+/* 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, located in the file LICENSE. */
+/* */
+/* History: */
+/******************************************************************************/
+
+typedef unsigned long U32;
+int t3FwReleaseMajor = 0x0;
+int t3FwReleaseMinor = 0x0;
+int t3FwReleaseFix = 0x0;
+U32 t3FwStartAddr = 0x08000000;
+U32 t3FwTextAddr = 0x08000000;
+int t3FwTextLen = 0x9c0;
+U32 t3FwRodataAddr = 0x080009c0;
+int t3FwRodataLen = 0x60;
+U32 t3FwDataAddr = 0x08000a40;
+int t3FwDataLen = 0x20;
+U32 t3FwSbssAddr = 0x08000a60;
+int t3FwSbssLen = 0xc;
+U32 t3FwBssAddr = 0x08000a70;
+int t3FwBssLen = 0x10;
+U32 t3FwText[(0x9c0/4) + 1] = {
+0x0,
+0x10000003, 0x0, 0xd, 0xd,
+0x3c1d0800, 0x37bd3ffc, 0x3a0f021, 0x3c100800,
+0x26100000, 0xe000018, 0x0, 0xd,
+0x3c1d0800, 0x37bd3ffc, 0x3a0f021, 0x3c100800,
+0x26100034, 0xe00021c, 0x0, 0xd,
+0x0, 0x0, 0x0, 0x27bdffe0,
+0x3c1cc000, 0xafbf0018, 0xaf80680c, 0xe00004c,
+0x241b2105, 0x97850000, 0x97870002, 0x9782002c,
+0x9783002e, 0x3c040800, 0x248409c0, 0xafa00014,
+0x21400, 0x621825, 0x52c00, 0xafa30010,
+0x8f860010, 0xe52825, 0xe000060, 0x24070102,
+0x3c02ac00, 0x34420100, 0x3c03ac01, 0x34630100,
+0xaf820490, 0x3c02ffff, 0xaf820494, 0xaf830498,
+0xaf82049c, 0x24020001, 0xaf825ce0, 0xe00003f,
+0xaf825d00, 0xe000140, 0x0, 0x8fbf0018,
+0x3e00008, 0x27bd0020, 0x2402ffff, 0xaf825404,
+0x8f835400, 0x34630400, 0xaf835400, 0xaf825404,
+0x3c020800, 0x24420034, 0xaf82541c, 0x3e00008,
+0xaf805400, 0x0, 0x0, 0x3c020800,
+0x34423000, 0x3c030800, 0x34633000, 0x3c040800,
+0x348437ff, 0x3c010800, 0xac220a64, 0x24020040,
+0x3c010800, 0xac220a68, 0x3c010800, 0xac200a60,
+0xac600000, 0x24630004, 0x83102b, 0x5040fffd,
+0xac600000, 0x3e00008, 0x0, 0x804821,
+0x8faa0010, 0x3c020800, 0x8c420a60, 0x3c040800,
+0x8c840a68, 0x8fab0014, 0x24430001, 0x44102b,
+0x3c010800, 0xac230a60, 0x14400003, 0x4021,
+0x3c010800, 0xac200a60, 0x3c020800, 0x8c420a60,
+0x3c030800, 0x8c630a64, 0x91240000, 0x21140,
+0x431021, 0x481021, 0x25080001, 0xa0440000,
+0x29020008, 0x1440fff4, 0x25290001, 0x3c020800,
+0x8c420a60, 0x3c030800, 0x8c630a64, 0x8f84680c,
+0x21140, 0x431021, 0xac440008, 0xac45000c,
+0xac460010, 0xac470014, 0xac4a0018, 0x3e00008,
+0xac4b001c, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x2000008,
+0x0, 0xa0001e3, 0x3c0a0001, 0xa0001e3,
+0x3c0a0002, 0xa0001e3, 0x0, 0xa0001e3,
+0x0, 0xa0001e3, 0x0, 0xa0001e3,
+0x0, 0xa0001e3, 0x0, 0xa0001e3,
+0x0, 0xa0001e3, 0x0, 0xa0001e3,
+0x0, 0xa0001e3, 0x0, 0xa0001e3,
+0x3c0a0007, 0xa0001e3, 0x3c0a0008, 0xa0001e3,
+0x3c0a0009, 0xa0001e3, 0x0, 0xa0001e3,
+0x0, 0xa0001e3, 0x3c0a000b, 0xa0001e3,
+0x3c0a000c, 0xa0001e3, 0x3c0a000d, 0xa0001e3,
+0x0, 0xa0001e3, 0x0, 0xa0001e3,
+0x3c0a000e, 0xa0001e3, 0x0, 0xa0001e3,
+0x0, 0xa0001e3, 0x0, 0xa0001e3,
+0x0, 0xa0001e3, 0x0, 0xa0001e3,
+0x0, 0xa0001e3, 0x0, 0xa0001e3,
+0x0, 0xa0001e3, 0x3c0a0013, 0xa0001e3,
+0x3c0a0014, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x27bdffe0,
+0x1821, 0x1021, 0xafbf0018, 0xafb10014,
+0xafb00010, 0x3c010800, 0x220821, 0xac200a70,
+0x3c010800, 0x220821, 0xac200a74, 0x3c010800,
+0x220821, 0xac200a78, 0x24630001, 0x1860fff5,
+0x2442000c, 0x24110001, 0x8f906810, 0x32020004,
+0x14400005, 0x24040001, 0x3c020800, 0x8c420a78,
+0x18400003, 0x2021, 0xe000182, 0x0,
+0x32020001, 0x10400003, 0x0, 0xe000169,
+0x0, 0xa000153, 0xaf915028, 0x8fbf0018,
+0x8fb10014, 0x8fb00010, 0x3e00008, 0x27bd0020,
+0x3c050800, 0x8ca50a70, 0x3c060800, 0x8cc60a80,
+0x3c070800, 0x8ce70a78, 0x27bdffe0, 0x3c040800,
+0x248409d0, 0xafbf0018, 0xafa00010, 0xe000060,
+0xafa00014, 0xe00017b, 0x2021, 0x8fbf0018,
+0x3e00008, 0x27bd0020, 0x24020001, 0x8f836810,
+0x821004, 0x21027, 0x621824, 0x3e00008,
+0xaf836810, 0x27bdffd8, 0xafbf0024, 0x1080002e,
+0xafb00020, 0x8f825cec, 0xafa20018, 0x8f825cec,
+0x3c100800, 0x26100a78, 0xafa2001c, 0x34028000,
+0xaf825cec, 0x8e020000, 0x18400016, 0x0,
+0x3c020800, 0x94420a74, 0x8fa3001c, 0x221c0,
+0xac830004, 0x8fa2001c, 0x3c010800, 0xe000201,
+0xac220a74, 0x10400005, 0x0, 0x8e020000,
+0x24420001, 0xa0001df, 0xae020000, 0x3c020800,
+0x8c420a70, 0x21c02, 0x321c0, 0xa0001c5,
+0xafa2001c, 0xe000201, 0x0, 0x1040001f,
+0x0, 0x8e020000, 0x8fa3001c, 0x24420001,
+0x3c010800, 0xac230a70, 0x3c010800, 0xac230a74,
+0xa0001df, 0xae020000, 0x3c100800, 0x26100a78,
+0x8e020000, 0x18400028, 0x0, 0xe000201,
+0x0, 0x14400024, 0x0, 0x8e020000,
+0x3c030800, 0x8c630a70, 0x2442ffff, 0xafa3001c,
+0x18400006, 0xae020000, 0x31402, 0x221c0,
+0x8c820004, 0x3c010800, 0xac220a70, 0x97a2001e,
+0x2442ff00, 0x2c420300, 0x1440000b, 0x24024000,
+0x3c040800, 0x248409dc, 0xafa00010, 0xafa00014,
+0x8fa6001c, 0x24050008, 0xe000060, 0x3821,
+0xa0001df, 0x0, 0xaf825cf8, 0x3c020800,
+0x8c420a40, 0x8fa3001c, 0x24420001, 0xaf835cf8,
+0x3c010800, 0xac220a40, 0x8fbf0024, 0x8fb00020,
+0x3e00008, 0x27bd0028, 0x27bdffe0, 0x3c040800,
+0x248409e8, 0x2821, 0x3021, 0x3821,
+0xafbf0018, 0xafa00010, 0xe000060, 0xafa00014,
+0x8fbf0018, 0x3e00008, 0x27bd0020, 0x8f82680c,
+0x8f85680c, 0x21827, 0x3182b, 0x31823,
+0x431024, 0x441021, 0xa2282b, 0x10a00006,
+0x0, 0x401821, 0x8f82680c, 0x43102b,
+0x1440fffd, 0x0, 0x3e00008, 0x0,
+0x3c040800, 0x8c840000, 0x3c030800, 0x8c630a40,
+0x64102b, 0x54400002, 0x831023, 0x641023,
+0x2c420008, 0x3e00008, 0x38420001, 0x27bdffe0,
+0x802821, 0x3c040800, 0x24840a00, 0x3021,
+0x3821, 0xafbf0018, 0xafa00010, 0xe000060,
+0xafa00014, 0xa000216, 0x0, 0x8fbf0018,
+0x3e00008, 0x27bd0020, 0x0, 0x27bdffe0,
+0x3c1cc000, 0xafbf0018, 0xe00004c, 0xaf80680c,
+0x3c040800, 0x24840a10, 0x3802821, 0x3021,
+0x3821, 0xafa00010, 0xe000060, 0xafa00014,
+0x2402ffff, 0xaf825404, 0x3c0200aa, 0xe000234,
+0xaf825434, 0x8fbf0018, 0x3e00008, 0x27bd0020,
+0x0, 0x0, 0x0, 0x27bdffe8,
+0xafb00010, 0x24100001, 0xafbf0014, 0x3c01c003,
+0xac200000, 0x8f826810, 0x30422000, 0x10400003,
+0x0, 0xe000246, 0x0, 0xa00023a,
+0xaf905428, 0x8fbf0014, 0x8fb00010, 0x3e00008,
+0x27bd0018, 0x27bdfff8, 0x8f845d0c, 0x3c0200ff,
+0x3c030800, 0x8c630a50, 0x3442fff8, 0x821024,
+0x1043001e, 0x3c0500ff, 0x34a5fff8, 0x3c06c003,
+0x3c074000, 0x851824, 0x8c620010, 0x3c010800,
+0xac230a50, 0x30420008, 0x10400005, 0x871025,
+0x8cc20000, 0x24420001, 0xacc20000, 0x871025,
+0xaf825d0c, 0x8fa20000, 0x24420001, 0xafa20000,
+0x8fa20000, 0x8fa20000, 0x24420001, 0xafa20000,
+0x8fa20000, 0x8f845d0c, 0x3c030800, 0x8c630a50,
+0x851024, 0x1443ffe8, 0x851824, 0x27bd0008,
+0x3e00008, 0x0, 0x0, 0x0 };
+U32 t3FwRodata[(0x60/4) + 1] = {
+0x35373031, 0x726c7341, 0x0,
+0x0, 0x53774576, 0x656e7430, 0x0,
+0x726c7045, 0x76656e74, 0x31000000, 0x556e6b6e,
+0x45766e74, 0x0, 0x0, 0x0,
+0x0, 0x66617461, 0x6c457272, 0x0,
+0x0, 0x4d61696e, 0x43707542, 0x0,
+0x0, 0x0 };
+U32 t3FwData[(0x20/4) + 1] = {
+0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0,
+0x0, 0x0 };
--- /dev/null
+/******************************************************************************/
+/* */
+/* Broadcom BCM5700 Linux Network Driver, Copyright (c) 2001 Broadcom */
+/* Corporation. */
+/* All rights reserved. */
+/* */
+/* 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, located in the file LICENSE. */
+/* */
+/* History: */
+/******************************************************************************/
+
+
+#ifndef AUTONEG_H
+#define AUTONEG_H
+
+
+
+/******************************************************************************/
+/* Constants. */
+/******************************************************************************/
+
+#define AN_LINK_TIMER_INTERVAL_US 9000 /* 10ms */
+
+/* TRUE, FALSE */
+#define AN_TRUE 1
+#define AN_FALSE 0
+
+
+
+/******************************************************************************/
+/* Main data structure for keeping track of 802.3z auto-negotation state */
+/* variables as shown in Figure 37-6 of the IEEE 802.3z specification. */
+/******************************************************************************/
+
+typedef struct
+{
+ /* Current auto-negotiation state. */
+ unsigned long State;
+ #define AN_STATE_UNKNOWN 0
+ #define AN_STATE_AN_ENABLE 1
+ #define AN_STATE_AN_RESTART_INIT 2
+ #define AN_STATE_AN_RESTART 3
+ #define AN_STATE_DISABLE_LINK_OK 4
+ #define AN_STATE_ABILITY_DETECT_INIT 5
+ #define AN_STATE_ABILITY_DETECT 6
+ #define AN_STATE_ACK_DETECT_INIT 7
+ #define AN_STATE_ACK_DETECT 8
+ #define AN_STATE_COMPLETE_ACK_INIT 9
+ #define AN_STATE_COMPLETE_ACK 10
+ #define AN_STATE_IDLE_DETECT_INIT 11
+ #define AN_STATE_IDLE_DETECT 12
+ #define AN_STATE_LINK_OK 13
+ #define AN_STATE_NEXT_PAGE_WAIT_INIT 14
+ #define AN_STATE_NEXT_PAGE_WAIT 16
+
+ /* Link timer. */
+ unsigned long LinkTime_us;
+
+ /* Current time. */
+ unsigned long CurrentTime_us;
+
+ /* Need these values for consistency check. */
+ unsigned short AbilityMatchCfg;
+
+ /* Ability, idle, and ack match functions. */
+ unsigned long AbilityMatchCnt;
+ char AbilityMatch;
+ char IdleMatch;
+ char AckMatch;
+
+ /* Tx config data */
+ union
+ {
+ /* The TxConfig register is arranged as follows: */
+ /* */
+ /* MSB LSB */
+ /* +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ */
+ /* | D7| D6| D5| D4| D3| D2| D1| D0|D15|D14|D13|D12|D11|D10| D9| D8| */
+ /* +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ */
+ struct
+ {
+#ifdef BIG_ENDIAN_HOST
+ unsigned int D7:1; /* PS1 */
+ unsigned int D6:1; /* HD */
+ unsigned int D5:1; /* FD */
+ unsigned int D4:1;
+ unsigned int D3:1;
+ unsigned int D2:1;
+ unsigned int D1:1;
+ unsigned int D0:1;
+ unsigned int D15:1; /* NP */
+ unsigned int D14:1; /* ACK */
+ unsigned int D13:1; /* RF2 */
+ unsigned int D12:1; /* RF1 */
+ unsigned int D11:1;
+ unsigned int D10:1;
+ unsigned int D9:1;
+ unsigned int D8:1; /* PS2 */
+#else /* BIG_ENDIAN_HOST */
+ unsigned int D8:1; /* PS2 */
+ unsigned int D9:1;
+ unsigned int D10:1;
+ unsigned int D11:1;
+ unsigned int D12:1; /* RF1 */
+ unsigned int D13:1; /* RF2 */
+ unsigned int D14:1; /* ACK */
+ unsigned int D15:1; /* NP */
+ unsigned int D0:1;
+ unsigned int D1:1;
+ unsigned int D2:1;
+ unsigned int D3:1;
+ unsigned int D4:1;
+ unsigned int D5:1; /* FD */
+ unsigned int D6:1; /* HD */
+ unsigned int D7:1; /* PS1 */
+#endif
+ } bits;
+
+ unsigned short AsUSHORT;
+
+ #define D8_PS2 bits.D8
+ #define D12_RF1 bits.D12
+ #define D13_RF2 bits.D13
+ #define D14_ACK bits.D14
+ #define D15_NP bits.D15
+ #define D5_FD bits.D5
+ #define D6_HD bits.D6
+ #define D7_PS1 bits.D7
+ } TxConfig;
+
+ /* Rx config data */
+ union
+ {
+ /* The RxConfig register is arranged as follows: */
+ /* */
+ /* MSB LSB */
+ /* +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ */
+ /* | D7| D6| D5| D4| D3| D2| D1| D0|D15|D14|D13|D12|D11|D10| D9| D8| */
+ /* +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ */
+ struct
+ {
+#ifdef BIG_ENDIAN_HOST
+ unsigned int D7:1; /* PS1 */
+ unsigned int D6:1; /* HD */
+ unsigned int D5:1; /* FD */
+ unsigned int D4:1;
+ unsigned int D3:1;
+ unsigned int D2:1;
+ unsigned int D1:1;
+ unsigned int D0:1;
+ unsigned int D15:1; /* NP */
+ unsigned int D14:1; /* ACK */
+ unsigned int D13:1; /* RF2 */
+ unsigned int D12:1; /* RF1 */
+ unsigned int D11:1;
+ unsigned int D10:1;
+ unsigned int D9:1;
+ unsigned int D8:1; /* PS2 */
+#else /* BIG_ENDIAN_HOST */
+ unsigned int D8:1; /* PS2 */
+ unsigned int D9:1;
+ unsigned int D10:1;
+ unsigned int D11:1;
+ unsigned int D12:1; /* RF1 */
+ unsigned int D13:1; /* RF2 */
+ unsigned int D14:1; /* ACK */
+ unsigned int D15:1; /* NP */
+ unsigned int D0:1;
+ unsigned int D1:1;
+ unsigned int D2:1;
+ unsigned int D3:1;
+ unsigned int D4:1;
+ unsigned int D5:1; /* FD */
+ unsigned int D6:1; /* HD */
+ unsigned int D7:1; /* PS1 */
+#endif
+ } bits;
+
+ unsigned short AsUSHORT;
+ } RxConfig;
+
+ #define AN_CONFIG_NP 0x0080
+ #define AN_CONFIG_ACK 0x0040
+ #define AN_CONFIG_RF2 0x0020
+ #define AN_CONFIG_RF1 0x0010
+ #define AN_CONFIG_PS2 0x0001
+ #define AN_CONFIG_PS1 0x8000
+ #define AN_CONFIG_HD 0x4000
+ #define AN_CONFIG_FD 0x2000
+
+
+ /* Management registers. */
+
+ /* Control register. */
+ union
+ {
+ struct
+ {
+ unsigned int an_enable:1;
+ unsigned int loopback:1;
+ unsigned int reset:1;
+ unsigned int restart_an:1;
+ } bits;
+
+ unsigned short AsUSHORT;
+
+ #define mr_an_enable Mr0.bits.an_enable
+ #define mr_loopback Mr0.bits.loopback
+ #define mr_main_reset Mr0.bits.reset
+ #define mr_restart_an Mr0.bits.restart_an
+ } Mr0;
+
+ /* Status register. */
+ union
+ {
+ struct
+ {
+ unsigned int an_complete:1;
+ unsigned int link_ok:1;
+ } bits;
+
+ unsigned short AsUSHORT;
+
+ #define mr_an_complete Mr1.bits.an_complete
+ #define mr_link_ok Mr1.bits.link_ok
+ } Mr1;
+
+ /* Advertisement register. */
+ union
+ {
+ struct
+ {
+ unsigned int reserved_4:5;
+ unsigned int full_duplex:1;
+ unsigned int half_duplex:1;
+ unsigned int sym_pause:1;
+ unsigned int asym_pause:1;
+ unsigned int reserved_11:3;
+ unsigned int remote_fault1:1;
+ unsigned int remote_fault2:1;
+ unsigned int reserved_14:1;
+ unsigned int next_page:1;
+ } bits;
+
+ unsigned short AsUSHORT;
+
+ #define mr_adv_full_duplex Mr4.bits.full_duplex
+ #define mr_adv_half_duplex Mr4.bits.half_duplex
+ #define mr_adv_sym_pause Mr4.bits.sym_pause
+ #define mr_adv_asym_pause Mr4.bits.asym_pause
+ #define mr_adv_remote_fault1 Mr4.bits.remote_fault1
+ #define mr_adv_remote_fault2 Mr4.bits.remote_fault2
+ #define mr_adv_next_page Mr4.bits.next_page
+ } Mr4;
+
+ /* Link partner advertisement register. */
+ union
+ {
+ struct
+ {
+ unsigned int reserved_4:5;
+ unsigned int lp_full_duplex:1;
+ unsigned int lp_half_duplex:1;
+ unsigned int lp_sym_pause:1;
+ unsigned int lp_asym_pause:1;
+ unsigned int reserved_11:3;
+ unsigned int lp_remote_fault1:1;
+ unsigned int lp_remote_fault2:1;
+ unsigned int lp_ack:1;
+ unsigned int lp_next_page:1;
+ } bits;
+
+ unsigned short AsUSHORT;
+
+ #define mr_lp_adv_full_duplex Mr5.bits.lp_full_duplex
+ #define mr_lp_adv_half_duplex Mr5.bits.lp_half_duplex
+ #define mr_lp_adv_sym_pause Mr5.bits.lp_sym_pause
+ #define mr_lp_adv_asym_pause Mr5.bits.lp_asym_pause
+ #define mr_lp_adv_remote_fault1 Mr5.bits.lp_remote_fault1
+ #define mr_lp_adv_remote_fault2 Mr5.bits.lp_remote_fault2
+ #define mr_lp_adv_next_page Mr5.bits.lp_next_page
+ } Mr5;
+
+ /* Auto-negotiation expansion register. */
+ union
+ {
+ struct
+ {
+ unsigned int reserved_0:1;
+ unsigned int page_received:1;
+ unsigned int next_pageable:1;
+ unsigned int reserved_15:13;
+ } bits;
+
+ unsigned short AsUSHORT;
+ } Mr6;
+
+ /* Auto-negotiation next page transmit register. */
+ union
+ {
+ struct
+ {
+ unsigned int code_field:11;
+ unsigned int toggle:1;
+ unsigned int ack2:1;
+ unsigned int message_page:1;
+ unsigned int reserved_14:1;
+ unsigned int next_page:1;
+ } bits;
+
+ unsigned short AsUSHORT;
+
+ #define mr_np_tx Mr7.AsUSHORT
+ } Mr7;
+
+ /* Auto-negotiation link partner ability register. */
+ union
+ {
+ struct
+ {
+ unsigned int code_field:11;
+ unsigned int toggle:1;
+ unsigned int ack2:1;
+ unsigned int message_page:1;
+ unsigned int ack:1;
+ unsigned int next_page:1;
+ } bits;
+
+ unsigned short AsUSHORT;
+
+ #define mr_lp_np_rx Mr8.AsUSHORT
+ } Mr8;
+
+ /* Extended status register. */
+ union
+ {
+ struct
+ {
+ unsigned int reserved_11:12;
+ unsigned int base1000_t_hd:1;
+ unsigned int base1000_t_fd:1;
+ unsigned int base1000_x_hd:1;
+ unsigned int base1000_x_fd:1;
+ } bits;
+
+ unsigned short AsUSHORT;
+ } Mr15;
+
+ /* Miscellaneous state variables. */
+ union
+ {
+ struct
+ {
+ unsigned int toggle_tx:1;
+ unsigned int toggle_rx:1;
+ unsigned int np_rx:1;
+ unsigned int page_rx:1;
+ unsigned int np_loaded:1;
+ } bits;
+
+ unsigned short AsUSHORT;
+
+ #define mr_toggle_tx MrMisc.bits.toggle_tx
+ #define mr_toggle_rx MrMisc.bits.toggle_rx
+ #define mr_np_rx MrMisc.bits.np_rx
+ #define mr_page_rx MrMisc.bits.page_rx
+ #define mr_np_loaded MrMisc.bits.np_loaded
+ } MrMisc;
+
+
+ /* Implement specifics */
+
+ /* Pointer to the operating system specific data structure. */
+ void *pContext;
+} AN_STATE_INFO, *PAN_STATE_INFO;
+
+
+
+/******************************************************************************/
+/* Return code of Autoneg8023z. */
+/******************************************************************************/
+
+typedef enum
+{
+ AUTONEG_STATUS_OK = 0,
+ AUTONEG_STATUS_DONE = 1,
+ AUTONEG_STATUS_TIMER_ENABLED = 2,
+ AUTONEG_STATUS_FAILED = 0xfffffff
+} AUTONEG_STATUS, *PAUTONEG_STATUS;
+
+
+
+/******************************************************************************/
+/* Function prototypes. */
+/******************************************************************************/
+
+AUTONEG_STATUS Autoneg8023z(PAN_STATE_INFO pAnInfo);
+void AutonegInit(PAN_STATE_INFO pAnInfo);
+
+
+
+/******************************************************************************/
+/* The following functions are defined in the os-dependent module. */
+/******************************************************************************/
+
+void MM_AnTxConfig(PAN_STATE_INFO pAnInfo);
+void MM_AnTxIdle(PAN_STATE_INFO pAnInfo);
+char MM_AnRxConfig(PAN_STATE_INFO pAnInfo, unsigned short *pRxConfig);
+
+
+
+#endif /* AUTONEG_H */
+
--- /dev/null
+
+/******************************************************************************/
+/* */
+/* Broadcom BCM5700 Linux Network Driver, Copyright (c) 2000 Broadcom */
+/* Corporation. */
+/* All rights reserved. */
+/* */
+/* 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, located in the file LICENSE. */
+/* */
+/* History: */
+/* 02/25/00 Hav Khauv Initial version. */
+/******************************************************************************/
+
+#ifndef DEBUG_H
+#define DEBUG_H
+
+#ifdef VXWORKS
+#include <vxWorks.h>
+#endif
+
+/******************************************************************************/
+/* Debug macros */
+/******************************************************************************/
+
+/* Code path for controlling output debug messages. */
+/* Define your code path here. */
+#define CP_INIT 0x010000
+#define CP_SEND 0x020000
+#define CP_RCV 0x040000
+#define CP_INT 0x080000
+#define CP_UINIT 0x100000
+#define CP_RESET 0x200000
+
+#define CP_ALL (CP_INIT | CP_SEND | CP_RCV | CP_INT | \
+ CP_RESET | CP_UINIT)
+
+#define CP_MASK 0xffff0000
+
+
+/* Debug message levels. */
+#define LV_VERBOSE 0x03
+#define LV_INFORM 0x02
+#define LV_WARN 0x01
+#define LV_FATAL 0x00
+
+#define LV_MASK 0xffff
+
+
+/* Code path and messsage level combined. These are the first argument of */
+/* the DbgMessage macro. */
+#define INIT_V (CP_INIT | LV_VERBOSE)
+#define INIT_I (CP_INIT | LV_INFORM)
+#define INIT_W (CP_INIT | LV_WARN)
+#define SEND_V (CP_SEND | LV_VERBOSE)
+#define SEND_I (CP_SEND | LV_INFORM)
+#define SEND_W (CP_SEND | LV_WARN)
+#define RCV_V (CP_RCV | LV_VERBOSE)
+#define RCV_I (CP_RCV | LV_INFORM)
+#define RCV_W (CP_RCV | LV_WARN)
+#define INT_V (CP_INT | LV_VERBOSE)
+#define INT_I (CP_INT | LV_INFORM)
+#define INT_W (CP_INT | LV_WARN)
+#define UINIT_V (CP_UINIT | LV_VERBOSE)
+#define UINIT_I (CP_UINIT | LV_INFORM)
+#define UINIT_W (CP_UINIT | LV_WARN)
+#define RESET_V (CP_RESET | LV_VERBOSE)
+#define RESET_I (CP_RESET | LV_INFORM)
+#define RESET_W (CP_RESET | LV_WARN)
+#define CPALL_V (CP_ALL | LV_VERBOSE)
+#define CPALL_I (CP_ALL | LV_INFORM)
+#define CPALL_W (CP_ALL | LV_WARN)
+
+
+/* All code path message levels. */
+#define FATAL (CP_ALL | LV_FATAL)
+#define WARN (CP_ALL | LV_WARN)
+#define INFORM (CP_ALL | LV_INFORM)
+#define VERBOSE (CP_ALL | LV_VERBOSE)
+
+
+/* These constants control the message output. */
+/* Set your debug message output level and code path here. */
+#ifndef DBG_MSG_CP
+#define DBG_MSG_CP CP_ALL /* Where to output messages. */
+#endif
+
+#ifndef DBG_MSG_LV
+#define DBG_MSG_LV LV_VERBOSE /* Level of message output. */
+#endif
+
+/* DbgMessage macro. */
+#if DBG
+#define DbgMessage(CNTRL, MESSAGE) \
+ if((CNTRL & DBG_MSG_CP) && ((CNTRL & LV_MASK) <= DBG_MSG_LV)) \
+ printf MESSAGE
+#define DbgBreak() DbgBreakPoint()
+#undef STATIC
+#define STATIC
+#else
+#define DbgMessage(CNTRL, MESSAGE)
+#define DbgBreak()
+#undef STATIC
+#define STATIC static
+#endif /* DBG */
+
+
+
+#endif /* DEBUG_H */
+
--- /dev/null
+
+/******************************************************************************/
+/* */
+/* Broadcom BCM5700 Linux Network Driver, Copyright (c) 2000 Broadcom */
+/* Corporation. */
+/* All rights reserved. */
+/* */
+/* 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, located in the file LICENSE. */
+/* */
+/* History: */
+/* 02/25/00 Hav Khauv Initial version. */
+/******************************************************************************/
+
+#ifndef LM_H
+#define LM_H
+
+#include "bcm570x_queue.h"
+#include "bcm570x_bits.h"
+
+
+
+/******************************************************************************/
+/* Basic types. */
+/******************************************************************************/
+
+typedef char LM_CHAR, *PLM_CHAR;
+typedef unsigned int LM_UINT, *PLM_UINT;
+typedef unsigned char LM_UINT8, *PLM_UINT8;
+typedef unsigned short LM_UINT16, *PLM_UINT16;
+typedef unsigned int LM_UINT32, *PLM_UINT32;
+typedef unsigned int LM_COUNTER, *PLM_COUNTER;
+typedef void LM_VOID, *PLM_VOID;
+typedef char LM_BOOL, *PLM_BOOL;
+
+/* 64bit value. */
+typedef struct {
+#ifdef BIG_ENDIAN_HOST
+ LM_UINT32 High;
+ LM_UINT32 Low;
+#else /* BIG_ENDIAN_HOST */
+ LM_UINT32 Low;
+ LM_UINT32 High;
+#endif /* !BIG_ENDIAN_HOST */
+} LM_UINT64, *PLM_UINT64;
+
+typedef LM_UINT64 LM_PHYSICAL_ADDRESS, *PLM_PHYSICAL_ADDRESS;
+
+/* void LM_INC_PHYSICAL_ADDRESS(PLM_PHYSICAL_ADDRESS pAddr,LM_UINT32 IncSize) */
+#define LM_INC_PHYSICAL_ADDRESS(pAddr, IncSize) \
+ { \
+ LM_UINT32 OrgLow; \
+ \
+ OrgLow = (pAddr)->Low; \
+ (pAddr)->Low += IncSize; \
+ if((pAddr)->Low < OrgLow) { \
+ (pAddr)->High++; /* Wrap around. */ \
+ } \
+ }
+
+
+#ifndef NULL
+#define NULL ((void *) 0)
+#endif /* NULL */
+
+#ifndef OFFSETOF
+#define OFFSETOF(_s, _m) (MM_UINT_PTR(&(((_s *) 0)->_m)))
+#endif /* OFFSETOF */
+
+
+
+/******************************************************************************/
+/* Simple macros. */
+/******************************************************************************/
+
+#define IS_ETH_BROADCAST(_pEthAddr) \
+ (((unsigned char *) (_pEthAddr))[0] == ((unsigned char) 0xff))
+
+#define IS_ETH_MULTICAST(_pEthAddr) \
+ (((unsigned char *) (_pEthAddr))[0] & ((unsigned char) 0x01))
+
+#define IS_ETH_ADDRESS_EQUAL(_pEtherAddr1, _pEtherAddr2) \
+ ((((unsigned char *) (_pEtherAddr1))[0] == \
+ ((unsigned char *) (_pEtherAddr2))[0]) && \
+ (((unsigned char *) (_pEtherAddr1))[1] == \
+ ((unsigned char *) (_pEtherAddr2))[1]) && \
+ (((unsigned char *) (_pEtherAddr1))[2] == \
+ ((unsigned char *) (_pEtherAddr2))[2]) && \
+ (((unsigned char *) (_pEtherAddr1))[3] == \
+ ((unsigned char *) (_pEtherAddr2))[3]) && \
+ (((unsigned char *) (_pEtherAddr1))[4] == \
+ ((unsigned char *) (_pEtherAddr2))[4]) && \
+ (((unsigned char *) (_pEtherAddr1))[5] == \
+ ((unsigned char *) (_pEtherAddr2))[5]))
+
+#define COPY_ETH_ADDRESS(_Src, _Dst) \
+ ((unsigned char *) (_Dst))[0] = ((unsigned char *) (_Src))[0]; \
+ ((unsigned char *) (_Dst))[1] = ((unsigned char *) (_Src))[1]; \
+ ((unsigned char *) (_Dst))[2] = ((unsigned char *) (_Src))[2]; \
+ ((unsigned char *) (_Dst))[3] = ((unsigned char *) (_Src))[3]; \
+ ((unsigned char *) (_Dst))[4] = ((unsigned char *) (_Src))[4]; \
+ ((unsigned char *) (_Dst))[5] = ((unsigned char *) (_Src))[5];
+
+
+
+/******************************************************************************/
+/* Constants. */
+/******************************************************************************/
+
+#define ETHERNET_ADDRESS_SIZE 6
+#define ETHERNET_PACKET_HEADER_SIZE 14
+#define MIN_ETHERNET_PACKET_SIZE 64 /* with 4 byte crc. */
+#define MAX_ETHERNET_PACKET_SIZE 1518 /* with 4 byte crc. */
+#define MIN_ETHERNET_PACKET_SIZE_NO_CRC 60
+#define MAX_ETHERNET_PACKET_SIZE_NO_CRC 1514
+#define MAX_ETHERNET_PACKET_BUFFER_SIZE 1536 /* A nice even number. */
+
+#ifndef LM_MAX_MC_TABLE_SIZE
+#define LM_MAX_MC_TABLE_SIZE 32
+#endif /* LM_MAX_MC_TABLE_SIZE */
+#define LM_MC_ENTRY_SIZE (ETHERNET_ADDRESS_SIZE+1)
+#define LM_MC_INSTANCE_COUNT_INDEX (LM_MC_ENTRY_SIZE-1)
+
+
+/* Receive filter masks. */
+#define LM_ACCEPT_UNICAST 0x0001
+#define LM_ACCEPT_MULTICAST 0x0002
+#define LM_ACCEPT_ALL_MULTICAST 0x0004
+#define LM_ACCEPT_BROADCAST 0x0008
+#define LM_ACCEPT_ERROR_PACKET 0x0010
+
+#define LM_PROMISCUOUS_MODE 0x10000
+
+
+
+/******************************************************************************/
+/* PCI registers. */
+/******************************************************************************/
+
+#define PCI_VENDOR_ID_REG 0x00
+#define PCI_DEVICE_ID_REG 0x02
+
+#define PCI_COMMAND_REG 0x04
+#define PCI_IO_SPACE_ENABLE 0x0001
+#define PCI_MEM_SPACE_ENABLE 0x0002
+#define PCI_BUSMASTER_ENABLE 0x0004
+#define PCI_MEMORY_WRITE_INVALIDATE 0x0010
+#define PCI_PARITY_ERROR_ENABLE 0x0040
+#define PCI_SYSTEM_ERROR_ENABLE 0x0100
+#define PCI_FAST_BACK_TO_BACK_ENABLE 0x0200
+
+#define PCI_STATUS_REG 0x06
+#define PCI_REV_ID_REG 0x08
+
+#define PCI_CACHE_LINE_SIZE_REG 0x0c
+
+#define PCI_IO_BASE_ADDR_REG 0x10
+#define PCI_IO_BASE_ADDR_MASK 0xfffffff0
+
+#define PCI_MEM_BASE_ADDR_LOW 0x10
+#define PCI_MEM_BASE_ADDR_HIGH 0x14
+
+#define PCI_SUBSYSTEM_VENDOR_ID_REG 0x2c
+#define PCI_SUBSYSTEM_ID_REG 0x2e
+#define PCI_INT_LINE_REG 0x3c
+
+#define PCIX_CAP_REG 0x40
+#define PCIX_ENABLE_RELAXED_ORDERING BIT_17
+
+/******************************************************************************/
+/* Fragment structure. */
+/******************************************************************************/
+
+typedef struct {
+ LM_UINT32 FragSize;
+ LM_PHYSICAL_ADDRESS FragBuf;
+} LM_FRAG, *PLM_FRAG;
+
+typedef struct {
+ /* FragCount is initialized for the caller to the maximum array size, on */
+ /* return FragCount is the number of the actual fragments in the array. */
+ LM_UINT32 FragCount;
+
+ /* Total buffer size. */
+ LM_UINT32 TotalSize;
+
+ /* Fragment array buffer. */
+ LM_FRAG Fragments[1];
+} LM_FRAG_LIST, *PLM_FRAG_LIST;
+
+#define DECLARE_FRAG_LIST_BUFFER_TYPE(_FRAG_LIST_TYPE_NAME, _MAX_FRAG_COUNT) \
+ typedef struct { \
+ LM_FRAG_LIST FragList; \
+ LM_FRAG FragListBuffer[_MAX_FRAG_COUNT-1]; \
+ } _FRAG_LIST_TYPE_NAME, *P##_FRAG_LIST_TYPE_NAME
+
+
+
+/******************************************************************************/
+/* Status codes. */
+/******************************************************************************/
+
+#define LM_STATUS_SUCCESS 0
+#define LM_STATUS_FAILURE 1
+
+#define LM_STATUS_INTERRUPT_ACTIVE 2
+#define LM_STATUS_INTERRUPT_NOT_ACTIVE 3
+
+#define LM_STATUS_LINK_ACTIVE 4
+#define LM_STATUS_LINK_DOWN 5
+#define LM_STATUS_LINK_SETTING_MISMATCH 6
+
+#define LM_STATUS_TOO_MANY_FRAGMENTS 7
+#define LM_STATUS_TRANSMIT_ABORTED 8
+#define LM_STATUS_TRANSMIT_ERROR 9
+#define LM_STATUS_RECEIVE_ABORTED 10
+#define LM_STATUS_RECEIVE_ERROR 11
+#define LM_STATUS_INVALID_PACKET_SIZE 12
+#define LM_STATUS_OUT_OF_MAP_REGISTERS 13
+#define LM_STATUS_UNKNOWN_ADAPTER 14
+
+typedef LM_UINT LM_STATUS, *PLM_STATUS;
+
+
+
+/******************************************************************************/
+/* Requested media type. */
+/******************************************************************************/
+
+#define LM_REQUESTED_MEDIA_TYPE_AUTO 0
+#define LM_REQUESTED_MEDIA_TYPE_BNC 1
+#define LM_REQUESTED_MEDIA_TYPE_UTP_AUTO 2
+#define LM_REQUESTED_MEDIA_TYPE_UTP_10MBPS 3
+#define LM_REQUESTED_MEDIA_TYPE_UTP_10MBPS_FULL_DUPLEX 4
+#define LM_REQUESTED_MEDIA_TYPE_UTP_100MBPS 5
+#define LM_REQUESTED_MEDIA_TYPE_UTP_100MBPS_FULL_DUPLEX 6
+#define LM_REQUESTED_MEDIA_TYPE_UTP_1000MBPS 7
+#define LM_REQUESTED_MEDIA_TYPE_UTP_1000MBPS_FULL_DUPLEX 8
+#define LM_REQUESTED_MEDIA_TYPE_FIBER_100MBPS 9
+#define LM_REQUESTED_MEDIA_TYPE_FIBER_100MBPS_FULL_DUPLEX 10
+#define LM_REQUESTED_MEDIA_TYPE_FIBER_1000MBPS 11
+#define LM_REQUESTED_MEDIA_TYPE_FIBER_1000MBPS_FULL_DUPLEX 12
+#define LM_REQUESTED_MEDIA_TYPE_MAC_LOOPBACK 0xfffe
+#define LM_REQUESTED_MEDIA_TYPE_PHY_LOOPBACK 0xffff
+
+typedef LM_UINT32 LM_REQUESTED_MEDIA_TYPE, *PLM_REQUESTED_MEDIA_TYPE;
+
+
+
+/******************************************************************************/
+/* Media type. */
+/******************************************************************************/
+
+#define LM_MEDIA_TYPE_UNKNOWN -1
+#define LM_MEDIA_TYPE_AUTO 0
+#define LM_MEDIA_TYPE_UTP 1
+#define LM_MEDIA_TYPE_BNC 2
+#define LM_MEDIA_TYPE_AUI 3
+#define LM_MEDIA_TYPE_FIBER 4
+
+typedef LM_UINT32 LM_MEDIA_TYPE, *PLM_MEDIA_TYPE;
+
+
+
+/******************************************************************************/
+/* Line speed. */
+/******************************************************************************/
+
+#define LM_LINE_SPEED_UNKNOWN 0
+#define LM_LINE_SPEED_10MBPS 1
+#define LM_LINE_SPEED_100MBPS 2
+#define LM_LINE_SPEED_1000MBPS 3
+
+typedef LM_UINT32 LM_LINE_SPEED, *PLM_LINE_SPEED;
+
+
+
+/******************************************************************************/
+/* Duplex mode. */
+/******************************************************************************/
+
+#define LM_DUPLEX_MODE_UNKNOWN 0
+#define LM_DUPLEX_MODE_HALF 1
+#define LM_DUPLEX_MODE_FULL 2
+
+typedef LM_UINT32 LM_DUPLEX_MODE, *PLM_DUPLEX_MODE;
+
+
+
+/******************************************************************************/
+/* Power state. */
+/******************************************************************************/
+
+#define LM_POWER_STATE_D0 0
+#define LM_POWER_STATE_D1 1
+#define LM_POWER_STATE_D2 2
+#define LM_POWER_STATE_D3 3
+
+typedef LM_UINT32 LM_POWER_STATE, *PLM_POWER_STATE;
+
+
+
+/******************************************************************************/
+/* Task offloading. */
+/******************************************************************************/
+
+#define LM_TASK_OFFLOAD_NONE 0x0000
+#define LM_TASK_OFFLOAD_TX_IP_CHECKSUM 0x0001
+#define LM_TASK_OFFLOAD_RX_IP_CHECKSUM 0x0002
+#define LM_TASK_OFFLOAD_TX_TCP_CHECKSUM 0x0004
+#define LM_TASK_OFFLOAD_RX_TCP_CHECKSUM 0x0008
+#define LM_TASK_OFFLOAD_TX_UDP_CHECKSUM 0x0010
+#define LM_TASK_OFFLOAD_RX_UDP_CHECKSUM 0x0020
+#define LM_TASK_OFFLOAD_TCP_SEGMENTATION 0x0040
+
+typedef LM_UINT32 LM_TASK_OFFLOAD, *PLM_TASK_OFFLOAD;
+
+
+
+/******************************************************************************/
+/* Flow control. */
+/******************************************************************************/
+
+#define LM_FLOW_CONTROL_NONE 0x00
+#define LM_FLOW_CONTROL_RECEIVE_PAUSE 0x01
+#define LM_FLOW_CONTROL_TRANSMIT_PAUSE 0x02
+#define LM_FLOW_CONTROL_RX_TX_PAUSE (LM_FLOW_CONTROL_RECEIVE_PAUSE | \
+ LM_FLOW_CONTROL_TRANSMIT_PAUSE)
+
+/* This value can be or-ed with RECEIVE_PAUSE and TRANSMIT_PAUSE. If the */
+/* auto-negotiation is disabled and the RECEIVE_PAUSE and TRANSMIT_PAUSE */
+/* bits are set, then flow control is enabled regardless of link partner's */
+/* flow control capability. */
+#define LM_FLOW_CONTROL_AUTO_PAUSE 0x80000000
+
+typedef LM_UINT32 LM_FLOW_CONTROL, *PLM_FLOW_CONTROL;
+
+
+
+/******************************************************************************/
+/* Wake up mode. */
+/******************************************************************************/
+
+#define LM_WAKE_UP_MODE_NONE 0
+#define LM_WAKE_UP_MODE_MAGIC_PACKET 1
+#define LM_WAKE_UP_MODE_NWUF 2
+#define LM_WAKE_UP_MODE_LINK_CHANGE 4
+
+typedef LM_UINT32 LM_WAKE_UP_MODE, *PLM_WAKE_UP_MODE;
+
+
+
+/******************************************************************************/
+/* Counters. */
+/******************************************************************************/
+
+#define LM_COUNTER_FRAMES_XMITTED_OK 0
+#define LM_COUNTER_FRAMES_RECEIVED_OK 1
+#define LM_COUNTER_ERRORED_TRANSMIT_COUNT 2
+#define LM_COUNTER_ERRORED_RECEIVE_COUNT 3
+#define LM_COUNTER_RCV_CRC_ERROR 4
+#define LM_COUNTER_ALIGNMENT_ERROR 5
+#define LM_COUNTER_SINGLE_COLLISION_FRAMES 6
+#define LM_COUNTER_MULTIPLE_COLLISION_FRAMES 7
+#define LM_COUNTER_FRAMES_DEFERRED 8
+#define LM_COUNTER_MAX_COLLISIONS 9
+#define LM_COUNTER_RCV_OVERRUN 10
+#define LM_COUNTER_XMIT_UNDERRUN 11
+#define LM_COUNTER_UNICAST_FRAMES_XMIT 12
+#define LM_COUNTER_MULTICAST_FRAMES_XMIT 13
+#define LM_COUNTER_BROADCAST_FRAMES_XMIT 14
+#define LM_COUNTER_UNICAST_FRAMES_RCV 15
+#define LM_COUNTER_MULTICAST_FRAMES_RCV 16
+#define LM_COUNTER_BROADCAST_FRAMES_RCV 17
+
+typedef LM_UINT32 LM_COUNTER_TYPE, *PLM_COUNTER_TYPE;
+
+
+
+/******************************************************************************/
+/* Forward definition. */
+/******************************************************************************/
+
+typedef struct _LM_DEVICE_BLOCK *PLM_DEVICE_BLOCK;
+typedef struct _LM_PACKET *PLM_PACKET;
+
+
+
+/******************************************************************************/
+/* Function prototypes. */
+/******************************************************************************/
+
+LM_STATUS LM_GetAdapterInfo(PLM_DEVICE_BLOCK pDevice);
+LM_STATUS LM_InitializeAdapter(PLM_DEVICE_BLOCK pDevice);
+LM_STATUS LM_ResetAdapter(PLM_DEVICE_BLOCK pDevice);
+LM_STATUS LM_DisableInterrupt(PLM_DEVICE_BLOCK pDevice);
+LM_STATUS LM_EnableInterrupt(PLM_DEVICE_BLOCK pDevice);
+LM_STATUS LM_SendPacket(PLM_DEVICE_BLOCK pDevice, PLM_PACKET pPacket);
+LM_STATUS LM_ServiceInterrupts(PLM_DEVICE_BLOCK pDevice);
+LM_STATUS LM_QueueRxPackets(PLM_DEVICE_BLOCK pDevice);
+LM_STATUS LM_SetReceiveMask(PLM_DEVICE_BLOCK pDevice, LM_UINT32 Mask);
+LM_STATUS LM_Halt(PLM_DEVICE_BLOCK pDevice);
+LM_STATUS LM_Abort(PLM_DEVICE_BLOCK pDevice);
+LM_STATUS LM_MulticastAdd(PLM_DEVICE_BLOCK pDevice, PLM_UINT8 pMcAddress);
+LM_STATUS LM_MulticastDel(PLM_DEVICE_BLOCK pDevice, PLM_UINT8 pMcAddress);
+LM_STATUS LM_MulticastClear(PLM_DEVICE_BLOCK pDevice);
+LM_STATUS LM_SetMacAddress(PLM_DEVICE_BLOCK pDevice, PLM_UINT8 pMacAddress);
+LM_STATUS LM_LoopbackAddress(PLM_DEVICE_BLOCK pDevice, PLM_UINT8 pAddress);
+
+LM_UINT32 LM_GetCrcCounter(PLM_DEVICE_BLOCK pDevice);
+
+LM_WAKE_UP_MODE LM_PMCapabilities(PLM_DEVICE_BLOCK pDevice);
+LM_STATUS LM_NwufAdd(PLM_DEVICE_BLOCK pDevice, LM_UINT32 ByteMaskSize,
+ LM_UINT8 *pByteMask, LM_UINT8 *pPattern);
+LM_STATUS LM_NwufRemove(PLM_DEVICE_BLOCK pDevice, LM_UINT32 ByteMaskSize,
+ LM_UINT8 *pByteMask, LM_UINT8 *pPattern);
+LM_STATUS LM_SetPowerState(PLM_DEVICE_BLOCK pDevice, LM_POWER_STATE PowerLevel);
+
+LM_VOID LM_ReadPhy(PLM_DEVICE_BLOCK pDevice, LM_UINT32 PhyReg,
+ PLM_UINT32 pData32);
+LM_VOID LM_WritePhy(PLM_DEVICE_BLOCK pDevice, LM_UINT32 PhyReg,
+ LM_UINT32 Data32);
+
+LM_STATUS LM_ControlLoopBack(PLM_DEVICE_BLOCK pDevice, LM_UINT32 Control);
+LM_STATUS LM_SetupPhy(PLM_DEVICE_BLOCK pDevice);
+int LM_BlinkLED(PLM_DEVICE_BLOCK pDevice, LM_UINT32 BlinkDuration);
+
+
+
+/******************************************************************************/
+/* These are the OS specific functions called by LMAC. */
+/******************************************************************************/
+
+LM_STATUS MM_ReadConfig16(PLM_DEVICE_BLOCK pDevice, LM_UINT32 Offset,
+ LM_UINT16 *pValue16);
+LM_STATUS MM_WriteConfig16(PLM_DEVICE_BLOCK pDevice, LM_UINT32 Offset,
+ LM_UINT16 Value16);
+LM_STATUS MM_ReadConfig32(PLM_DEVICE_BLOCK pDevice, LM_UINT32 Offset,
+ LM_UINT32 *pValue32);
+LM_STATUS MM_WriteConfig32(PLM_DEVICE_BLOCK pDevice, LM_UINT32 Offset,
+ LM_UINT32 Value32);
+LM_STATUS MM_MapMemBase(PLM_DEVICE_BLOCK pDevice);
+LM_STATUS MM_MapIoBase(PLM_DEVICE_BLOCK pDevice);
+LM_STATUS MM_IndicateRxPackets(PLM_DEVICE_BLOCK pDevice);
+LM_STATUS MM_IndicateTxPackets(PLM_DEVICE_BLOCK pDevice);
+LM_STATUS MM_StartTxDma(PLM_DEVICE_BLOCK pDevice, PLM_PACKET pPacket);
+LM_STATUS MM_CompleteTxDma(PLM_DEVICE_BLOCK pDevice, PLM_PACKET pPacket);
+LM_STATUS MM_AllocateMemory(PLM_DEVICE_BLOCK pDevice, LM_UINT32 BlockSize,
+ PLM_VOID *pMemoryBlockVirt);
+LM_STATUS MM_AllocateSharedMemory(PLM_DEVICE_BLOCK pDevice, LM_UINT32 BlockSize,
+ PLM_VOID *pMemoryBlockVirt, PLM_PHYSICAL_ADDRESS pMemoryBlockPhy,
+ LM_BOOL Cached);
+LM_STATUS MM_GetConfig(PLM_DEVICE_BLOCK pDevice);
+LM_STATUS MM_IndicateStatus(PLM_DEVICE_BLOCK pDevice, LM_STATUS Status);
+LM_STATUS MM_InitializeUmPackets(PLM_DEVICE_BLOCK pDevice);
+LM_STATUS MM_FreeRxBuffer(PLM_DEVICE_BLOCK pDevice, PLM_PACKET pPacket);
+LM_STATUS MM_CoalesceTxBuffer(PLM_DEVICE_BLOCK pDevice, PLM_PACKET pPacket);
+LM_STATUS LM_MbufWorkAround(PLM_DEVICE_BLOCK pDevice);
+LM_STATUS LM_SetLinkSpeed(PLM_DEVICE_BLOCK pDevice,
+ LM_REQUESTED_MEDIA_TYPE RequestedMediaType);
+
+#if INCLUDE_5703_A0_FIX
+LM_STATUS LM_Load5703DmaWFirmware(PLM_DEVICE_BLOCK pDevice);
+#endif
+
+
+#endif /* LM_H */
+
--- /dev/null
+
+/******************************************************************************/
+/* */
+/* Broadcom BCM5700 Linux Network Driver, Copyright (c) 2000 Broadcom */
+/* Corporation. */
+/* All rights reserved. */
+/* */
+/* 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, located in the file LICENSE. */
+/* */
+/******************************************************************************/
+
+#ifndef MM_H
+#define MM_H
+
+#define __raw_readl readl
+#define __raw_writel writel
+
+#define BIG_ENDIAN_HOST 1
+#define readl(addr) (*(volatile unsigned int*)(addr))
+#define writel(b,addr) ((*(volatile unsigned int *) (addr)) = (b))
+
+/* Define memory barrier function here if needed */
+#define wmb()
+#define membar()
+#include <common.h>
+#include <asm/types.h>
+#include "bcm570x_lm.h"
+#include "bcm570x_queue.h"
+#include "tigon3.h"
+#include <pci.h>
+
+#define FALSE 0
+#define TRUE 1
+#define ERROR -1
+
+#if DBG
+#define STATIC
+#else
+#define STATIC static
+#endif
+
+extern int MM_Packet_Desc_Size;
+
+#define MM_PACKET_DESC_SIZE MM_Packet_Desc_Size
+
+DECLARE_QUEUE_TYPE(UM_RX_PACKET_Q, MAX_RX_PACKET_DESC_COUNT+1);
+
+#define MAX_MEM 16
+
+/* Synch */
+typedef int mutex_t;
+typedef int spinlock_t;
+
+/* Embedded device control */
+typedef struct _UM_DEVICE_BLOCK {
+ LM_DEVICE_BLOCK lm_dev;
+ pci_dev_t pdev;
+ char *name;
+ void *mem_list[MAX_MEM];
+ dma_addr_t dma_list[MAX_MEM];
+ int mem_size_list[MAX_MEM];
+ int mem_list_num;
+ int mtu;
+ int index;
+ int opened;
+ int delayed_link_ind; /* Delay link status during initial load */
+ int adapter_just_inited; /* the first few seconds after init. */
+ int spurious_int; /* new -- unsupported */
+ int timer_interval;
+ int adaptive_expiry;
+ int crc_counter_expiry; /* new -- unsupported */
+ int poll_tib_expiry; /* new -- unsupported */
+ int tx_full;
+ int tx_queued;
+ int line_speed; /* in Mbps, 0 if link is down */
+ UM_RX_PACKET_Q rx_out_of_buf_q;
+ int rx_out_of_buf;
+ int rx_low_buf_thresh; /* changed to rx_buf_repl_thresh */
+ int rx_buf_repl_panic_thresh;
+ int rx_buf_align; /* new -- unsupported */
+ int do_global_lock;
+ mutex_t global_lock;
+ mutex_t undi_lock;
+ long undi_flags;
+ volatile int interrupt;
+ int tasklet_pending;
+ int tasklet_busy; /* new -- unsupported */
+ int rx_pkt;
+ int tx_pkt;
+#ifdef NICE_SUPPORT /* unsupported, this is a linux ioctl */
+ void (*nice_rx)(void*, void* );
+ void* nice_ctx;
+#endif /* NICE_SUPPORT */
+ int rx_adaptive_coalesce;
+ unsigned int rx_last_cnt;
+ unsigned int tx_last_cnt;
+ unsigned int rx_curr_coalesce_frames;
+ unsigned int rx_curr_coalesce_ticks;
+ unsigned int tx_curr_coalesce_frames; /* new -- unsupported */
+#if TIGON3_DEBUG /* new -- unsupported */
+ uint tx_zc_count;
+ uint tx_chksum_count;
+ uint tx_himem_count;
+ uint rx_good_chksum_count;
+#endif
+ unsigned int rx_bad_chksum_count; /* new -- unsupported */
+ unsigned int rx_misc_errors; /* new -- unsupported */
+} UM_DEVICE_BLOCK, *PUM_DEVICE_BLOCK;
+
+
+/* Physical/PCI DMA address */
+typedef union {
+ dma_addr_t dma_map;
+} dma_map_t;
+
+/* Packet */
+typedef struct
+_UM_PACKET {
+ LM_PACKET lm_packet;
+ void* skbuff; /* Address of packet buffer */
+} UM_PACKET, *PUM_PACKET;
+
+#define MM_ACQUIRE_UNDI_LOCK(_pDevice)
+#define MM_RELEASE_UNDI_LOCK(_pDevice)
+#define MM_ACQUIRE_INT_LOCK(_pDevice)
+#define MM_RELEASE_INT_LOCK(_pDevice)
+#define MM_UINT_PTR(_ptr) ((unsigned long) (_ptr))
+
+/* Macro for setting 64bit address struct */
+#define set_64bit_addr(paddr, low, high) \
+ (paddr)->Low = low; \
+ (paddr)->High = high;
+
+/* Assume that PCI controller's view of host memory is same as host */
+
+#define MEM_TO_PCI_PHYS(addr) (addr)
+
+extern void MM_SetAddr (LM_PHYSICAL_ADDRESS *paddr, dma_addr_t addr);
+extern void MM_SetT3Addr(T3_64BIT_HOST_ADDR *paddr, dma_addr_t addr);
+extern void MM_MapTxDma (PLM_DEVICE_BLOCK pDevice,
+ struct _LM_PACKET *pPacket, T3_64BIT_HOST_ADDR *paddr,
+ LM_UINT32 *len, int frag);
+extern void MM_MapRxDma ( PLM_DEVICE_BLOCK pDevice,
+ struct _LM_PACKET *pPacket,
+ T3_64BIT_HOST_ADDR *paddr);
+
+
+/* BSP needs to provide sysUsecDelay and sysSerialPrintString */
+extern void sysSerialPrintString (char *s);
+#define MM_Wait(usec) udelay(usec)
+
+/* Define memory barrier function here if needed */
+#define wmb()
+
+#if 0
+#define cpu_to_le32(val) LONGSWAP(val)
+#endif
+#endif /* MM_H */
--- /dev/null
+
+/******************************************************************************/
+/* */
+/* Broadcom BCM5700 Linux Network Driver, Copyright (c) 2000 Broadcom */
+/* Corporation. */
+/* All rights reserved. */
+/* */
+/* 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, located in the file LICENSE. */
+/* */
+/* Queue functions. */
+/* void QQ_InitQueue(PQQ_CONTAINER pQueue) */
+/* char QQ_Full(PQQ_CONTAINER pQueue) */
+/* char QQ_Empty(PQQ_CONTAINER pQueue) */
+/* unsigned int QQ_GetSize(PQQ_CONTAINER pQueue) */
+/* unsigned int QQ_GetEntryCnt(PQQ_CONTAINER pQueue) */
+/* char QQ_PushHead(PQQ_CONTAINER pQueue, PQQ_ENTRY pEntry) */
+/* char QQ_PushTail(PQQ_CONTAINER pQueue, PQQ_ENTRY pEntry) */
+/* PQQ_ENTRY QQ_PopHead(PQQ_CONTAINER pQueue) */
+/* PQQ_ENTRY QQ_PopTail(PQQ_CONTAINER pQueue) */
+/* PQQ_ENTRY QQ_GetHead(PQQ_CONTAINER pQueue, unsigned int Idx) */
+/* PQQ_ENTRY QQ_GetTail(PQQ_CONTAINER pQueue, unsigned int Idx) */
+/* */
+/* */
+/* History: */
+/* 02/25/00 Hav Khauv Initial version. */
+/******************************************************************************/
+
+#ifndef BCM_QUEUE_H
+#define BCM_QUEUE_H
+#ifndef EMBEDDED
+#define EMBEDDED 1
+#endif
+
+/******************************************************************************/
+/* Queue definitions. */
+/******************************************************************************/
+
+/* Entry for queueing. */
+typedef void *PQQ_ENTRY;
+
+/* Linux Atomic Ops support */
+typedef struct { int counter; } atomic_t;
+
+
+/*
+ * This combination of `inline' and `extern' has almost the effect of a
+ * macro. The way to use it is to put a function definition in a header
+ * file with these keywords, and put another copy of the definition
+ * (lacking `inline' and `extern') in a library file. The definition in
+ * the header file will cause most calls to the function to be inlined.
+ * If any uses of the function remain, they will refer to the single copy
+ * in the library.
+ */
+extern __inline void
+atomic_set(atomic_t* entry, int val)
+{
+ entry->counter = val;
+}
+extern __inline int
+atomic_read(atomic_t* entry)
+{
+ return entry->counter;
+}
+extern __inline void
+atomic_inc(atomic_t* entry)
+{
+ if(entry)
+ entry->counter++;
+}
+
+extern __inline void
+atomic_dec(atomic_t* entry)
+{
+ if(entry)
+ entry->counter--;
+}
+
+extern __inline void
+atomic_sub(int a, atomic_t* entry)
+{
+ if(entry)
+ entry->counter -= a;
+}
+extern __inline void
+atomic_add(int a, atomic_t* entry)
+{
+ if(entry)
+ entry->counter += a;
+}
+
+
+/* Queue header -- base type. */
+typedef struct {
+ unsigned int Head;
+ unsigned int Tail;
+ unsigned int Size;
+ atomic_t EntryCnt;
+ PQQ_ENTRY Array[1];
+} QQ_CONTAINER, *PQQ_CONTAINER;
+
+
+/* Declare queue type macro. */
+#define DECLARE_QUEUE_TYPE(_QUEUE_TYPE, _QUEUE_SIZE) \
+ \
+ typedef struct { \
+ QQ_CONTAINER Container; \
+ PQQ_ENTRY EntryBuffer[_QUEUE_SIZE]; \
+ } _QUEUE_TYPE, *P##_QUEUE_TYPE
+
+
+
+/******************************************************************************/
+/* Compilation switches. */
+/******************************************************************************/
+
+#if DBG
+#undef QQ_NO_OVERFLOW_CHECK
+#undef QQ_NO_UNDERFLOW_CHECK
+#endif /* DBG */
+
+#ifdef QQ_USE_MACROS
+/* notdone */
+#else
+
+#ifdef QQ_NO_INLINE
+#define __inline
+#endif /* QQ_NO_INLINE */
+
+/******************************************************************************/
+/* Description: */
+/* */
+/* Return: */
+/******************************************************************************/
+extern __inline void
+QQ_InitQueue(
+PQQ_CONTAINER pQueue,
+unsigned int QueueSize) {
+ pQueue->Head = 0;
+ pQueue->Tail = 0;
+ pQueue->Size = QueueSize+1;
+ atomic_set(&pQueue->EntryCnt, 0);
+} /* QQ_InitQueue */
+
+
+
+/******************************************************************************/
+/* Description: */
+/* */
+/* Return: */
+/******************************************************************************/
+extern __inline char
+QQ_Full(
+PQQ_CONTAINER pQueue) {
+ unsigned int NewHead;
+
+ NewHead = (pQueue->Head + 1) % pQueue->Size;
+
+ return(NewHead == pQueue->Tail);
+} /* QQ_Full */
+
+
+
+/******************************************************************************/
+/* Description: */
+/* */
+/* Return: */
+/******************************************************************************/
+extern __inline char
+QQ_Empty(
+PQQ_CONTAINER pQueue) {
+ return(pQueue->Head == pQueue->Tail);
+} /* QQ_Empty */
+
+
+
+/******************************************************************************/
+/* Description: */
+/* */
+/* Return: */
+/******************************************************************************/
+extern __inline unsigned int
+QQ_GetSize(
+PQQ_CONTAINER pQueue) {
+ return pQueue->Size;
+} /* QQ_GetSize */
+
+
+
+/******************************************************************************/
+/* Description: */
+/* */
+/* Return: */
+/******************************************************************************/
+extern __inline unsigned int
+QQ_GetEntryCnt(
+PQQ_CONTAINER pQueue) {
+ return atomic_read(&pQueue->EntryCnt);
+} /* QQ_GetEntryCnt */
+
+
+
+/******************************************************************************/
+/* Description: */
+/* */
+/* Return: */
+/* TRUE entry was added successfully. */
+/* FALSE queue is full. */
+/******************************************************************************/
+extern __inline char
+QQ_PushHead(
+PQQ_CONTAINER pQueue,
+PQQ_ENTRY pEntry) {
+ unsigned int Head;
+
+ Head = (pQueue->Head + 1) % pQueue->Size;
+
+#if !defined(QQ_NO_OVERFLOW_CHECK)
+ if(Head == pQueue->Tail) {
+ return 0;
+ } /* if */
+#endif /* QQ_NO_OVERFLOW_CHECK */
+
+ pQueue->Array[pQueue->Head] = pEntry;
+ wmb();
+ pQueue->Head = Head;
+ atomic_inc(&pQueue->EntryCnt);
+
+ return -1;
+} /* QQ_PushHead */
+
+
+
+/******************************************************************************/
+/* Description: */
+/* */
+/* Return: */
+/* TRUE entry was added successfully. */
+/* FALSE queue is full. */
+/******************************************************************************/
+extern __inline char
+QQ_PushTail(
+PQQ_CONTAINER pQueue,
+PQQ_ENTRY pEntry) {
+ unsigned int Tail;
+
+ Tail = pQueue->Tail;
+ if(Tail == 0) {
+ Tail = pQueue->Size;
+ } /* if */
+ Tail--;
+
+#if !defined(QQ_NO_OVERFLOW_CHECK)
+ if(Tail == pQueue->Head) {
+ return 0;
+ } /* if */
+#endif /* QQ_NO_OVERFLOW_CHECK */
+
+ pQueue->Array[Tail] = pEntry;
+ wmb();
+ pQueue->Tail = Tail;
+ atomic_inc(&pQueue->EntryCnt);
+
+ return -1;
+} /* QQ_PushTail */
+
+
+
+/******************************************************************************/
+/* Description: */
+/* */
+/* Return: */
+/******************************************************************************/
+extern __inline PQQ_ENTRY
+QQ_PopHead(
+PQQ_CONTAINER pQueue) {
+ unsigned int Head;
+ PQQ_ENTRY Entry;
+
+ Head = pQueue->Head;
+
+#if !defined(QQ_NO_UNDERFLOW_CHECK)
+ if(Head == pQueue->Tail) {
+ return (PQQ_ENTRY) 0;
+ } /* if */
+#endif /* QQ_NO_UNDERFLOW_CHECK */
+
+ if(Head == 0) {
+ Head = pQueue->Size;
+ } /* if */
+ Head--;
+
+ Entry = pQueue->Array[Head];
+#ifdef EMBEDDED
+ membar();
+#else
+ mb();
+#endif
+ pQueue->Head = Head;
+ atomic_dec(&pQueue->EntryCnt);
+
+ return Entry;
+} /* QQ_PopHead */
+
+
+
+/******************************************************************************/
+/* Description: */
+/* */
+/* Return: */
+/******************************************************************************/
+extern __inline PQQ_ENTRY
+QQ_PopTail(
+PQQ_CONTAINER pQueue) {
+ unsigned int Tail;
+ PQQ_ENTRY Entry;
+
+ Tail = pQueue->Tail;
+
+#if !defined(QQ_NO_UNDERFLOW_CHECK)
+ if(Tail == pQueue->Head) {
+ return (PQQ_ENTRY) 0;
+ } /* if */
+#endif /* QQ_NO_UNDERFLOW_CHECK */
+
+ Entry = pQueue->Array[Tail];
+#ifdef EMBEDDED
+ membar();
+#else
+ mb();
+#endif
+ pQueue->Tail = (Tail + 1) % pQueue->Size;
+ atomic_dec(&pQueue->EntryCnt);
+
+ return Entry;
+} /* QQ_PopTail */
+
+
+
+/******************************************************************************/
+/* Description: */
+/* */
+/* Return: */
+/******************************************************************************/
+extern __inline PQQ_ENTRY
+QQ_GetHead(
+ PQQ_CONTAINER pQueue,
+ unsigned int Idx)
+{
+ if(Idx >= atomic_read(&pQueue->EntryCnt))
+ {
+ return (PQQ_ENTRY) 0;
+ }
+
+ if(pQueue->Head > Idx)
+ {
+ Idx = pQueue->Head - Idx;
+ }
+ else
+ {
+ Idx = pQueue->Size - (Idx - pQueue->Head);
+ }
+ Idx--;
+
+ return pQueue->Array[Idx];
+}
+
+
+
+/******************************************************************************/
+/* Description: */
+/* */
+/* Return: */
+/******************************************************************************/
+extern __inline PQQ_ENTRY
+QQ_GetTail(
+ PQQ_CONTAINER pQueue,
+ unsigned int Idx)
+{
+ if(Idx >= atomic_read(&pQueue->EntryCnt))
+ {
+ return (PQQ_ENTRY) 0;
+ }
+
+ Idx += pQueue->Tail;
+ if(Idx >= pQueue->Size)
+ {
+ Idx = Idx - pQueue->Size;
+ }
+
+ return pQueue->Array[Idx];
+}
+
+#endif /* QQ_USE_MACROS */
+
+
+
+#endif /* QUEUE_H */
--- /dev/null
+/*
+ * (C) Copyright 2002 ELTEC Elektronik AG
+ * Frank Gottschling <fgottschling@eltec.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
+ */
+
+/*
+ * cfb_console.c
+ *
+ * Color Framebuffer Console driver for 8/15/16/24/32 bits per pixel.
+ *
+ * At the moment only the 8x16 font is tested and the font fore- and
+ * background color is limited to black/white/gray colors. The Linux
+ * logo can be placed in the upper left corner and additional board
+ * information strings (that normaly goes to serial port) can be drawed.
+ *
+ * The console driver can use the standard PC keyboard interface (i8042)
+ * for character input. Character output goes to a memory mapped video
+ * framebuffer with little or big-endian organisation.
+ * With environment setting 'console=serial' the console i/o can be
+ * forced to serial port.
+
+ The driver uses graphic specific defines/parameters/functions:
+
+ (for SMI LynxE graphic chip)
+
+ CONFIG_VIDEO_SMI_LYNXEM - use graphic driver for SMI 710,712,810
+ VIDEO_FB_LITTLE_ENDIAN - framebuffer organisation default: big endian
+ VIDEO_HW_RECTFILL - graphic driver supports hardware rectangle fill
+ VIDEO_HW_BITBLT - graphic driver supports hardware bit blt
+
+ Console Parameters are set by graphic drivers global struct:
+
+ VIDEO_VISIBLE_COLS - x resolution
+ VIDEO_VISIBLE_ROWS - y resolution
+ VIDEO_PIXEL_SIZE - storage size in byte per pixel
+ VIDEO_DATA_FORMAT - graphical data format GDF
+ VIDEO_FB_ADRS - start of video memory
+
+ CONFIG_I8042_KBD - AT Keyboard driver for i8042
+ VIDEO_KBD_INIT_FCT - init function for keyboard
+ VIDEO_TSTC_FCT - keyboard_tstc function
+ VIDEO_GETC_FCT - keyboard_getc function
+
+ CONFIG_CONSOLE_CURSOR - on/off drawing cursor is done with delay
+ loop in VIDEO_TSTC_FCT (i8042)
+ CFG_CONSOLE_BLINK_COUNT - value for delay loop - blink rate
+ CONFIG_CONSOLE_TIME - display time/date in upper right corner,
+ needs CFG_CMD_DATE and CONFIG_CONSOLE_CURSOR
+ CONFIG_VIDEO_LOGO - display Linux Logo in upper left corner
+ CONFIG_CONSOLE_EXTRA_INFO - display additional board information strings
+ that normaly goes to serial port. This define
+ requires a board specific function:
+ video_drawstring (VIDEO_INFO_X,
+ VIDEO_INFO_Y + i*VIDEO_FONT_HEIGHT,
+ info);
+ that fills a info buffer at i=row.
+ s.a: board/eltec/bab7xx.
+CONFIG_VGA_AS_SINGLE_DEVICE - If set the framebuffer device will be initialised
+ as an output only device. The Keyboard driver
+ will not be set-up. This may be used, if you
+ have none or more than one Keyboard devices
+ (USB Keyboard, AT Keyboard).
+
+CONFIG_VIDEO_SW_CURSOR: - Draws a cursor after the last character. No
+ blinking is provided. Uses the macros CURSOR_SET
+ and CURSOR_OFF.
+CONFIG_VIDEO_HW_CURSOR: - Uses the hardware cursor capability of the
+ graphic chip. Uses the macro CURSOR_SET.
+ ATTENTION: If booting an OS, the display driver
+ must disable the hardware register of the graphic
+ chip. Otherwise a blinking field is displayed
+*/
+
+#include <common.h>
+
+#ifdef CONFIG_CFB_CONSOLE
+
+/*****************************************************************************/
+/* Console device defines with SMI graphic */
+/* Any other graphic must change this section */
+/*****************************************************************************/
+
+#ifdef CONFIG_VIDEO_SMI_LYNXEM
+
+#define VIDEO_FB_LITTLE_ENDIAN
+#define VIDEO_HW_RECTFILL
+#define VIDEO_HW_BITBLT
+#endif
+
+/*****************************************************************************/
+/* Defines for the CT69000 driver */
+/*****************************************************************************/
+#ifdef CONFIG_VIDEO_CT69000
+
+#define VIDEO_FB_LITTLE_ENDIAN
+#define VIDEO_HW_RECTFILL
+#define VIDEO_HW_BITBLT
+#endif
+
+/*****************************************************************************/
+/* Include video_fb.h after definitions of VIDEO_HW_RECTFILL etc */
+/*****************************************************************************/
+#include <video_fb.h>
+
+/*****************************************************************************/
+/* some Macros */
+/*****************************************************************************/
+#define VIDEO_VISIBLE_COLS (pGD->winSizeX)
+#define VIDEO_VISIBLE_ROWS (pGD->winSizeY)
+#define VIDEO_PIXEL_SIZE (pGD->gdfBytesPP)
+#define VIDEO_DATA_FORMAT (pGD->gdfIndex)
+#define VIDEO_FB_ADRS (pGD->frameAdrs)
+
+/*****************************************************************************/
+/* Console device defines with i8042 keyboard controller */
+/* Any other keyboard controller must change this section */
+/*****************************************************************************/
+
+#ifdef CONFIG_I8042_KBD
+#include <i8042.h>
+
+#define VIDEO_KBD_INIT_FCT i8042_kbd_init()
+#define VIDEO_TSTC_FCT i8042_tstc
+#define VIDEO_GETC_FCT i8042_getc
+#endif
+
+/*****************************************************************************/
+/* Console device */
+/*****************************************************************************/
+
+#include <version.h>
+#include <linux/types.h>
+#include <devices.h>
+#include <video_font.h>
+#ifdef CFG_CMD_DATE
+#include <rtc.h>
+
+#endif
+
+/*****************************************************************************/
+/* Cursor definition: */
+/* CONFIG_CONSOLE_CURSOR: Uses a timer function (see drivers/i8042.c) to */
+/* let the cursor blink. Uses the macros CURSOR_OFF */
+/* and CURSOR_ON. */
+/* CONFIG_VIDEO_SW_CURSOR: Draws a cursor after the last character. No */
+/* blinking is provided. Uses the macros CURSOR_SET */
+/* and CURSOR_OFF. */
+/* CONFIG_VIDEO_HW_CURSOR: Uses the hardware cursor capability of the */
+/* graphic chip. Uses the macro CURSOR_SET. */
+/* ATTENTION: If booting an OS, the display driver */
+/* must disable the hardware register of the graphic */
+/* chip. Otherwise a blinking field is displayed */
+/*****************************************************************************/
+#if !defined(CONFIG_CONSOLE_CURSOR) && \
+ !defined(CONFIG_VIDEO_SW_CURSOR) && \
+ !defined(CONFIG_VIDEO_HW_CURSOR)
+/* no Cursor defined */
+#define CURSOR_ON
+#define CURSOR_OFF
+#define CURSOR_SET
+#endif
+
+#ifdef CONFIG_CONSOLE_CURSOR
+#ifdef CURSOR_ON
+#error only one of CONFIG_CONSOLE_CURSOR,CONFIG_VIDEO_SW_CURSOR,CONFIG_VIDEO_HW_CURSOR can be defined
+#endif
+void console_cursor (int state);
+#define CURSOR_ON console_cursor(1);
+#define CURSOR_OFF console_cursor(0);
+#define CURSOR_SET
+#ifndef CONFIG_I8042_KBD
+#warning Cursor drawing on/off needs timer function s.a. drivers/i8042.c
+#endif
+#else
+#ifdef CONFIG_CONSOLE_TIME
+#error CONFIG_CONSOLE_CURSOR must be defined for CONFIG_CONSOLE_TIME
+#endif
+#endif /* CONFIG_CONSOLE_CURSOR */
+
+#ifdef CONFIG_VIDEO_SW_CURSOR
+#ifdef CURSOR_ON
+#error only one of CONFIG_CONSOLE_CURSOR,CONFIG_VIDEO_SW_CURSOR,CONFIG_VIDEO_HW_CURSOR can be defined
+#endif
+#define CURSOR_ON
+#define CURSOR_OFF video_putchar(console_col * VIDEO_FONT_WIDTH,\
+ console_row * VIDEO_FONT_HEIGHT, ' ');
+#define CURSOR_SET video_set_cursor();
+#endif /* CONFIG_VIDEO_SW_CURSOR */
+
+
+#ifdef CONFIG_VIDEO_HW_CURSOR
+#ifdef CURSOR_ON
+#error only one of CONFIG_CONSOLE_CURSOR,CONFIG_VIDEO_SW_CURSOR,CONFIG_VIDEO_HW_CURSOR can be defined
+#endif
+#define CURSOR_ON
+#define CURSOR_OFF
+#define CURSOR_SET video_set_hw_cursor(console_col * VIDEO_FONT_WIDTH, \
+ (console_row * VIDEO_FONT_HEIGHT) + VIDEO_LOGO_HEIGHT);
+#endif /* CONFIG_VIDEO_HW_CURSOR */
+
+#ifdef CONFIG_VIDEO_LOGO
+#define LINUX_LOGO_WIDTH 80
+#define LINUX_LOGO_HEIGHT 80
+#define LINUX_LOGO_COLORS 214
+#define LINUX_LOGO_LUT_OFFSET 0x20
+#define __initdata
+#include <linux_logo.h>
+#define VIDEO_LOGO_WIDTH LINUX_LOGO_WIDTH
+#define VIDEO_LOGO_HEIGHT LINUX_LOGO_HEIGHT
+
+#define VIDEO_INFO_X (VIDEO_LOGO_WIDTH)
+#define VIDEO_INFO_Y (VIDEO_FONT_HEIGHT/2)
+#else
+#define VIDEO_LOGO_WIDTH 0
+#define VIDEO_LOGO_HEIGHT 0
+#endif
+
+#define VIDEO_COLS VIDEO_VISIBLE_COLS
+#define VIDEO_ROWS VIDEO_VISIBLE_ROWS
+#define VIDEO_SIZE (VIDEO_ROWS*VIDEO_COLS*VIDEO_PIXEL_SIZE)
+#define VIDEO_PIX_BLOCKS (VIDEO_SIZE >> 2)
+#define VIDEO_LINE_LEN (VIDEO_COLS*VIDEO_PIXEL_SIZE)
+#define VIDEO_BURST_LEN (VIDEO_COLS/8)
+
+#ifdef CONFIG_VIDEO_LOGO
+#define CONSOLE_ROWS ((VIDEO_ROWS - VIDEO_LOGO_HEIGHT) / VIDEO_FONT_HEIGHT)
+#else
+#define CONSOLE_ROWS (VIDEO_ROWS / VIDEO_FONT_HEIGHT)
+#endif
+
+#define CONSOLE_COLS (VIDEO_COLS / VIDEO_FONT_WIDTH)
+#define CONSOLE_ROW_SIZE (VIDEO_FONT_HEIGHT * VIDEO_LINE_LEN)
+#define CONSOLE_ROW_FIRST (video_console_address)
+#define CONSOLE_ROW_SECOND (video_console_address + CONSOLE_ROW_SIZE)
+#define CONSOLE_ROW_LAST (video_console_address + CONSOLE_SIZE - CONSOLE_ROW_SIZE)
+#define CONSOLE_SIZE (CONSOLE_ROW_SIZE * CONSOLE_ROWS)
+#define CONSOLE_SCROLL_SIZE (CONSOLE_SIZE - CONSOLE_ROW_SIZE)
+
+/* Macros */
+#ifdef VIDEO_FB_LITTLE_ENDIAN
+#define SWAP16(x) ((((x) & 0x00ff) << 8) | ( (x) >> 8))
+#define SWAP32(x) ((((x) & 0x000000ff) << 24) | (((x) & 0x0000ff00) << 8)|\
+ (((x) & 0x00ff0000) >> 8) | (((x) & 0xff000000) >> 24) )
+#define SHORTSWAP32(x) ((((x) & 0x000000ff) << 8) | (((x) & 0x0000ff00) >> 8)|\
+ (((x) & 0x00ff0000) << 8) | (((x) & 0xff000000) >> 8) )
+#else
+#define SWAP16(x) (x)
+#define SWAP32(x) (x)
+#define SHORTSWAP32(x) (x)
+#endif
+
+#if defined(DEBUG) || defined(DEBUG_CFB_CONSOLE)
+#define PRINTD(x) printf(x)
+#else
+#define PRINTD(x)
+#endif
+
+
+#ifdef CONFIG_CONSOLE_EXTRA_INFO
+extern void video_get_info_str ( /* setup a board string: type, speed, etc. */
+ int line_number, /* location to place info string beside logo */
+ char *info /* buffer for info string */
+ );
+
+#endif
+
+/* Locals */
+static GraphicDevice *pGD; /* Pointer to Graphic array */
+
+static void *video_fb_address; /* frame buffer address */
+static void *video_console_address; /* console buffer start address */
+
+static int console_col = 0; /* cursor col */
+static int console_row = 0; /* cursor row */
+
+static u32 eorx, fgx, bgx; /* color pats */
+
+static const int video_font_draw_table8[] = {
+ 0x00000000, 0x000000ff, 0x0000ff00, 0x0000ffff,
+ 0x00ff0000, 0x00ff00ff, 0x00ffff00, 0x00ffffff,
+ 0xff000000, 0xff0000ff, 0xff00ff00, 0xff00ffff,
+ 0xffff0000, 0xffff00ff, 0xffffff00, 0xffffffff };
+
+static const int video_font_draw_table15[] = {
+ 0x00000000, 0x00007fff, 0x7fff0000, 0x7fff7fff };
+
+static const int video_font_draw_table16[] = {
+ 0x00000000, 0x0000ffff, 0xffff0000, 0xffffffff };
+
+static const int video_font_draw_table24[16][3] = {
+ { 0x00000000, 0x00000000, 0x00000000 },
+ { 0x00000000, 0x00000000, 0x00ffffff },
+ { 0x00000000, 0x0000ffff, 0xff000000 },
+ { 0x00000000, 0x0000ffff, 0xffffffff },
+ { 0x000000ff, 0xffff0000, 0x00000000 },
+ { 0x000000ff, 0xffff0000, 0x00ffffff },
+ { 0x000000ff, 0xffffffff, 0xff000000 },
+ { 0x000000ff, 0xffffffff, 0xffffffff },
+ { 0xffffff00, 0x00000000, 0x00000000 },
+ { 0xffffff00, 0x00000000, 0x00ffffff },
+ { 0xffffff00, 0x0000ffff, 0xff000000 },
+ { 0xffffff00, 0x0000ffff, 0xffffffff },
+ { 0xffffffff, 0xffff0000, 0x00000000 },
+ { 0xffffffff, 0xffff0000, 0x00ffffff },
+ { 0xffffffff, 0xffffffff, 0xff000000 },
+ { 0xffffffff, 0xffffffff, 0xffffffff } };
+
+static const int video_font_draw_table32[16][4] = {
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
+ { 0x00000000, 0x00000000, 0x00000000, 0x00ffffff },
+ { 0x00000000, 0x00000000, 0x00ffffff, 0x00000000 },
+ { 0x00000000, 0x00000000, 0x00ffffff, 0x00ffffff },
+ { 0x00000000, 0x00ffffff, 0x00000000, 0x00000000 },
+ { 0x00000000, 0x00ffffff, 0x00000000, 0x00ffffff },
+ { 0x00000000, 0x00ffffff, 0x00ffffff, 0x00000000 },
+ { 0x00000000, 0x00ffffff, 0x00ffffff, 0x00ffffff },
+ { 0x00ffffff, 0x00000000, 0x00000000, 0x00000000 },
+ { 0x00ffffff, 0x00000000, 0x00000000, 0x00ffffff },
+ { 0x00ffffff, 0x00000000, 0x00ffffff, 0x00000000 },
+ { 0x00ffffff, 0x00000000, 0x00ffffff, 0x00ffffff },
+ { 0x00ffffff, 0x00ffffff, 0x00000000, 0x00000000 },
+ { 0x00ffffff, 0x00ffffff, 0x00000000, 0x00ffffff },
+ { 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00000000 },
+ { 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff } };
+
+
+/******************************************************************************/
+
+
+static void video_drawchars (int xx, int yy, unsigned char *s, int count)
+{
+ u8 *cdat, *dest, *dest0;
+ int rows, offset, c;
+
+ offset = yy * VIDEO_LINE_LEN + xx * VIDEO_PIXEL_SIZE;
+ dest0 = video_fb_address + offset;
+
+ switch (VIDEO_DATA_FORMAT)
+ {
+ case GDF__8BIT_INDEX:
+ case GDF__8BIT_332RGB:
+ while (count--)
+ {
+ c = *s ;
+ cdat = video_fontdata + c * VIDEO_FONT_HEIGHT;
+ for (rows = VIDEO_FONT_HEIGHT, dest = dest0; rows--; dest += VIDEO_LINE_LEN)
+ {
+ u8 bits = *cdat++;
+ ((u32 *)dest)[0] = (video_font_draw_table8[bits >> 4] & eorx) ^ bgx;
+ ((u32 *)dest)[1] = (video_font_draw_table8[bits & 15] & eorx) ^ bgx;
+ }
+ dest0 += VIDEO_FONT_WIDTH * VIDEO_PIXEL_SIZE;
+ s++;
+ }
+ break;
+
+ case GDF_15BIT_555RGB:
+ while (count--)
+ {
+ c = *s ;
+ cdat = video_fontdata + c * VIDEO_FONT_HEIGHT;
+ for (rows = VIDEO_FONT_HEIGHT, dest = dest0; rows--; dest += VIDEO_LINE_LEN)
+ {
+ u8 bits = *cdat++;
+ ((u32 *)dest)[0] = SHORTSWAP32((video_font_draw_table15[bits >> 6] & eorx) ^ bgx);
+ ((u32 *)dest)[1] = SHORTSWAP32((video_font_draw_table15[bits >> 4 & 3] & eorx) ^ bgx);
+ ((u32 *)dest)[2] = SHORTSWAP32((video_font_draw_table15[bits >> 2 & 3] & eorx) ^ bgx);
+ ((u32 *)dest)[3] = SHORTSWAP32((video_font_draw_table15[bits & 3] & eorx) ^ bgx);
+ }
+ dest0 += VIDEO_FONT_WIDTH * VIDEO_PIXEL_SIZE;
+ s++ ;
+ }
+ break;
+
+ case GDF_16BIT_565RGB:
+ while (count--)
+ {
+ c = *s ;
+ cdat = video_fontdata + c * VIDEO_FONT_HEIGHT;
+ for (rows = VIDEO_FONT_HEIGHT, dest = dest0; rows--; dest += VIDEO_LINE_LEN)
+ {
+ u8 bits = *cdat++;
+ ((u32 *)dest)[0] = SHORTSWAP32((video_font_draw_table16[bits >> 6] & eorx) ^ bgx);
+ ((u32 *)dest)[1] = SHORTSWAP32((video_font_draw_table16[bits >> 4 & 3] & eorx) ^ bgx);
+ ((u32 *)dest)[2] = SHORTSWAP32((video_font_draw_table16[bits >> 2 & 3] & eorx) ^ bgx);
+ ((u32 *)dest)[3] = SHORTSWAP32((video_font_draw_table16[bits & 3] & eorx) ^ bgx);
+ }
+ dest0 += VIDEO_FONT_WIDTH * VIDEO_PIXEL_SIZE;
+ s++ ;
+ }
+ break;
+
+ case GDF_32BIT_X888RGB:
+ while (count--)
+ {
+ c = *s ;
+ cdat = video_fontdata + c * VIDEO_FONT_HEIGHT;
+ for (rows = VIDEO_FONT_HEIGHT, dest = dest0; rows--; dest += VIDEO_LINE_LEN)
+ {
+ u8 bits = *cdat++;
+ ((u32 *)dest)[0] = SWAP32((video_font_draw_table32[bits >> 4][0] & eorx) ^ bgx);
+ ((u32 *)dest)[1] = SWAP32((video_font_draw_table32[bits >> 4][1] & eorx) ^ bgx);
+ ((u32 *)dest)[2] = SWAP32((video_font_draw_table32[bits >> 4][2] & eorx) ^ bgx);
+ ((u32 *)dest)[3] = SWAP32((video_font_draw_table32[bits >> 4][3] & eorx) ^ bgx);
+ ((u32 *)dest)[4] = SWAP32((video_font_draw_table32[bits & 15][0] & eorx) ^ bgx);
+ ((u32 *)dest)[5] = SWAP32((video_font_draw_table32[bits & 15][1] & eorx) ^ bgx);
+ ((u32 *)dest)[6] = SWAP32((video_font_draw_table32[bits & 15][2] & eorx) ^ bgx);
+ ((u32 *)dest)[7] = SWAP32((video_font_draw_table32[bits & 15][3] & eorx) ^ bgx);
+ }
+ dest0 += VIDEO_FONT_WIDTH * VIDEO_PIXEL_SIZE;
+ s++ ;
+ }
+ break;
+
+ case GDF_24BIT_888RGB:
+ while (count--)
+ {
+ c = *s ;
+ cdat = video_fontdata + c * VIDEO_FONT_HEIGHT;
+ for (rows = VIDEO_FONT_HEIGHT, dest = dest0; rows--; dest += VIDEO_LINE_LEN)
+ {
+ u8 bits = *cdat++;
+ ((u32 *)dest)[0] = (video_font_draw_table24[bits >> 4][0] & eorx) ^ bgx;
+ ((u32 *)dest)[1] = (video_font_draw_table24[bits >> 4][1] & eorx) ^ bgx;
+ ((u32 *)dest)[2] = (video_font_draw_table24[bits >> 4][2] & eorx) ^ bgx;
+ ((u32 *)dest)[3] = (video_font_draw_table24[bits & 15][0] & eorx) ^ bgx;
+ ((u32 *)dest)[4] = (video_font_draw_table24[bits & 15][1] & eorx) ^ bgx;
+ ((u32 *)dest)[5] = (video_font_draw_table24[bits & 15][2] & eorx) ^ bgx;
+ }
+ dest0 += VIDEO_FONT_WIDTH * VIDEO_PIXEL_SIZE;
+ s++ ;
+ }
+ break;
+ }
+}
+
+/*****************************************************************************/
+
+static inline void video_drawstring(int xx, int yy, unsigned char *s)
+{
+ video_drawchars (xx, yy, s, strlen(s));
+}
+
+/*****************************************************************************/
+
+static void video_putchar(int xx, int yy, unsigned char c)
+{
+#ifdef CONFIG_VIDEO_LOGO
+ video_drawchars (xx, yy + VIDEO_LOGO_HEIGHT, &c, 1);
+#else
+ video_drawchars (xx, yy, &c, 1);
+#endif
+}
+
+/*****************************************************************************/
+#if defined(CONFIG_CONSOLE_CURSOR) || defined(CONFIG_VIDEO_SW_CURSOR)
+static void video_set_cursor(void)
+{
+ /* swap drawing colors */
+ eorx = fgx;
+ fgx = bgx;
+ bgx = eorx;
+ eorx = fgx ^ bgx;
+ /* draw cursor */
+ video_putchar (console_col * VIDEO_FONT_WIDTH,
+ console_row * VIDEO_FONT_HEIGHT, ' ');
+ /* restore drawing colors */
+ eorx = fgx;
+ fgx = bgx;
+ bgx = eorx;
+ eorx = fgx ^ bgx;
+}
+#endif
+/*****************************************************************************/
+#ifdef CONFIG_CONSOLE_CURSOR
+void console_cursor (int state)
+{
+ static int last_state = 0;
+#ifdef CONFIG_CONSOLE_TIME
+ struct rtc_time tm;
+ char info[16];
+
+ /* time update only if cursor is on (faster scroll) */
+ if (state)
+ {
+ rtc_get (&tm);
+
+ sprintf(info, " %02d:%02d:%02d ", tm.tm_hour, tm.tm_min, tm.tm_sec);
+ video_drawstring(VIDEO_VISIBLE_COLS-10*VIDEO_FONT_WIDTH,
+ VIDEO_INFO_Y, info);
+
+ sprintf(info, "%02d.%02d.%04d", tm.tm_mday, tm.tm_mon, tm.tm_year);
+ video_drawstring(VIDEO_VISIBLE_COLS-10*VIDEO_FONT_WIDTH,
+ VIDEO_INFO_Y+1*VIDEO_FONT_HEIGHT, info);
+ }
+#endif
+
+ if (state && (last_state != state))
+ {
+ video_set_cursor();
+ }
+
+ if (!state && (last_state != state))
+ {
+ /* clear cursor */
+ video_putchar (console_col * VIDEO_FONT_WIDTH,
+ console_row * VIDEO_FONT_HEIGHT, ' ');
+ }
+
+ last_state = state;
+}
+#endif
+
+/*****************************************************************************/
+
+#ifndef VIDEO_HW_RECTFILL
+static void memsetl (int *p, int c, int v)
+{
+ while (c--)
+ *(p++) = v;
+}
+#endif
+
+/*****************************************************************************/
+
+#ifndef VIDEO_HW_BITBLT
+static void memcpyl (int *d, int *s, int c)
+{
+ while (c--)
+ *(d++) = *(s++);
+}
+#endif
+
+/*****************************************************************************/
+
+static void console_scrollup (void)
+{
+ /* copy up rows ignoring the first one */
+
+#ifdef VIDEO_HW_BITBLT
+ video_hw_bitblt (
+ VIDEO_PIXEL_SIZE, /* bytes per pixel */
+ 0, /* source pos x */
+ VIDEO_LOGO_HEIGHT + VIDEO_FONT_HEIGHT, /* source pos y */
+ 0, /* dest pos x */
+ VIDEO_LOGO_HEIGHT, /* dest pos y */
+ VIDEO_VISIBLE_COLS, /* frame width */
+ VIDEO_VISIBLE_ROWS - VIDEO_LOGO_HEIGHT - VIDEO_FONT_HEIGHT /* frame height */
+ );
+#else
+ memcpyl (CONSOLE_ROW_FIRST, CONSOLE_ROW_SECOND, CONSOLE_SCROLL_SIZE >> 2);
+#endif
+
+ /* clear the last one */
+#ifdef VIDEO_HW_RECTFILL
+ video_hw_rectfill (
+ VIDEO_PIXEL_SIZE, /* bytes per pixel */
+ 0, /* dest pos x */
+ VIDEO_VISIBLE_ROWS - VIDEO_FONT_HEIGHT, /* dest pos y */
+ VIDEO_VISIBLE_COLS, /* frame width */
+ VIDEO_FONT_HEIGHT, /* frame height */
+ CONSOLE_BG_COL /* fill color */
+ );
+#else
+ memsetl (CONSOLE_ROW_LAST, CONSOLE_ROW_SIZE >> 2, CONSOLE_BG_COL);
+#endif
+}
+
+/*****************************************************************************/
+
+static void console_back (void)
+{
+ CURSOR_OFF
+ console_col--;
+
+ if (console_col < 0)
+ {
+ console_col = CONSOLE_COLS - 1;
+ console_row--;
+ if (console_row < 0)
+ console_row = 0;
+ }
+ video_putchar (console_col * VIDEO_FONT_WIDTH,
+ console_row * VIDEO_FONT_HEIGHT, ' ');
+}
+
+/*****************************************************************************/
+
+static void console_newline (void)
+{
+ CURSOR_OFF
+ console_row++;
+ console_col = 0;
+
+ /* Check if we need to scroll the terminal */
+ if (console_row >= CONSOLE_ROWS)
+ {
+ /* Scroll everything up */
+ console_scrollup ();
+
+ /* Decrement row number */
+ console_row--;
+ }
+}
+
+/*****************************************************************************/
+
+void video_putc (const char c)
+{
+ switch (c)
+ {
+ case 13: /* ignore */
+ break;
+
+ case '\n': /* next line */
+ console_newline();
+ break;
+
+ case 9: /* tab 8 */
+ CURSOR_OFF
+ console_col |= 0x0008;
+ console_col &= ~0x0007;
+
+ if (console_col >= CONSOLE_COLS)
+ console_newline();
+ break;
+
+ case 8: /* backspace */
+ console_back();
+ break;
+
+ default: /* draw the char */
+ video_putchar (console_col * VIDEO_FONT_WIDTH,
+ console_row * VIDEO_FONT_HEIGHT, c);
+ console_col++ ;
+
+ /* check for newline */
+ if (console_col >= CONSOLE_COLS)
+ console_newline();
+ }
+ CURSOR_SET
+}
+
+
+
+/*****************************************************************************/
+
+void video_puts (const char *s)
+{
+ int count = strlen(s);
+
+ while(count--)
+ video_putc(*s++);
+}
+
+/*****************************************************************************/
+
+#ifdef CONFIG_VIDEO_LOGO
+void logo_plot (void *screen, int width, int x, int y)
+{
+ int skip = (width - LINUX_LOGO_WIDTH) * VIDEO_PIXEL_SIZE,
+ xcount, i,
+ ycount = LINUX_LOGO_HEIGHT;
+ unsigned char
+ *source = linux_logo,
+ *dest = (unsigned char *) screen + ((y * width * VIDEO_PIXEL_SIZE) + x),
+ r, g, b;
+
+ if (VIDEO_DATA_FORMAT == GDF__8BIT_INDEX)
+ {
+ for (i = 0; i < LINUX_LOGO_COLORS; i++)
+ {
+ r = (unsigned char)linux_logo_red [i];
+ g = (unsigned char)linux_logo_green[i];
+ b = (unsigned char)linux_logo_blue [i];
+ video_set_lut (LINUX_LOGO_LUT_OFFSET + i, r, g, b);
+ }
+ }
+
+ while (ycount--)
+ {
+ xcount = LINUX_LOGO_WIDTH;
+ while (xcount--)
+ {
+ r = (unsigned char)linux_logo_red [*source - LINUX_LOGO_LUT_OFFSET];
+ g = (unsigned char)linux_logo_green[*source - LINUX_LOGO_LUT_OFFSET];
+ b = (unsigned char)linux_logo_blue [*source - LINUX_LOGO_LUT_OFFSET];
+
+ switch (VIDEO_DATA_FORMAT)
+ {
+ case GDF__8BIT_INDEX:
+ *dest = *source;
+ break;
+ case GDF__8BIT_332RGB:
+ *dest = ((r>>5)<<5) | ((g>>5)<<2) | (b>>6);
+ break;
+ case GDF_15BIT_555RGB:
+ *(unsigned short *)dest =
+ SWAP16((unsigned short)(((r>>3)<<10) | ((g>>3)<<5) | (b>>3)));
+ break;
+ case GDF_16BIT_565RGB:
+ *(unsigned short *)dest =
+ SWAP16((unsigned short)(((r>>3)<<11) | ((g>>2)<<5) | (b>>3)));
+ break;
+ case GDF_32BIT_X888RGB:
+ *(unsigned long *)dest =
+ SWAP32((unsigned long)((r<<16) | (g<<8) | b));
+ break;
+ case GDF_24BIT_888RGB:
+#ifdef VIDEO_FB_LITTLE_ENDIAN
+ dest[0] = b;
+ dest[1] = g;
+ dest[2] = r;
+#else
+ dest[0] = r;
+ dest[1] = g;
+ dest[2] = b;
+#endif
+ break;
+ }
+ source++;
+ dest += VIDEO_PIXEL_SIZE;
+ }
+ dest += skip;
+ }
+}
+
+
+/*****************************************************************************/
+
+static void *video_logo (void)
+{
+ char info[128];
+
+ logo_plot (video_fb_address, VIDEO_COLS, 0, 0);
+
+ sprintf(info, " %s (%s - %s)", U_BOOT_VERSION, __DATE__, __TIME__);
+ video_drawstring (VIDEO_INFO_X, VIDEO_INFO_Y, info);
+
+#ifdef CONFIG_CONSOLE_EXTRA_INFO
+ {
+ int i, n = ((VIDEO_LOGO_HEIGHT-VIDEO_FONT_HEIGHT)/VIDEO_FONT_HEIGHT);
+
+ for (i = 1; i < n; i++)
+ {
+ video_get_info_str (i, info);
+ if (*info)
+ video_drawstring (VIDEO_INFO_X,
+ VIDEO_INFO_Y + i*VIDEO_FONT_HEIGHT, info);
+ }
+ }
+#endif
+
+ return (video_fb_address + VIDEO_LOGO_HEIGHT * VIDEO_LINE_LEN);
+}
+#endif
+
+
+/*****************************************************************************/
+
+static int video_init(void)
+{
+ unsigned char color8;
+
+ if ((pGD=video_hw_init()) == NULL)
+ return -1;
+
+ video_fb_address = (void*)VIDEO_FB_ADRS;
+#ifdef CONFIG_VIDEO_HW_CURSOR
+ video_init_hw_cursor(VIDEO_FONT_WIDTH, VIDEO_FONT_HEIGHT);
+#endif
+
+ /* Init drawing pats */
+ switch (VIDEO_DATA_FORMAT)
+ {
+ case GDF__8BIT_INDEX:
+ video_set_lut (0x01, CONSOLE_FG_COL, CONSOLE_FG_COL, CONSOLE_FG_COL);
+ video_set_lut (0x00, CONSOLE_BG_COL, CONSOLE_BG_COL, CONSOLE_BG_COL);
+ fgx = 0x01010101;
+ bgx = 0x00000000;
+ break;
+ case GDF__8BIT_332RGB:
+ color8 = ((CONSOLE_FG_COL & 0xe0) | ((CONSOLE_FG_COL>>3) & 0x1c) | CONSOLE_FG_COL>>6);
+ fgx = (color8<<24) | (color8<<16) | (color8<<8) | color8;
+ color8 = ((CONSOLE_BG_COL & 0xe0) | ((CONSOLE_BG_COL>>3) & 0x1c) | CONSOLE_BG_COL>>6);
+ bgx = (color8<<24) | (color8<<16) | (color8<<8) | color8;
+ break;
+ case GDF_15BIT_555RGB:
+ fgx = (((CONSOLE_FG_COL>>3)<<26) | ((CONSOLE_FG_COL>>3)<<21) | ((CONSOLE_FG_COL>>3)<<16) |
+ ((CONSOLE_FG_COL>>3)<<10) | ((CONSOLE_FG_COL>>3)<<5) | (CONSOLE_FG_COL>>3));
+ bgx = (((CONSOLE_BG_COL>>3)<<26) | ((CONSOLE_BG_COL>>3)<<21) | ((CONSOLE_BG_COL>>3)<<16) |
+ ((CONSOLE_BG_COL>>3)<<10) | ((CONSOLE_BG_COL>>3)<<5) | (CONSOLE_BG_COL>>3));
+ break;
+ case GDF_16BIT_565RGB:
+ fgx = (((CONSOLE_FG_COL>>3)<<27) | ((CONSOLE_FG_COL>>2)<<21) | ((CONSOLE_FG_COL>>3)<<16) |
+ ((CONSOLE_FG_COL>>3)<<11) | ((CONSOLE_FG_COL>>2)<<5) | (CONSOLE_FG_COL>>3));
+ bgx = (((CONSOLE_BG_COL>>3)<<27) | ((CONSOLE_BG_COL>>2)<<21) | ((CONSOLE_BG_COL>>3)<<16) |
+ ((CONSOLE_BG_COL>>3)<<11) | ((CONSOLE_BG_COL>>2)<<5) | (CONSOLE_BG_COL>>3));
+ break;
+ case GDF_32BIT_X888RGB:
+ fgx = (CONSOLE_FG_COL<<16) | (CONSOLE_FG_COL<<8) | CONSOLE_FG_COL;
+ bgx = (CONSOLE_BG_COL<<16) | (CONSOLE_BG_COL<<8) | CONSOLE_BG_COL;
+ break;
+ case GDF_24BIT_888RGB:
+ fgx = (CONSOLE_FG_COL<<24) | (CONSOLE_FG_COL<<16) | (CONSOLE_FG_COL<<8) | CONSOLE_FG_COL;
+ bgx = (CONSOLE_BG_COL<<24) | (CONSOLE_BG_COL<<16) | (CONSOLE_BG_COL<<8) | CONSOLE_BG_COL;
+ break;
+ }
+ eorx = fgx ^ bgx;
+
+#ifdef CONFIG_VIDEO_LOGO
+ /* Plot the logo and get start point of console */
+ PRINTD("Video: Drawing the logo ...\n");
+ video_console_address = video_logo();
+#else
+ video_console_address = video_fb_address;
+#endif
+
+ /* Initialize the console */
+ console_col = 0;
+ console_row = 0;
+
+ return 0 ;
+}
+
+
+/*****************************************************************************/
+
+int drv_video_init (void)
+{
+ int skip_dev_init;
+ device_t console_dev;
+ char *penv;
+
+ skip_dev_init = 0;
+
+ /* Force console i/o to serial ? */
+ if ((penv = getenv ("console")) != NULL)
+ if (strcmp (penv, "serial") == 0)
+ return 0;
+
+ /* Init video chip - returns with framebuffer cleared */
+ if (video_init() == -1)
+ skip_dev_init = 1;
+#ifdef CONFIG_VGA_AS_SINGLE_DEVICE
+ /* Devices VGA and Keyboard will be assigned seperately */
+ /* Init vga device */
+ if (!skip_dev_init)
+ {
+ memset (&console_dev, 0, sizeof(console_dev));
+ strcpy(console_dev.name, "vga");
+ console_dev.ext = DEV_EXT_VIDEO; /* Video extensions */
+ console_dev.flags = DEV_FLAGS_OUTPUT | DEV_FLAGS_SYSTEM;
+ console_dev.putc = video_putc; /* 'putc' function */
+ console_dev.puts = video_puts; /* 'puts' function */
+ console_dev.tstc = NULL; /* 'tstc' function */
+ console_dev.getc = NULL; /* 'getc' function */
+
+ if (device_register (&console_dev) == 0)
+ return 1;
+ }
+#else
+ PRINTD("KBD: Keyboard init ...\n");
+ if (VIDEO_KBD_INIT_FCT == -1)
+ skip_dev_init = 1;
+
+ /* Init console device */
+ if (!skip_dev_init)
+ {
+ memset (&console_dev, 0, sizeof(console_dev));
+ strcpy(console_dev.name, "console");
+ console_dev.ext = DEV_EXT_VIDEO; /* Video extensions */
+ console_dev.flags = DEV_FLAGS_OUTPUT | DEV_FLAGS_INPUT | DEV_FLAGS_SYSTEM;
+ console_dev.putc = video_putc; /* 'putc' function */
+ console_dev.puts = video_puts; /* 'puts' function */
+ console_dev.tstc = VIDEO_TSTC_FCT; /* 'tstc' function */
+ console_dev.getc = VIDEO_GETC_FCT; /* 'getc' function */
+
+ if (device_register (&console_dev) == 0)
+ return 1;
+ }
+#endif /* CONFIG_VGA_AS_SINGLE_DEVICE */
+ /* No console dev available */
+ return 0;
+}
+
+#endif /* CONFIG_CFB_CONSOLE */
+
+
+
+
+
+
+
--- /dev/null
+/*
+ * Cirrus Logic CS8900A Ethernet
+ *
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Marius Groeger <mgroeger@sysgo.de>
+ *
+ * Copyright (C) 1999 Ben Williamson <benw@pobox.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is loaded into SRAM in bootstrap mode, where it waits
+ * for commands on UART1 to read and write memory, jump to code etc.
+ * A design goal for this program is to be entirely independent of the
+ * target board. Anything with a CL-PS7111 or EP7211 should be able to run
+ * this code in bootstrap mode. All the board specifics can be handled on
+ * the host.
+ *
+ * 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.
+ */
+
+#include <common.h>
+#include <command.h>
+#include "cs8900.h"
+#include <net.h>
+
+#ifdef CONFIG_DRIVER_CS8900
+
+#if (CONFIG_COMMANDS & CFG_CMD_NET)
+
+
+/* packet page register access functions */
+
+#ifdef CS8900_BUS32
+/* we don't need 16 bit initialisation on 32 bit bus */
+#define get_reg_init_bus(x) get_reg((x))
+#else
+static unsigned short get_reg_init_bus(int regno)
+{
+ /* force 16 bit busmode */
+ volatile unsigned char c;
+ c = CS8900_BUS16_0;
+ c = CS8900_BUS16_1;
+ c = CS8900_BUS16_0;
+ c = CS8900_BUS16_1;
+ c = CS8900_BUS16_0;
+
+ CS8900_PPTR = regno;
+ return (unsigned short) CS8900_PDATA;
+}
+#endif
+
+static unsigned short
+get_reg(int regno)
+{
+ CS8900_PPTR = regno;
+ return (unsigned short) CS8900_PDATA;
+}
+
+
+static void put_reg(int regno, unsigned short val)
+{
+ CS8900_PPTR = regno;
+ CS8900_PDATA = val;
+}
+
+static void eth_reset(void)
+{
+ int tmo;
+ unsigned short us;
+
+ /* reset NIC */
+ put_reg(PP_SelfCTL, get_reg(PP_SelfCTL) | PP_SelfCTL_Reset );
+
+ /* wait for 200ms */
+ udelay(200000);
+ /* Wait until the chip is reset */
+
+ tmo = get_timer(0) + 1 * CFG_HZ;
+ while ((((us = get_reg_init_bus(PP_SelfSTAT)) & PP_SelfSTAT_InitD) == 0)
+ && tmo < get_timer(0))
+ /*NOP*/;
+}
+
+void cs8900_get_enetaddr (uchar *addr)
+{
+ int i;
+ /* verify chip id */
+ if (get_reg_init_bus(PP_ChipID) != 0x630e)
+ return;
+ eth_reset();
+ if ((get_reg(PP_SelfST) & (PP_SelfSTAT_EEPROM | PP_SelfSTAT_EEPROM_OK)) ==
+ (PP_SelfSTAT_EEPROM|PP_SelfSTAT_EEPROM_OK)) {
+ /* Load the MAC from EEPROM */
+ for (i=0; i<6/2; i++) {
+ unsigned int Addr;
+ Addr = get_reg(PP_IA+i*2);
+ addr[i*2] = Addr & 0xFF;
+ addr[i*2+1] = Addr >> 8;
+ }
+ }
+}
+
+void eth_halt( void )
+{
+ /* disable transmitter/receiver mode */
+ put_reg(PP_LineCTL, 0);
+
+ /* "shutdown" to show ChipID or kernel wouldn't find he cs8900 ... */
+ get_reg_init_bus(PP_ChipID);
+}
+
+int eth_init( bd_t *bd )
+{
+
+ /* verify chip id */
+ if (get_reg_init_bus(PP_ChipID) != 0x630e)
+ {
+ printf( "CS8900 Ethernet chip not found?!\n" );
+ return 0;
+ }
+
+ eth_reset();
+ /* set the ethernet address */
+ put_reg(PP_IA + 0, bd->bi_enetaddr[0] | (bd->bi_enetaddr[1] << 8));
+ put_reg(PP_IA + 2, bd->bi_enetaddr[2] | (bd->bi_enetaddr[3] << 8));
+ put_reg(PP_IA + 4, bd->bi_enetaddr[4] | (bd->bi_enetaddr[5] << 8));
+
+ /* receive only error free packets addressed to this card */
+ put_reg(PP_RxCTL, PP_RxCTL_IA | PP_RxCTL_Broadcast | PP_RxCTL_RxOK);
+
+ /* do not generate any interrupts on receive operations */
+ put_reg(PP_RxCFG, 0);
+
+ /* do not generate any interrupts on transmit operations */
+ put_reg(PP_TxCFG, 0);
+
+ /* do not generate any interrupts on buffer operations */
+ put_reg(PP_BufCFG, 0);
+
+ /* enable transmitter/receiver mode */
+ put_reg(PP_LineCTL, PP_LineCTL_Rx | PP_LineCTL_Tx);
+
+ return 0;
+}
+
+/* Get a data block via Ethernet */
+extern int eth_rx(void)
+{
+ int i;
+ unsigned short rxlen;
+ unsigned short *addr;
+ unsigned short status;
+
+ status = get_reg(PP_RER);
+
+ if ((status & PP_RER_RxOK) == 0)
+ return 0;
+
+ status = CS8900_RTDATA; /* stat */
+ rxlen = CS8900_RTDATA; /* len */
+
+ if(rxlen > PKTSIZE_ALIGN + PKTALIGN)
+ printf("packet too big!\n");
+
+ for(addr = (unsigned short *)NetRxPackets[0], i = rxlen >> 1; i > 0; i-- )
+ *addr++ = CS8900_RTDATA;
+ if(rxlen & 1)
+ *addr++ = CS8900_RTDATA;
+
+ /* Pass the packet up to the protocol layers. */
+ NetReceive(NetRxPackets[0], rxlen);
+
+ return rxlen;
+}
+
+/* Send a data block via Ethernet. */
+extern int eth_send(volatile void *packet, int length)
+{
+ volatile unsigned short *addr;
+ int tmo;
+ unsigned short s;
+
+retry:
+ /* initiate a transmit sequence */
+ CS8900_TxCMD = PP_TxCmd_TxStart_Full;
+ CS8900_TxLEN = length;
+
+ /* Test to see if the chip has allocated memory for the packet */
+ if ((get_reg(PP_BusSTAT) & PP_BusSTAT_TxRDY) == 0) {
+ /* Oops... this should not happen! */
+ printf("cs: unable to send packet; retrying...\n");
+ for (tmo = get_timer(0) + 5 * CFG_HZ; get_timer(0) < tmo; )
+ /*NOP*/;
+ eth_reset();
+ goto retry;
+ }
+
+ /* Write the contents of the packet */
+ /* assume even number of bytes */
+ for(addr = packet; length > 0; length -= 2 )
+ CS8900_RTDATA = *addr++;
+
+ /* wait for transfer to succeed */
+ tmo = get_timer(0) + 5 * CFG_HZ;
+ while((s = get_reg(PP_TER) & ~0x1F) == 0)
+ {
+ if (get_timer(0) >= tmo)
+ break;
+ }
+
+ /* nothing */ ;
+ if ((s & (PP_TER_CRS | PP_TER_TxOK)) != PP_TER_TxOK) {
+ printf("\ntransmission error %#x\n", s);
+ }
+
+ return 0;
+}
+
+#endif /* COMMANDS & CFG_NET */
+
+#endif /* CONFIG_DRIVER_CS8900 */
--- /dev/null
+/*
+ * (C) Copyright 2002
+ * Denis Peter, MPL AG Switzerland
+ *
+ * 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
+ */
+
+/*
+ * ported from ctfb.c (linux kernel) for the U-Boot
+ *
+ */
+
+/************************************************************************
+ Get Parameters for the video mode:
+ Parameters can be set via the variable "videomode" in the environment.
+ 2 diferent ways are possible:
+ "videomode=301" - 301 is a hexadecimal number describing the VESA
+ mode. Following modes are implemented:
+
+ Colors 640x480 800x600 1024x768 1152x864
+ --------+-----------------------------------
+ 8 bits | 0x301 0x303 0x305 0x161
+ 15 bits | 0x310 0x313 0x316 0x162
+ 16 bits | 0x311 0x314 0x317 0x163
+ 24 bits | 0x312 0x315 0x318 ?
+ --------+-----------------------------------
+ "videomode=bootargs"
+ - the parameters are parsed from the bootargs.
+ The format is "NAME:VALUE,NAME:VALUE" etc.
+ Ex.:
+ "bootargs=video=ctfb:x:800,y:600,depth:16,pclk:25000"
+ Parameters not included in the list will be taken from
+ the default mode, which is one of the following:
+ mode:0 640x480x24
+ mode:1 800x600x16
+ mode:2 1024x768x8
+ mode:3 960x720x24
+ mode:4 1152x864x16
+ if "mode" is not provided within the parameter list,
+ mode:0 is assumed.
+ Following parameters are supported:
+ x xres = visible resolution horizontal
+ y yres = visible resolution vertical
+ pclk pixelclocks in pico sec
+ le left_marging time from sync to picture in pixelclocks
+ ri right_marging time from picture to sync in pixelclocks
+ up upper_margin time from sync to picture
+ lo lower_margin
+ hs hsync_len length of horizontal sync
+ vs vsync_len length of vertical sync
+ sync see FB_SYNC_*
+ vmode see FB_VMODE_*
+ depth Color depth in bits per pixel
+ All other parameters in the variable bootargs are ignored.
+ It is also possible to set the parameters direct in the
+ variable "videomode", or in another variable i.e.
+ "myvideo" and setting the variable "videomode=myvideo"..
+****************************************************************************/
+
+#include <common.h>
+
+#ifdef CONFIG_VIDEO
+
+#include <pci.h>
+#include <video_fb.h>
+
+#ifdef CONFIG_VIDEO_CT69000
+
+/* debug */
+#undef VGA_DEBUG
+#undef VGA_DUMP_REG
+#ifdef VGA_DEBUG
+#define PRINTF(fmt,args...) printf (fmt ,##args)
+#else
+#define PRINTF(fmt,args...)
+#endif
+
+/* Macros */
+#ifndef min
+#define min( a, b ) ( ( a ) < ( b ) ) ? ( a ) : ( b )
+#endif
+#ifndef max
+#define max( a, b ) ( ( a ) > ( b ) ) ? ( a ) : ( b )
+#endif
+#ifdef minmax
+#error "term minmax already used."
+#endif
+#define minmax( a, x, b ) max( ( a ), min( ( x ), ( b ) ) )
+#define N_ELTS( x ) ( sizeof( x ) / sizeof( x[ 0 ] ) )
+
+/* CT Register Offsets */
+#define CT_AR_O 0x3c0 /* Index and Data write port of the attribute Registers */
+#define CT_GR_O 0x3ce /* Index port of the Graphic Controller Registers */
+#define CT_SR_O 0x3c4 /* Index port of the Sequencer Controller */
+#define CT_CR_O 0x3d4 /* Index port of the CRT Controller */
+#define CT_XR_O 0x3d6 /* Extended Register index */
+#define CT_MSR_W_O 0x3c2 /* Misc. Output Register (write only) */
+#define CT_LUT_MASK_O 0x3c6 /* Color Palette Mask */
+#define CT_LUT_START_O 0x3c8 /* Color Palette Write Mode Index */
+#define CT_LUT_RGB_O 0x3c9 /* Color Palette Data Port */
+#define CT_STATUS_REG0_O 0x3c2 /* Status Register 0 (read only) */
+#define CT_STATUS_REG1_O 0x3da /* Input Status Register 1 (read only) */
+
+#define CT_FP_O 0x3d0 /* Index port of the Flat panel Registers */
+#define CT_MR_O 0x3d2 /* Index Port of the Multimedia Extension */
+
+/* defines for the memory mapped registers */
+#define BR00_o 0x400000 /* Source and Destination Span Register */
+#define BR01_o 0x400004 /* Pattern/Source Expansion Background Color & Transparency Key Register */
+#define BR02_o 0x400008 /* Pattern/Source Expansion Foreground Color Register */
+#define BR03_o 0x40000C /* Monochrome Source Control Register */
+#define BR04_o 0x400010 /* BitBLT Control Register */
+#define BR05_o 0x400014 /* Pattern Address Registe */
+#define BR06_o 0x400018 /* Source Address Register */
+#define BR07_o 0x40001C /* Destination Address Register */
+#define BR08_o 0x400020 /* Destination Width & Height Register */
+#define BR09_o 0x400024 /* Source Expansion Background Color & Transparency Key Register */
+#define BR0A_o 0x400028 /* Source Expansion Foreground Color Register */
+
+#define CURSOR_SIZE 0x1000 /* in KByte for HW Cursor */
+#define PATTERN_ADR (pGD->dprBase + CURSOR_SIZE) /* pattern Memory after Cursor Memory */
+#define PATTERN_SIZE 8*8*4 /* 4 Bytes per Pixel 8 x 8 Pixel */
+#define ACCELMEMORY (CURSOR_SIZE + PATTERN_SIZE) /* reserved Memory for BITBlt and hw cursor */
+
+/* Some Mode definitions */
+#define FB_SYNC_HOR_HIGH_ACT 1 /* horizontal sync high active */
+#define FB_SYNC_VERT_HIGH_ACT 2 /* vertical sync high active */
+#define FB_SYNC_EXT 4 /* external sync */
+#define FB_SYNC_COMP_HIGH_ACT 8 /* composite sync high active */
+#define FB_SYNC_BROADCAST 16 /* broadcast video timings */
+ /* vtotal = 144d/288n/576i => PAL */
+ /* vtotal = 121d/242n/484i => NTSC */
+#define FB_SYNC_ON_GREEN 32 /* sync on green */
+
+#define FB_VMODE_NONINTERLACED 0 /* non interlaced */
+#define FB_VMODE_INTERLACED 1 /* interlaced */
+#define FB_VMODE_DOUBLE 2 /* double scan */
+#define FB_VMODE_MASK 255
+
+#define FB_VMODE_YWRAP 256 /* ywrap instead of panning */
+#define FB_VMODE_SMOOTH_XPAN 512 /* smooth xpan possible (internally used) */
+#define FB_VMODE_CONUPDATE 512 /* don't update x/yoffset */
+
+#define text 0
+#define fntwidth 8
+
+/* table for VGA Initialization */
+typedef struct {
+ const unsigned char reg;
+ const unsigned char val;
+} CT_CFG_TABLE;
+
+/* this table provides some basic initialisations such as Memory Clock etc */
+static CT_CFG_TABLE xreg[] = {
+ {0x09, 0x01}, /* CRT Controller Extensions Enable */
+ {0x0A, 0x02}, /* Frame Buffer Mapping */
+ {0x0B, 0x01}, /* PCI Write Burst support */
+ {0x20, 0x00}, /* BitBLT Configuration */
+ {0x40, 0x03}, /* Memory Access Control */
+ {0x60, 0x00}, /* Video Pin Control */
+ {0x61, 0x00}, /* DPMS Synch control */
+ {0x62, 0x00}, /* GPIO Pin Control */
+ {0x63, 0xBD}, /* GPIO Pin Data */
+ {0x67, 0x00}, /* Pin Tri-State */
+ {0x80, 0x80}, /* Pixel Pipeline Config 0 register */
+ {0xA0, 0x00}, /* Cursor 1 Control Reg */
+ {0xA1, 0x00}, /* Cursor 1 Vertical Extension Reg */
+ {0xA2, 0x00}, /* Cursor 1 Base Address Low */
+ {0xA3, 0x00}, /* Cursor 1 Base Address High */
+ {0xA4, 0x00}, /* Cursor 1 X-Position Low */
+ {0xA5, 0x00}, /* Cursor 1 X-Position High */
+ {0xA6, 0x00}, /* Cursor 1 Y-Position Low */
+ {0xA7, 0x00}, /* Cursor 1 Y-Position High */
+ {0xA8, 0x00}, /* Cursor 2 Control Reg */
+ {0xA9, 0x00}, /* Cursor 2 Vertical Extension Reg */
+ {0xAA, 0x00}, /* Cursor 2 Base Address Low */
+ {0xAB, 0x00}, /* Cursor 2 Base Address High */
+ {0xAC, 0x00}, /* Cursor 2 X-Position Low */
+ {0xAD, 0x00}, /* Cursor 2 X-Position High */
+ {0xAE, 0x00}, /* Cursor 2 Y-Position Low */
+ {0xAF, 0x00}, /* Cursor 2 Y-Position High */
+ {0xC0, 0x7D}, /* Dot Clock 0 VCO M-Divisor */
+ {0xC1, 0x07}, /* Dot Clock 0 VCO N-Divisor */
+ {0xC3, 0x34}, /* Dot Clock 0 Divisor select */
+ {0xC4, 0x55}, /* Dot Clock 1 VCO M-Divisor */
+ {0xC5, 0x09}, /* Dot Clock 1 VCO N-Divisor */
+ {0xC7, 0x24}, /* Dot Clock 1 Divisor select */
+ {0xC8, 0x7D}, /* Dot Clock 2 VCO M-Divisor */
+ {0xC9, 0x07}, /* Dot Clock 2 VCO N-Divisor */
+ {0xCB, 0x34}, /* Dot Clock 2 Divisor select */
+ {0xCC, 0x38}, /* Memory Clock 0 VCO M-Divisor */
+ {0xCD, 0x03}, /* Memory Clock 0 VCO N-Divisor */
+ {0xCE, 0x90}, /* Memory Clock 0 Divisor select */
+ {0xCF, 0x06}, /* Clock Config */
+ {0xD0, 0x0F}, /* Power Down */
+ {0xD1, 0x01}, /* Power Down BitBLT */
+ {0xFF, 0xFF} /* end of table */
+};
+/* Clock Config:
+ * =============
+ *
+ * PD Registers:
+ * -------------
+ * Bit2 and Bit4..6 are used for the Loop Divisor and Post Divisor.
+ * They are encoded as follows:
+ *
+ * +---+--------------+
+ * | 2 | Loop Divisor |
+ * +---+--------------+
+ * | 1 | 1 |
+ * +---+--------------+
+ * | 0 | 4 |
+ * +---+--------------+
+ * Note: The Memory Clock does not have a Loop Divisor.
+ * +---+---+---+--------------+
+ * | 6 | 5 | 4 | Post Divisor |
+ * +---+---+---+--------------+
+ * | 0 | 0 | 0 | 1 |
+ * +---+---+---+--------------+
+ * | 0 | 0 | 1 | 2 |
+ * +---+---+---+--------------+
+ * | 0 | 1 | 0 | 4 |
+ * +---+---+---+--------------+
+ * | 0 | 1 | 1 | 8 |
+ * +---+---+---+--------------+
+ * | 1 | 0 | 0 | 16 |
+ * +---+---+---+--------------+
+ * | 1 | 0 | 1 | 32 |
+ * +---+---+---+--------------+
+ * | 1 | 1 | X | reserved |
+ * +---+---+---+--------------+
+ *
+ * All other bits are reserved in these registers.
+ *
+ * Clock VCO M Registers:
+ * ----------------------
+ * These Registers contain the M Value -2.
+ *
+ * Clock VCO N Registers:
+ * ----------------------
+ * These Registers contain the N Value -2.
+ *
+ * Formulas:
+ * ---------
+ * Fvco = (Fref * Loop Divisor * M/N), whereas 100MHz < Fvco < 220MHz
+ * Fout = Fvco / Post Divisor
+ *
+ * Dot Clk0 (default 25MHz):
+ * -------------------------
+ * Fvco = 14.318 * 127 / 9 = 202.045MHz
+ * Fout = 202.045MHz / 8 = 25.25MHz
+ * Post Divisor = 8
+ * Loop Divisor = 1
+ * XRC0 = (M - 2) = 125 = 0x7D
+ * XRC1 = (N - 2) = 7 = 0x07
+ * XRC3 = 0x34
+ *
+ * Dot Clk1 (default 28MHz):
+ * -------------------------
+ * Fvco = 14.318 * 87 / 11 = 113.24MHz
+ * Fout = 113.24MHz / 4 = 28.31MHz
+ * Post Divisor = 4
+ * Loop Divisor = 1
+ * XRC4 = (M - 2) = 85 = 0x55
+ * XRC5 = (N - 2) = 9 = 0x09
+ * XRC7 = 0x24
+ *
+ * Dot Clk2 (variable for extended modes set to 25MHz):
+ * ----------------------------------------------------
+ * Fvco = 14.318 * 127 / 9 = 202.045MHz
+ * Fout = 202.045MHz / 8 = 25.25MHz
+ * Post Divisor = 8
+ * Loop Divisor = 1
+ * XRC8 = (M - 2) = 125 = 0x7D
+ * XRC9 = (N - 2) = 7 = 0x07
+ * XRCB = 0x34
+ *
+ * Memory Clk for most modes >50MHz:
+ * ----------------------------------
+ * Fvco = 14.318 * 58 / 5 = 166MHz
+ * Fout = 166MHz / 2 = 83MHz
+ * Post Divisor = 2
+ * XRCC = (M - 2) = 57 = 0x38
+ * XRCD = (N - 2) = 3 = 0x03
+ * XRCE = 0x90
+ *
+ * Note Bit7 enables the clock source from the VCO
+ *
+ */
+
+/******************************************************************
+ * Resolution Struct
+ ******************************************************************/
+struct ctfb_res_modes {
+ int xres; /* visible resolution */
+ int yres;
+ /* Timing: All values in pixclocks, except pixclock (of course) */
+ int pixclock; /* pixel clock in ps (pico seconds) */
+ int left_margin; /* time from sync to picture */
+ int right_margin; /* time from picture to sync */
+ int upper_margin; /* time from sync to picture */
+ int lower_margin;
+ int hsync_len; /* length of horizontal sync */
+ int vsync_len; /* length of vertical sync */
+ int sync; /* see FB_SYNC_* */
+ int vmode; /* see FB_VMODE_* */
+};
+
+/******************************************************************
+ * Vesa Mode Struct
+ ******************************************************************/
+struct ctfb_vesa_modes {
+ int vesanr; /* Vesa number as in LILO (VESA Nr + 0x200} */
+ int resindex; /* index to resolution struct */
+ int bits_per_pixel; /* bpp */
+};
+/*******************************************************************
+ * Chips struct
+ *******************************************************************/
+struct ctfb_chips_properties {
+ int device_id; /* PCI Device ID */
+ unsigned long max_mem; /* memory for frame buffer */
+ int vld_set; /* value of VLD if bit2 in clock control is set */
+ int vld_not_set; /* value of VLD if bit2 in clock control is set */
+ int mn_diff; /* difference between M/N Value + mn_diff = M/N Register */
+ int mn_min; /* min value of M/N Value */
+ int mn_max; /* max value of M/N Value */
+ int vco_min; /* VCO Min in MHz */
+ int vco_max; /* VCO Max in MHz */
+};
+
+static const struct ctfb_chips_properties chips[] = {
+ {PCI_DEVICE_ID_CT_69000, 0x200000, 1, 4, -2, 3, 257, 100, 220},
+ {PCI_DEVICE_ID_CT_65555, 0x100000, 16, 4, 0, 1, 255, 48, 220}, /* NOT TESTED */
+ {0, 0, 0, 0, 0, 0, 0, 0, 0} /* Terminator */
+};
+
+/*************************************************
+ Video Modes:
+Colours 640x400 640x480 800x600 1024x768 1152x864 1280x1024 1600x1200
+--------+--------------------------------------------------------------
+ 4 bits | ? ? 0x302 ? ? ? ?
+ 8 bits | 0x300 0x301 0x303 0x305 0x161 0x307 0x31C
+15 bits | ? 0x310 0x313 0x316 0x162 0x319 0x31D
+16 bits | ? 0x311 0x314 0x317 0x163 0x31A 0x31E
+24 bits | ? 0x312 0x315 0x318 ? 0x31B 0x31F
+32 bits | ? ? ? ? 0x164 ?
+*/
+
+#define RES_MODE_640x480 0
+#define RES_MODE_800x600 1
+#define RES_MODE_1024x768 2
+#define RES_MODE_960_720 3
+#define RES_MODE_1152x864 4
+#define RES_MODES_COUNT 5
+
+#define VESA_MODES_COUNT 15
+
+static const struct ctfb_vesa_modes vesa_modes[VESA_MODES_COUNT] = {
+ {0x301, RES_MODE_640x480, 8},
+ {0x310, RES_MODE_640x480, 15},
+ {0x311, RES_MODE_640x480, 16},
+ {0x312, RES_MODE_640x480, 24},
+ {0x303, RES_MODE_800x600, 8},
+ {0x313, RES_MODE_800x600, 15},
+ {0x314, RES_MODE_800x600, 16},
+ {0x315, RES_MODE_800x600, 24},
+ {0x305, RES_MODE_1024x768, 8},
+ {0x316, RES_MODE_1024x768, 15},
+ {0x317, RES_MODE_1024x768, 16},
+ {0x318, RES_MODE_1024x768, 24},
+ {0x161, RES_MODE_1152x864, 8},
+ {0x162, RES_MODE_1152x864, 15},
+ {0x163, RES_MODE_1152x864, 16}
+};
+
+static const struct ctfb_res_modes res_mode_init[RES_MODES_COUNT] = {
+ /* x y pixclk le ri up lo hs vs s vmode */
+ {640, 480, 39721, 40, 24, 32, 11, 96, 2, 0,
+ FB_VMODE_NONINTERLACED},
+ {800, 600, 27778, 64, 24, 22, 1, 72, 2, 0, FB_VMODE_NONINTERLACED},
+ {1024, 768, 15384, 168, 8, 29, 3, 144, 4, 0,
+ FB_VMODE_NONINTERLACED},
+ {960, 720, 13100, 160, 40, 32, 8, 80, 4, 0,
+ FB_VMODE_NONINTERLACED},
+ {1152, 864, 12004, 200, 64, 32, 16, 80, 4, 0,
+ FB_VMODE_NONINTERLACED}
+};
+
+/*
+ * The Graphic Device
+ */
+GraphicDevice ctfb;
+
+/*******************************************************************************
+*
+* Low Level Routines
+*/
+
+/*******************************************************************************
+*
+* Read CT ISA register
+*/
+#ifdef VGA_DEBUG
+static unsigned char
+ctRead (unsigned short index)
+{
+ GraphicDevice *pGD = (GraphicDevice *) & ctfb;
+ if (index == CT_AR_O)
+ /* synch the Flip Flop */
+ in8 (pGD->isaBase + CT_STATUS_REG1_O);
+
+ return (in8 (pGD->isaBase + index));
+}
+#endif
+/*******************************************************************************
+*
+* Write CT ISA register
+*/
+static void
+ctWrite (unsigned short index, unsigned char val)
+{
+ GraphicDevice *pGD = (GraphicDevice *) & ctfb;
+
+ out8 ((pGD->isaBase + index), val);
+}
+
+/*******************************************************************************
+*
+* Read CT ISA register indexed
+*/
+static unsigned char
+ctRead_i (unsigned short index, char reg)
+{
+ GraphicDevice *pGD = (GraphicDevice *) & ctfb;
+ if (index == CT_AR_O)
+ /* synch the Flip Flop */
+ in8 (pGD->isaBase + CT_STATUS_REG1_O);
+ out8 ((pGD->isaBase + index), reg);
+ return (in8 (pGD->isaBase + index + 1));
+}
+
+/*******************************************************************************
+*
+* Write CT ISA register indexed
+*/
+static void
+ctWrite_i (unsigned short index, char reg, char val)
+{
+ GraphicDevice *pGD = (GraphicDevice *) & ctfb;
+ if (index == CT_AR_O) {
+ /* synch the Flip Flop */
+ in8 (pGD->isaBase + CT_STATUS_REG1_O);
+ out8 ((pGD->isaBase + index), reg);
+ out8 ((pGD->isaBase + index), val);
+ } else {
+ out8 ((pGD->isaBase + index), reg);
+ out8 ((pGD->isaBase + index + 1), val);
+ }
+}
+
+/*******************************************************************************
+*
+* Write a table of CT ISA register
+*/
+static void
+ctLoadRegs (unsigned short index, CT_CFG_TABLE * regTab)
+{
+ while (regTab->reg != 0xFF) {
+ ctWrite_i (index, regTab->reg, regTab->val);
+ regTab++;
+ }
+}
+
+/*****************************************************************************/
+static void
+SetArRegs (void)
+{
+ int i, tmp;
+
+ for (i = 0; i < 0x10; i++)
+ ctWrite_i (CT_AR_O, i, i);
+ if (text)
+ tmp = 0x04;
+ else
+ tmp = 0x41;
+
+ ctWrite_i (CT_AR_O, 0x10, tmp); /* Mode Control Register */
+ ctWrite_i (CT_AR_O, 0x11, 0x00); /* Overscan Color Register */
+ ctWrite_i (CT_AR_O, 0x12, 0x0f); /* Memory Plane Enable Register */
+ if (fntwidth == 9)
+ tmp = 0x08;
+ else
+ tmp = 0x00;
+ ctWrite_i (CT_AR_O, 0x13, tmp); /* Horizontal Pixel Panning */
+ ctWrite_i (CT_AR_O, 0x14, 0x00); /* Color Select Register */
+ ctWrite (CT_AR_O, 0x20); /* enable video */
+}
+
+/*****************************************************************************/
+static void
+SetGrRegs (void)
+{ /* Set Graphics Mode */
+ int i;
+
+ for (i = 0; i < 0x05; i++)
+ ctWrite_i (CT_GR_O, i, 0);
+ if (text) {
+ ctWrite_i (CT_GR_O, 0x05, 0x10);
+ ctWrite_i (CT_GR_O, 0x06, 0x02);
+ } else {
+ ctWrite_i (CT_GR_O, 0x05, 0x40);
+ ctWrite_i (CT_GR_O, 0x06, 0x05);
+ }
+ ctWrite_i (CT_GR_O, 0x07, 0x0f);
+ ctWrite_i (CT_GR_O, 0x08, 0xff);
+}
+
+/*****************************************************************************/
+static void
+SetSrRegs (void)
+{
+ int tmp = 0;
+
+ ctWrite_i (CT_SR_O, 0x00, 0x00); /* reset */
+ /*rr( sr, 0x01, tmp );
+ if( fntwidth == 8 ) tmp |= 0x01; else tmp &= ~0x01;
+ wr( sr, 0x01, tmp ); */
+ if (fntwidth == 8)
+ ctWrite_i (CT_SR_O, 0x01, 0x01); /* Clocking Mode Register */
+ else
+ ctWrite_i (CT_SR_O, 0x01, 0x00); /* Clocking Mode Register */
+ ctWrite_i (CT_SR_O, 0x02, 0x0f); /* Enable CPU wr access to given memory plane */
+ ctWrite_i (CT_SR_O, 0x03, 0x00); /* Character Map Select Register */
+ if (text)
+ tmp = 0x02;
+ else
+ tmp = 0x0e;
+ ctWrite_i (CT_SR_O, 0x04, tmp); /* Enable CPU accesses to the rest of the 256KB
+ total VGA memory beyond the first 64KB and set
+ fb mapping mode. */
+ ctWrite_i (CT_SR_O, 0x00, 0x03); /* enable */
+}
+
+/*****************************************************************************/
+static void
+SetBitsPerPixelIntoXrRegs (int bpp)
+{
+ unsigned int n = (bpp >> 3), tmp; /* only for 15, 8, 16, 24 bpp */
+ static char md[4] = { 0x04, 0x02, 0x05, 0x06 }; /* DisplayColorMode */
+ static char off[4] = { ~0x20, ~0x30, ~0x20, ~0x10 }; /* mask */
+ static char on[4] = { 0x10, 0x00, 0x10, 0x20 }; /* mask */
+ if (bpp == 15)
+ n = 0;
+ tmp = ctRead_i (CT_XR_O, 0x20);
+ tmp &= off[n];
+ tmp |= on[n];
+ ctWrite_i (CT_XR_O, 0x20, tmp); /* BitBLT Configuration */
+ ctWrite_i (CT_XR_O, 0x81, md[n]);
+}
+
+/*****************************************************************************/
+static void
+SetCrRegs (struct ctfb_res_modes *var, int bits_per_pixel)
+{ /* he -le- ht|0 hd -ri- hs -h- he */
+ unsigned char cr[0x7a];
+ int i, tmp;
+ unsigned int hd, hs, he, ht, hbe; /* Horizontal. */
+ unsigned int vd, vs, ve, vt; /* vertical */
+ unsigned int bpp, wd, dblscan, interlaced, bcast, CrtHalfLine;
+ unsigned int CompSyncCharClkDelay, CompSyncPixelClkDelay;
+ unsigned int NTSC_PAL_HorizontalPulseWidth, BlDelayCtrl;
+ unsigned int HorizontalEqualizationPulses;
+ unsigned int HorizontalSerration1Start, HorizontalSerration2Start;
+
+ const int LineCompare = 0x3ff;
+ unsigned int TextScanLines = 1; /* this is in fact a vertical zoom factor */
+ unsigned int RAMDAC_BlankPedestalEnable = 0; /* 1=en-, 0=disable, see XR82 */
+
+ hd = (var->xres) / 8; /* HDisp. */
+ hs = (var->xres + var->right_margin) / 8; /* HsStrt */
+ he = (var->xres + var->right_margin + var->hsync_len) / 8; /* HsEnd */
+ ht = (var->left_margin + var->xres + var->right_margin + var->hsync_len) / 8; /* HTotal */
+ hbe = ht - 1; /* HBlankEnable todo docu wants ht here, but it does not work */
+ /* ve -up- vt|0 vd -lo- vs -v- ve */
+ vd = var->yres; /* VDisplay */
+ vs = var->yres + var->lower_margin; /* VSyncStart */
+ ve = var->yres + var->lower_margin + var->vsync_len; /* VSyncEnd */
+ vt = var->upper_margin + var->yres + var->lower_margin + var->vsync_len; /* VTotal */
+ bpp = bits_per_pixel;
+ dblscan = (var->vmode & FB_VMODE_DOUBLE) ? 1 : 0;
+ interlaced = var->vmode & FB_VMODE_INTERLACED;
+ bcast = var->sync & FB_SYNC_BROADCAST;
+ CrtHalfLine = bcast ? (hd >> 1) : 0;
+ BlDelayCtrl = bcast ? 1 : 0;
+ CompSyncCharClkDelay = 0; /* 2 bit */
+ CompSyncPixelClkDelay = 0; /* 3 bit */
+ if (bcast) {
+ NTSC_PAL_HorizontalPulseWidth = 7; /*( var->hsync_len >> 1 ) + 1 */
+ HorizontalEqualizationPulses = 0; /* inverse value */
+ HorizontalSerration1Start = 31; /* ( ht >> 1 ) */
+ HorizontalSerration2Start = 89; /* ( ht >> 1 ) */
+ } else {
+ NTSC_PAL_HorizontalPulseWidth = 0;
+ /* 4 bit: hsync pulse width = ( ( CR74[4:0] - CR74[5] )
+ * / 2 ) + 1 --> CR74[4:0] = 2*(hs-1) + CR74[5] */
+ HorizontalEqualizationPulses = 1; /* inverse value */
+ HorizontalSerration1Start = 0; /* ( ht >> 1 ) */
+ HorizontalSerration2Start = 0; /* ( ht >> 1 ) */
+ }
+
+ if (bpp == 15)
+ bpp = 16;
+ wd = var->xres * bpp / 64; /* double words per line */
+ if (interlaced) { /* we divide all vertical timings, exept vd */
+ vs >>= 1;
+ ve >>= 1;
+ vt >>= 1;
+ }
+ memset (cr, 0, sizeof (cr));
+ cr[0x00] = 0xff & (ht - 5);
+ cr[0x01] = hd - 1; /* soll:4f ist 59 */
+ cr[0x02] = hd;
+ cr[0x03] = (hbe & 0x1F) | 0x80; /* hd + ht - hd */
+ cr[0x04] = hs;
+ cr[0x05] = ((hbe & 0x20) << 2) | (he & 0x1f);
+ cr[0x06] = (vt - 2) & 0xFF;
+ cr[0x30] = (vt - 2) >> 8;
+ cr[0x07] = ((vt & 0x100) >> 8)
+ | ((vd & 0x100) >> 7)
+ | ((vs & 0x100) >> 6)
+ | ((vs & 0x100) >> 5)
+ | ((LineCompare & 0x100) >> 4)
+ | ((vt & 0x200) >> 4)
+ | ((vd & 0x200) >> 3)
+ | ((vs & 0x200) >> 2);
+ cr[0x08] = 0x00;
+ cr[0x09] = (dblscan << 7)
+ | ((LineCompare & 0x200) >> 3)
+ | ((vs & 0x200) >> 4)
+ | (TextScanLines - 1);
+ cr[0x10] = vs & 0xff; /* VSyncPulseStart */
+ cr[0x32] = (vs & 0xf00) >> 8; /* VSyncPulseStart */
+ cr[0x11] = (ve & 0x0f); /* | 0x20; */
+ cr[0x12] = (vd - 1) & 0xff; /* LineCount */
+ cr[0x31] = ((vd - 1) & 0xf00) >> 8; /* LineCount */
+ cr[0x13] = wd & 0xff;
+ cr[0x41] = (wd & 0xf00) >> 8;
+ cr[0x15] = vs & 0xff;
+ cr[0x33] = (vs & 0xf00) >> 8;
+ cr[0x38] = (0x100 & (ht - 5)) >> 8;
+ cr[0x3C] = 0xc0 & hbe;
+ cr[0x16] = (vt - 1) & 0xff; /* vbe - docu wants vt here, */
+ cr[0x17] = 0xe3; /* but it does not work */
+ cr[0x18] = 0xff & LineCompare;
+ cr[0x22] = 0xff; /* todo? */
+ cr[0x70] = interlaced ? (0x80 | CrtHalfLine) : 0x00; /* check:0xa6 */
+ cr[0x71] = 0x80 | (RAMDAC_BlankPedestalEnable << 6)
+ | (BlDelayCtrl << 5)
+ | ((0x03 & CompSyncCharClkDelay) << 3)
+ | (0x07 & CompSyncPixelClkDelay); /* todo: see XR82 */
+ cr[0x72] = HorizontalSerration1Start;
+ cr[0x73] = HorizontalSerration2Start;
+ cr[0x74] = (HorizontalEqualizationPulses << 5)
+ | NTSC_PAL_HorizontalPulseWidth;
+ /* todo: ct69000 has also 0x75-79 */
+ /* now set the registers */
+ for (i = 0; i <= 0x0d; i++) { /*CR00 .. CR0D */
+ ctWrite_i (CT_CR_O, i, cr[i]);
+ }
+ for (i = 0x10; i <= 0x18; i++) { /*CR10 .. CR18 */
+ ctWrite_i (CT_CR_O, i, cr[i]);
+ }
+ i = 0x22; /*CR22 */
+ ctWrite_i (CT_CR_O, i, cr[i]);
+ for (i = 0x30; i <= 0x33; i++) { /*CR30 .. CR33 */
+ ctWrite_i (CT_CR_O, i, cr[i]);
+ }
+ i = 0x38; /*CR38 */
+ ctWrite_i (CT_CR_O, i, cr[i]);
+ i = 0x3C; /*CR3C */
+ ctWrite_i (CT_CR_O, i, cr[i]);
+ for (i = 0x40; i <= 0x41; i++) { /*CR40 .. CR41 */
+ ctWrite_i (CT_CR_O, i, cr[i]);
+ }
+ for (i = 0x70; i <= 0x74; i++) { /*CR70 .. CR74 */
+ ctWrite_i (CT_CR_O, i, cr[i]);
+ }
+ tmp = ctRead_i (CT_CR_O, 0x40);
+ tmp &= 0x0f;
+ tmp |= 0x80;
+ ctWrite_i (CT_CR_O, 0x40, tmp); /* StartAddressEnable */
+}
+
+/* pixelclock control */
+
+/*****************************************************************************
+ We have a rational number p/q and need an m/n which is very close to p/q
+ but has m and n within mnmin and mnmax. We have no floating point in the
+ kernel. We can use long long without divide. And we have time to compute...
+******************************************************************************/
+static unsigned int
+FindBestPQFittingMN (unsigned int p, unsigned int q, unsigned int mnmin,
+ unsigned int mnmax, unsigned int *pm, unsigned int *pn)
+{
+ /* this code is not for general purpose usable but good for our number ranges */
+ unsigned int n = mnmin, m = 0;
+ long long int L = 0, P = p, Q = q, H = P >> 1;
+ long long int D = 0x7ffffffffffffffLL;
+ for (n = mnmin; n <= mnmax; n++) {
+ m = mnmin; /* p/q ~ m/n -> p*n ~ m*q -> p*n-x*q ~ 0 */
+ L = P * n - m * Q; /* n * vco - m * fref should be near 0 */
+ while (L > 0 && m < mnmax) {
+ L -= q; /* difference is greater as 0 subtract fref */
+ m++; /* and increment m */
+ }
+ /* difference is less or equal than 0 or m > maximum */
+ if (m > mnmax)
+ break; /* no solution: if we increase n we get the same situation */
+ /* L is <= 0 now */
+ if (-L > H && m > mnmin) { /* if difference > the half fref */
+ L += q; /* we take the situation before */
+ m--; /* because its closer to 0 */
+ }
+ L = (L < 0) ? -L : +L; /* absolute value */
+ if (D < L) /* if last difference was better take next n */
+ continue;
+ D = L;
+ *pm = m;
+ *pn = n; /* keep improved data */
+ if (D == 0)
+ break; /* best result we can get */
+ }
+ return (unsigned int) (0xffffffff & D);
+}
+
+/* that is the hardware < 69000 we have to manage
+ +---------+ +-------------------+ +----------------------+ +--+
+ | REFCLK |__|NTSC Divisor Select|__|FVCO Reference Divisor|__|÷N|__
+ | 14.3MHz | |(NTSCDS) (÷1, ÷5) | |Select (RDS) (÷1, ÷4) | | | |
+ +---------+ +-------------------+ +----------------------+ +--+ |
+ ___________________________________________________________________|
+ |
+ | fvco fout
+ | +--------+ +------------+ +-----+ +-------------------+ +----+
+ +-| Phase |__|Charge Pump |__| VCO |_____|Post Divisor (PD) |___|CLK |--->
+ +-| Detect | |& Filter VCO| | | | |÷1, 2, 4, 8, 16, 32| | |
+ | +--------+ +------------+ +-----+ | +-------------------+ +----+
+ | |
+ | +--+ +---------------+ |
+ |____|÷M|___|VCO Loop Divide|__________|
+ | | |(VLD)(÷4, ÷16) |
+ +--+ +---------------+
+****************************************************************************
+ that is the hardware >= 69000 we have to manage
+ +---------+ +--+
+ | REFCLK |__|÷N|__
+ | 14.3MHz | | | |
+ +---------+ +--+ |
+ __________________|
+ |
+ | fvco fout
+ | +--------+ +------------+ +-----+ +-------------------+ +----+
+ +-| Phase |__|Charge Pump |__| VCO |_____|Post Divisor (PD) |___|CLK |--->
+ +-| Detect | |& Filter VCO| | | | |÷1, 2, 4, 8, 16, 32| | |
+ | +--------+ +------------+ +-----+ | +-------------------+ +----+
+ | |
+ | +--+ +---------------+ |
+ |____|÷M|___|VCO Loop Divide|__________|
+ | | |(VLD)(÷1, ÷4) |
+ +--+ +---------------+
+
+
+*/
+
+#define VIDEO_FREF 14318180; /* Hz */
+/*****************************************************************************/
+static int
+ReadPixClckFromXrRegsBack (struct ctfb_chips_properties *param)
+{
+ unsigned int m, n, vld, pd, PD, fref, xr_cb, i, pixclock;
+ i = 0;
+ pixclock = -1;
+ fref = VIDEO_FREF;
+ m = ctRead_i (CT_XR_O, 0xc8);
+ n = ctRead_i (CT_XR_O, 0xc9);
+ m -= param->mn_diff;
+ n -= param->mn_diff;
+ xr_cb = ctRead_i (CT_XR_O, 0xcb);
+ PD = (0x70 & xr_cb) >> 4;
+ pd = 1;
+ for (i = 0; i < PD; i++) {
+ pd *= 2;
+ }
+ vld = (0x04 & xr_cb) ? param->vld_set : param->vld_not_set;
+ if (n * vld * m) {
+ unsigned long long p = 1000000000000LL * pd * n;
+ unsigned long long q = (long long) fref * vld * m;
+ while ((p > 0xffffffffLL) || (q > 0xffffffffLL)) {
+ p >>= 1; /* can't divide with long long so we scale down */
+ q >>= 1;
+ }
+ pixclock = (unsigned) p / (unsigned) q;
+ } else
+ printf ("Invalid data in xr regs.\n");
+ return pixclock;
+}
+
+/*****************************************************************************/
+static void
+FindAndSetPllParamIntoXrRegs (unsigned int pixelclock,
+ struct ctfb_chips_properties *param)
+{
+ unsigned int m, n, vld, pd, PD, fref, xr_cb;
+ unsigned int fvcomin, fvcomax, pclckmin, pclckmax, pclk;
+ unsigned int pfreq, fvco, new_pixclock;
+
+ fref = VIDEO_FREF;
+ pd = 1;
+ PD = 0;
+ fvcomin = param->vco_min;
+ fvcomax = param->vco_max; /* MHz */
+ pclckmin = 1000000 / fvcomax + 1; /* 4546 */
+ pclckmax = 32000000 / fvcomin - 1; /* 666665 */
+ pclk = minmax (pclckmin, pixelclock, pclckmax); /* ps pp */
+ pfreq = 250 * (4000000000U / pclk);
+ fvco = pfreq; /* Hz */
+ new_pixclock = 0;
+ while (fvco < fvcomin * 1000000) {
+ /* double VCO starting with the pixelclock frequency
+ * as long as it is lower than the minimal VCO frequency */
+ fvco *= 2;
+ pd *= 2;
+ PD++;
+ }
+ /* fvco is exactly pd * pixelclock and higher than the ninmal VCO frequency */
+ vld = (param->vld_set > param->vld_not_set) ?
+ param->vld_not_set : param->vld_set;
+ /* start with lower VLD (higher VLD is NOT yet implemented */
+ FindBestPQFittingMN (fvco / vld, fref, param->mn_min, param->mn_max, &m, &n); /* rds = 1 */
+ m += param->mn_diff;
+ n += param->mn_diff;
+ PRINTF ("VCO %d, pd %d, m %d n %d vld %d \n", fvco, pd, m, n, vld);
+ xr_cb = ((0x7 & PD) << 4) | (vld == param->vld_set ? 0x04 : 0);
+ /* All four of the registers used for dot clock 2 (XRC8 - XRCB) must be
+ * written, and in order from XRC8 to XRCB, before the hardware will
+ * update the synthesizer s settings.
+ */
+ ctWrite_i (CT_XR_O, 0xc8, m);
+ ctWrite_i (CT_XR_O, 0xc9, n); /* xrca does not exist in CT69000 and CT69030 */
+ ctWrite_i (CT_XR_O, 0xca, 0); /* because of a hw bug I guess, but we write */
+ ctWrite_i (CT_XR_O, 0xcb, xr_cb); /* 0 to it for savety */
+ new_pixclock = ReadPixClckFromXrRegsBack (param);
+ PRINTF ("pixelclock.set = %d, pixelclock.real = %d \n",
+ pixelclock, new_pixclock);
+}
+
+/*****************************************************************************/
+static void
+SetMsrRegs (struct ctfb_res_modes *mode)
+{
+ unsigned char h_synch_high, v_synch_high;
+
+ h_synch_high = (mode->sync & FB_SYNC_HOR_HIGH_ACT) ? 0 : 0x40; /* horizontal Synch High active */
+ v_synch_high = (mode->sync & FB_SYNC_VERT_HIGH_ACT) ? 0 : 0x80; /* vertical Synch High active */
+ ctWrite (CT_MSR_W_O, (h_synch_high | v_synch_high | 0x29));
+ /* upper64K==0x20, CLC2select==0x08, RAMenable==0x02!(todo), CGA==0x01
+ * Selects the upper 64KB page.Bit5=1
+ * CLK2 (left reserved in standard VGA) Bit3|2=1|0
+ * Disables CPU access to frame buffer. Bit1=0
+ * Sets the I/O address decode for ST01, FCR, and all CR registers
+ * to the 3Dx I/O address range (CGA emulation). Bit0=1
+ */
+}
+
+/************************************************************************************/
+#ifdef VGA_DUMP_REG
+
+static void
+ctDispRegs (unsigned short index, int from, int to)
+{
+ unsigned char status;
+ int i;
+
+ for (i = from; i < to; i++) {
+ status = ctRead_i (index, i);
+ printf ("%02X: is %02X\n", i, status);
+ }
+}
+
+void
+video_dump_reg (void)
+{
+ int i;
+
+ printf ("Extended Regs:\n");
+ ctDispRegs (CT_XR_O, 0, 0xC);
+ ctDispRegs (CT_XR_O, 0xe, 0xf);
+ ctDispRegs (CT_XR_O, 0x20, 0x21);
+ ctDispRegs (CT_XR_O, 0x40, 0x50);
+ ctDispRegs (CT_XR_O, 0x60, 0x64);
+ ctDispRegs (CT_XR_O, 0x67, 0x68);
+ ctDispRegs (CT_XR_O, 0x70, 0x72);
+ ctDispRegs (CT_XR_O, 0x80, 0x83);
+ ctDispRegs (CT_XR_O, 0xA0, 0xB0);
+ ctDispRegs (CT_XR_O, 0xC0, 0xD3);
+ printf ("Sequencer Regs:\n");
+ ctDispRegs (CT_SR_O, 0, 0x8);
+ printf ("Graphic Regs:\n");
+ ctDispRegs (CT_GR_O, 0, 0x9);
+ printf ("CRT Regs:\n");
+ ctDispRegs (CT_CR_O, 0, 0x19);
+ ctDispRegs (CT_CR_O, 0x22, 0x23);
+ ctDispRegs (CT_CR_O, 0x30, 0x34);
+ ctDispRegs (CT_CR_O, 0x38, 0x39);
+ ctDispRegs (CT_CR_O, 0x3C, 0x3D);
+ ctDispRegs (CT_CR_O, 0x40, 0x42);
+ ctDispRegs (CT_CR_O, 0x70, 0x80);
+ /* don't display the attributes */
+}
+
+#endif
+
+#ifdef CONFIG_VIDEO_HW_CURSOR
+/***************************************************************
+ * Set Hardware Cursor in Pixel
+ */
+void
+video_set_hw_cursor (int x, int y)
+{
+ int sig_x = 0, sig_y = 0;
+ if (x < 0) {
+ x *= -1;
+ sig_x = 1;
+ }
+ if (y < 0) {
+ y *= -1;
+ sig_y = 1;
+ }
+ ctWrite_i (CT_XR_O, 0xa4, x & 0xff);
+ ctWrite_i (CT_XR_O, 0xa5, (x >> 8) & 0x7);
+ ctWrite_i (CT_XR_O, 0xa6, y & 0xff);
+ ctWrite_i (CT_XR_O, 0xa7, (y >> 8) & 0x7);
+}
+
+/***************************************************************
+ * Init Hardware Cursor. To know the size of the Cursor,
+ * we have to know the Font size.
+ */
+void
+video_init_hw_cursor (int font_width, int font_height)
+{
+ unsigned char xr_80;
+ unsigned long *curs, pattern;
+ int i;
+ int cursor_start;
+ GraphicDevice *pGD = (GraphicDevice *) & ctfb;
+
+ cursor_start = pGD->dprBase;
+ xr_80 = ctRead_i (CT_XR_O, 0x80);
+ /* set start address */
+ ctWrite_i (CT_XR_O, 0xa2, (cursor_start >> 8) & 0xf0);
+ ctWrite_i (CT_XR_O, 0xa3, (cursor_start >> 16) & 0x3f);
+ /* set cursor shape */
+ curs = (unsigned long *) cursor_start;
+ i = 0;
+ while (i < 0x400) {
+ curs[i++] = 0xffffffff; /* AND mask */
+ curs[i++] = 0xffffffff; /* AND mask */
+ curs[i++] = 0; /* XOR mask */
+ curs[i++] = 0; /* XOR mask */
+ /* Transparent */
+ }
+ pattern = 0xffffffff >> font_width;
+ i = 0;
+ while (i < (font_height * 2)) {
+ curs[i++] = pattern; /* AND mask */
+ curs[i++] = pattern; /* AND mask */
+ curs[i++] = 0; /* XOR mask */
+ curs[i++] = 0; /* XOR mask */
+ /* Cursor Color 0 */
+ }
+ /* set blink rate */
+ ctWrite_i (CT_FP_O, 0x19, 0xf);
+
+ /* set cursors colors */
+ xr_80 = ctRead_i (CT_XR_O, 0x80);
+ xr_80 |= 0x1; /* alternate palette select */
+ ctWrite_i (CT_XR_O, 0x80, xr_80);
+ video_set_lut (4, CONSOLE_FG_COL, CONSOLE_FG_COL, CONSOLE_FG_COL);
+ /* position 4 is color 0 cursor 0 */
+ xr_80 &= 0xfe; /* normal palette select */
+ ctWrite_i (CT_XR_O, 0x80, xr_80);
+ /* cursor enable */
+ ctWrite_i (CT_XR_O, 0xa0, 0x91);
+ xr_80 |= 0x10; /* enable hwcursor */
+ ctWrite_i (CT_XR_O, 0x80, xr_80);
+ video_set_hw_cursor (0, 0);
+}
+#endif /* CONFIG_VIDEO_HW_CURSOR */
+
+/***************************************************************
+ * Wait for BitBlt ready
+ */
+static int
+video_wait_bitblt (unsigned long addr)
+{
+ unsigned long br04;
+ int i = 0;
+ br04 = in32r (addr);
+ while (br04 & 0x80000000) {
+ udelay (1);
+ br04 = in32r (addr);
+ if (i++ > 1000000) {
+ printf ("ERROR Timeout %lx\n", br04);
+ return 1;
+ }
+ }
+ return 0;
+}
+
+/***************************************************************
+ * Set up BitBlt Registrs
+ */
+static void
+SetDrawingEngine (int bits_per_pixel)
+{
+ unsigned long br04, br00;
+ unsigned char tmp;
+
+ GraphicDevice *pGD = (GraphicDevice *) & ctfb;
+
+ tmp = ctRead_i (CT_XR_O, 0x20); /* BitBLT Configuration */
+ tmp |= 0x02; /* reset BitBLT */
+ ctWrite_i (CT_XR_O, 0x20, tmp); /* BitBLT Configuration */
+ udelay (10);
+ tmp &= 0xfd; /* release reset BitBLT */
+ ctWrite_i (CT_XR_O, 0x20, tmp); /* BitBLT Configuration */
+ video_wait_bitblt (pGD->pciBase + BR04_o);
+
+ /* set pattern Address */
+ out32r (pGD->pciBase + BR05_o, PATTERN_ADR & 0x003ffff8);
+ br04 = 0;
+ if (bits_per_pixel == 1) {
+ br04 |= 0x00040000; /* monochome Pattern */
+ br04 |= 0x00001000; /* monochome source */
+ }
+ br00 = ((pGD->winSizeX * pGD->gdfBytesPP) << 16) + (pGD->winSizeX * pGD->gdfBytesPP); /* bytes per scanline */
+ out32r (pGD->pciBase + BR00_o, br00); /* */
+ out32r (pGD->pciBase + BR08_o, (10 << 16) + 10); /* dummy */
+ out32r (pGD->pciBase + BR04_o, br04); /* write all 0 */
+ out32r (pGD->pciBase + BR07_o, 0); /* destination */
+ video_wait_bitblt (pGD->pciBase + BR04_o);
+}
+
+/************************************************************************
+ * Get Parameters for the video mode:
+ */
+/*********************************************************************
+ * returns the length to the next seperator
+ */
+static int
+video_get_param_len (char *start, char sep)
+{
+ int i = 0;
+ while ((*start != 0) && (*start != sep)) {
+ start++;
+ i++;
+ }
+ return i;
+}
+
+static int
+video_search_param (char *start, char *param)
+{
+ int len, totallen, i;
+ char *p = start;
+ len = strlen (param);
+ totallen = len + strlen (start);
+ for (i = 0; i < totallen; i++) {
+ if (strncmp (p++, param, len) == 0)
+ return (i);
+ }
+ return -1;
+}
+
+/***************************************************************
+* Get parameter via the environment as it is done for the
+* linux kernel i.e:
+* video=ctfb:x:800,xv:1280,y:600,yv:1024,depth:16,mode:0,pclk:25000,
+* le:56,ri:48,up:26,lo:5,hs:152,vs:2,sync:0,vmode:0,accel:0
+*
+* penv is a pointer to the environment, containing the string, or the name of
+* another environment variable. It could even be the term "bootargs"
+*/
+
+#define GET_OPTION(name,var) \
+ if(strncmp(p,name,strlen(name))==0) { \
+ val_s=p+strlen(name); \
+ var=simple_strtoul(val_s, NULL, 10); \
+ }
+
+static int
+video_get_params (struct ctfb_res_modes *pPar, char *penv)
+{
+ char *p, *s, *val_s;
+ int i = 0, t;
+ int bpp;
+ int mode;
+ /* first search for the environment containing the real param string */
+ s = penv;
+ if ((p = getenv (s)) != NULL) {
+ s = p;
+ }
+ /* in case of the bootargs line, we have to start
+ * after "video=ctfb:"
+ */
+ i = video_search_param (s, "video=ctfb:");
+ if (i >= 0) {
+ s += i;
+ s += strlen ("video=ctfb:");
+ }
+ /* search for mode as a default value */
+ p = s;
+ t = 0;
+ mode = 0; /* default */
+ while ((i = video_get_param_len (p, ',')) != 0) {
+ GET_OPTION ("mode:", mode)
+ p += i;
+ if (*p != 0)
+ p++; /* skip ',' */
+ }
+ if (mode >= RES_MODES_COUNT)
+ mode = 0;
+ *pPar = res_mode_init[mode]; /* copy default values */
+ bpp = 24 - ((mode % 3) * 8);
+ p = s; /* restart */
+ while ((i = video_get_param_len (p, ',')) != 0) {
+ GET_OPTION ("x:", pPar->xres)
+ GET_OPTION ("y:", pPar->yres)
+ GET_OPTION ("le:", pPar->left_margin)
+ GET_OPTION ("ri:", pPar->right_margin)
+ GET_OPTION ("up:", pPar->upper_margin)
+ GET_OPTION ("lo:", pPar->lower_margin)
+ GET_OPTION ("hs:", pPar->hsync_len)
+ GET_OPTION ("vs:", pPar->vsync_len)
+ GET_OPTION ("sync:", pPar->sync)
+ GET_OPTION ("vmode:", pPar->vmode)
+ GET_OPTION ("pclk:", pPar->pixclock)
+ GET_OPTION ("depth:", bpp)
+ p += i;
+ if (*p != 0)
+ p++; /* skip ',' */
+ }
+ return bpp;
+}
+
+/****************************************************************************
+* supported Video Chips
+*/
+static struct pci_device_id supported[] = {
+ {PCI_VENDOR_ID_CT, PCI_DEVICE_ID_CT_69000},
+ {}
+};
+
+/*******************************************************************************
+*
+* Init video chip
+*/
+void *
+video_hw_init (void)
+{
+ GraphicDevice *pGD = (GraphicDevice *) & ctfb;
+ unsigned short device_id;
+ pci_dev_t devbusfn;
+ int videomode;
+ unsigned long t1, hsynch, vsynch;
+ unsigned int pci_mem_base, *vm;
+ int tmp, i, bits_per_pixel;
+ char *penv;
+ struct ctfb_res_modes *res_mode;
+ struct ctfb_res_modes var_mode;
+ struct ctfb_chips_properties *chips_param;
+ /* Search for video chip */
+
+ if ((devbusfn = pci_find_devices (supported, 0)) < 0) {
+#ifdef CONFIG_VIDEO_ONBOARD
+ printf ("Video: Controller not found !\n");
+#endif
+ return (NULL);
+ }
+
+ /* PCI setup */
+ pci_write_config_dword (devbusfn, PCI_COMMAND,
+ (PCI_COMMAND_MEMORY | PCI_COMMAND_IO));
+ pci_read_config_word (devbusfn, PCI_DEVICE_ID, &device_id);
+ pci_read_config_dword (devbusfn, PCI_BASE_ADDRESS_0, &pci_mem_base);
+ pci_mem_base = pci_mem_to_phys (devbusfn, pci_mem_base);
+
+ /* get chips params */
+ for (chips_param = (struct ctfb_chips_properties *) &chips[0];
+ chips_param->device_id != 0; chips_param++) {
+ if (chips_param->device_id == device_id)
+ break;
+ }
+ if (chips_param->device_id == 0) {
+#ifdef CONFIG_VIDEO_ONBOARD
+ printf ("Video: controller 0x%X not supported\n", device_id);
+#endif
+ return NULL;
+ }
+ /* supported Video controller found */
+ printf ("Video: ");
+
+ tmp = 0;
+ videomode = 0x301;
+ /* get video mode via environment */
+ if ((penv = getenv ("videomode")) != NULL) {
+ /* deceide if it is a string */
+ if (penv[0] <= '9') {
+ videomode = (int) simple_strtoul (penv, NULL, 16);
+ tmp = 1;
+ }
+ } else {
+ tmp = 1;
+ }
+ if (tmp) {
+ /* parameter are vesa modes */
+ /* search params */
+ for (i = 0; i < VESA_MODES_COUNT; i++) {
+ if (vesa_modes[i].vesanr == videomode)
+ break;
+ }
+ if (i == VESA_MODES_COUNT) {
+ printf ("no VESA Mode found, switching to mode 0x301 ");
+ i = 0;
+ }
+ res_mode =
+ (struct ctfb_res_modes *) &res_mode_init[vesa_modes[i].
+ resindex];
+ bits_per_pixel = vesa_modes[i].bits_per_pixel;
+ } else {
+
+ res_mode = (struct ctfb_res_modes *) &var_mode;
+ bits_per_pixel = video_get_params (res_mode, penv);
+ }
+
+ /* calculate available color depth for controller memory */
+ if (bits_per_pixel == 15)
+ tmp = 2;
+ else
+ tmp = bits_per_pixel >> 3; /* /8 */
+ if (((chips_param->max_mem -
+ ACCELMEMORY) / (res_mode->xres * res_mode->yres)) < tmp) {
+ tmp =
+ ((chips_param->max_mem -
+ ACCELMEMORY) / (res_mode->xres * res_mode->yres));
+ if (tmp == 0) {
+ printf
+ ("No matching videomode found .-> reduce resolution\n");
+ return NULL;
+ } else {
+ printf ("Switching back to %d Bits per Pixel ",
+ tmp << 3);
+ bits_per_pixel = tmp << 3;
+ }
+ }
+
+ /* calculate hsynch and vsynch freq (info only) */
+ t1 = (res_mode->left_margin + res_mode->xres +
+ res_mode->right_margin + res_mode->hsync_len) / 8;
+ t1 *= 8;
+ t1 *= res_mode->pixclock;
+ t1 /= 1000;
+ hsynch = 1000000000L / t1;
+ t1 *=
+ (res_mode->upper_margin + res_mode->yres +
+ res_mode->lower_margin + res_mode->vsync_len);
+ t1 /= 1000;
+ vsynch = 1000000000L / t1;
+
+ /* fill in Graphic device struct */
+ sprintf (pGD->modeIdent, "%dx%dx%d %ldkHz %ldHz", res_mode->xres,
+ res_mode->yres, bits_per_pixel, (hsynch / 1000),
+ (vsynch / 1000));
+ printf ("%s\n", pGD->modeIdent);
+ pGD->winSizeX = res_mode->xres;
+ pGD->winSizeY = res_mode->yres;
+ pGD->plnSizeX = res_mode->xres;
+ pGD->plnSizeY = res_mode->yres;
+ switch (bits_per_pixel) {
+ case 8:
+ pGD->gdfBytesPP = 1;
+ pGD->gdfIndex = GDF__8BIT_INDEX;
+ break;
+ case 15:
+ pGD->gdfBytesPP = 2;
+ pGD->gdfIndex = GDF_15BIT_555RGB;
+ break;
+ case 16:
+ pGD->gdfBytesPP = 2;
+ pGD->gdfIndex = GDF_16BIT_565RGB;
+ break;
+ case 24:
+ pGD->gdfBytesPP = 3;
+ pGD->gdfIndex = GDF_24BIT_888RGB;
+ break;
+ }
+ pGD->isaBase = CFG_ISA_IO_BASE_ADDRESS;
+ pGD->pciBase = pci_mem_base;
+ pGD->frameAdrs = pci_mem_base;
+ pGD->memSize = chips_param->max_mem;
+ /* Cursor Start Address */
+ pGD->dprBase =
+ (pGD->winSizeX * pGD->winSizeY * pGD->gdfBytesPP) + pci_mem_base;
+ if ((pGD->dprBase & 0x0fff) != 0) {
+ /* allign it */
+ pGD->dprBase &= 0xfffff000;
+ pGD->dprBase += 0x00001000;
+ }
+ PRINTF ("Cursor Start %x Pattern Start %x\n", pGD->dprBase,
+ PATTERN_ADR);
+ pGD->vprBase = pci_mem_base; /* Dummy */
+ pGD->cprBase = pci_mem_base; /* Dummy */
+ /* set up Hardware */
+
+ ctWrite (CT_MSR_W_O, 0x01);
+
+ /* set the extended Registers */
+ ctLoadRegs (CT_XR_O, xreg);
+ /* set atribute registers */
+ SetArRegs ();
+ /* set Graphics register */
+ SetGrRegs ();
+ /* set sequencer */
+ SetSrRegs ();
+
+ /* set msr */
+ SetMsrRegs (res_mode);
+
+ /* set CRT Registers */
+ SetCrRegs (res_mode, bits_per_pixel);
+ /* set color mode */
+ SetBitsPerPixelIntoXrRegs (bits_per_pixel);
+
+ /* set PLL */
+ FindAndSetPllParamIntoXrRegs (res_mode->pixclock, chips_param);
+
+ ctWrite_i (CT_SR_O, 0, 0x03); /* clear synchronous reset */
+ /* Clear video memory */
+ i = pGD->memSize / 4;
+ vm = (unsigned int *) pGD->pciBase;
+ while (i--)
+ *vm++ = 0;
+ SetDrawingEngine (bits_per_pixel);
+#ifdef VGA_DUMP_REG
+ video_dump_reg ();
+#endif
+
+ return ((void *) &ctfb);
+}
+
+ /*******************************************************************************
+*
+* Set a RGB color in the LUT (8 bit index)
+*/
+void
+video_set_lut (unsigned int index, /* color number */
+ unsigned char r, /* red */
+ unsigned char g, /* green */
+ unsigned char b /* blue */
+ )
+{
+
+ ctWrite (CT_LUT_MASK_O, 0xff);
+
+ ctWrite (CT_LUT_START_O, (char) index);
+
+ ctWrite (CT_LUT_RGB_O, r); /* red */
+ ctWrite (CT_LUT_RGB_O, g); /* green */
+ ctWrite (CT_LUT_RGB_O, b); /* blue */
+ udelay (1);
+ ctWrite (CT_LUT_MASK_O, 0xff);
+}
+
+/*******************************************************************************
+*
+* Drawing engine fill on screen region
+*/
+void
+video_hw_rectfill (unsigned int bpp, /* bytes per pixel */
+ unsigned int dst_x, /* dest pos x */
+ unsigned int dst_y, /* dest pos y */
+ unsigned int dim_x, /* frame width */
+ unsigned int dim_y, /* frame height */
+ unsigned int color /* fill color */
+ )
+{
+ GraphicDevice *pGD = (GraphicDevice *) & ctfb;
+ unsigned long *p, br04;
+
+ video_wait_bitblt (pGD->pciBase + BR04_o);
+
+ p = (unsigned long *) PATTERN_ADR;
+ dim_x *= bpp;
+ if (bpp == 3)
+ bpp++; /* 24Bit needs a 32bit pattern */
+ memset (p, color, (bpp * sizeof (unsigned char) * 8 * 8)); /* 8 x 8 pattern data */
+ out32r (pGD->pciBase + BR07_o, ((pGD->winSizeX * dst_y) + dst_x) * pGD->gdfBytesPP); /* destination */
+ br04 = in32r (pGD->pciBase + BR04_o) & 0xffffff00;
+ br04 |= 0xF0; /* write Pattern P -> D */
+ out32r (pGD->pciBase + BR04_o, br04); /* */
+ out32r (pGD->pciBase + BR08_o, (dim_y << 16) + dim_x); /* starts the BITBlt */
+ video_wait_bitblt (pGD->pciBase + BR04_o);
+}
+
+/*******************************************************************************
+*
+* Drawing engine bitblt with screen region
+*/
+void
+video_hw_bitblt (unsigned int bpp, /* bytes per pixel */
+ unsigned int src_x, /* source pos x */
+ unsigned int src_y, /* source pos y */
+ unsigned int dst_x, /* dest pos x */
+ unsigned int dst_y, /* dest pos y */
+ unsigned int dim_x, /* frame width */
+ unsigned int dim_y /* frame height */
+ )
+{
+ GraphicDevice *pGD = (GraphicDevice *) & ctfb;
+ unsigned long br04;
+
+ br04 = in32r (pGD->pciBase + BR04_o);
+
+ /* to prevent data corruption due to overlap, we have to
+ * find out if, and how the frames overlaps */
+ if (src_x < dst_x) {
+ /* src is more left than dest
+ * the frame may overlap -> start from right to left */
+ br04 |= 0x00000100; /* set bit 8 */
+ src_x += dim_x;
+ dst_x += dim_x;
+ } else {
+ br04 &= 0xfffffeff; /* clear bit 8 left to right */
+ }
+ if (src_y < dst_y) {
+ /* src is higher than dst
+ * the frame may overlap => start from bottom */
+ br04 |= 0x00000200; /* set bit 9 */
+ src_y += dim_y;
+ dst_y += dim_y;
+ } else {
+ br04 &= 0xfffffdff; /* clear bit 9 top to bottom */
+ }
+ dim_x *= bpp;
+ out32r (pGD->pciBase + BR06_o, ((pGD->winSizeX * src_y) + src_x) * pGD->gdfBytesPP); /* source */
+ out32r (pGD->pciBase + BR07_o, ((pGD->winSizeX * dst_y) + dst_x) * pGD->gdfBytesPP); /* destination */
+ br04 &= 0xffffff00;
+ br04 |= 0x000000CC; /* S -> D */
+ out32r (pGD->pciBase + BR04_o, br04); /* */
+ out32r (pGD->pciBase + BR08_o, (dim_y << 16) + dim_x); /* start the BITBlt */
+ video_wait_bitblt (pGD->pciBase + BR04_o);
+}
+
+#endif /* CONFIG_CT69000 */
+
+#endif /* CONFIG_VIDEO */
--- /dev/null
+/*
+ * 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 (CONFIG_COMMANDS & CFG_CMD_NET) && defined(CONFIG_NET_MULTI) \
+ && defined(CONFIG_TULIP)
+
+#include <malloc.h>
+#include <net.h>
+#include <pci.h>
+
+#undef DEBUG
+#undef DEBUG_SROM
+#undef DEBUG_SROM2
+
+#undef UPDATE_SROM
+
+/* PCI Registers.
+ */
+#define PCI_CFDA_PSM 0x43
+
+#define CFRV_RN 0x000000f0 /* Revision Number */
+
+#define WAKEUP 0x00 /* Power Saving Wakeup */
+#define SLEEP 0x80 /* Power Saving Sleep Mode */
+
+#define DC2114x_BRK 0x0020 /* CFRV break between DC21142 & DC21143 */
+
+/* Ethernet chip registers.
+ */
+#define DE4X5_BMR 0x000 /* Bus Mode Register */
+#define DE4X5_TPD 0x008 /* Transmit Poll Demand Reg */
+#define DE4X5_RRBA 0x018 /* RX Ring Base Address Reg */
+#define DE4X5_TRBA 0x020 /* TX Ring Base Address Reg */
+#define DE4X5_STS 0x028 /* Status Register */
+#define DE4X5_OMR 0x030 /* Operation Mode Register */
+#define DE4X5_SICR 0x068 /* SIA Connectivity Register */
+#define DE4X5_APROM 0x048 /* Ethernet Address PROM */
+
+/* Register bits.
+ */
+#define BMR_SWR 0x00000001 /* Software Reset */
+#define STS_TS 0x00700000 /* Transmit Process State */
+#define STS_RS 0x000e0000 /* Receive Process State */
+#define OMR_ST 0x00002000 /* Start/Stop Transmission Command */
+#define OMR_SR 0x00000002 /* Start/Stop Receive */
+#define OMR_PS 0x00040000 /* Port Select */
+#define OMR_SDP 0x02000000 /* SD Polarity - MUST BE ASSERTED */
+#define OMR_PM 0x00000080 /* Pass All Multicast */
+
+/* Descriptor bits.
+ */
+#define R_OWN 0x80000000 /* Own Bit */
+#define RD_RER 0x02000000 /* Receive End Of Ring */
+#define RD_LS 0x00000100 /* Last Descriptor */
+#define RD_ES 0x00008000 /* Error Summary */
+#define TD_TER 0x02000000 /* Transmit End Of Ring */
+#define T_OWN 0x80000000 /* Own Bit */
+#define TD_LS 0x40000000 /* Last Segment */
+#define TD_FS 0x20000000 /* First Segment */
+#define TD_ES 0x00008000 /* Error Summary */
+#define TD_SET 0x08000000 /* Setup Packet */
+
+/* The EEPROM commands include the alway-set leading bit. */
+#define SROM_WRITE_CMD 5
+#define SROM_READ_CMD 6
+#define SROM_ERASE_CMD 7
+
+#define SROM_HWADD 0x0014 /* Hardware Address offset in SROM */
+#define SROM_RD 0x00004000 /* Read from Boot ROM */
+#define EE_DATA_WRITE 0x04 /* EEPROM chip data in. */
+#define EE_WRITE_0 0x4801
+#define EE_WRITE_1 0x4805
+#define EE_DATA_READ 0x08 /* EEPROM chip data out. */
+#define SROM_SR 0x00000800 /* Select Serial ROM when set */
+
+#define DT_IN 0x00000004 /* Serial Data In */
+#define DT_CLK 0x00000002 /* Serial ROM Clock */
+#define DT_CS 0x00000001 /* Serial ROM Chip Select */
+
+#define POLL_DEMAND 1
+
+#define RESET_DE4X5(dev) {\
+ int i;\
+ i=INL(dev, DE4X5_BMR);\
+ udelay(1000);\
+ OUTL(dev, i | BMR_SWR, DE4X5_BMR);\
+ udelay(1000);\
+ OUTL(dev, i, DE4X5_BMR);\
+ udelay(1000);\
+ for (i=0;i<5;i++) {INL(dev, DE4X5_BMR); udelay(10000);}\
+ udelay(1000);\
+}
+
+#define START_DE4X5(dev) {\
+ s32 omr; \
+ omr = INL(dev, DE4X5_OMR);\
+ omr |= OMR_ST | OMR_SR;\
+ OUTL(dev, omr, DE4X5_OMR); /* Enable the TX and/or RX */\
+}
+
+#define STOP_DE4X5(dev) {\
+ s32 omr; \
+ omr = INL(dev, DE4X5_OMR);\
+ omr &= ~(OMR_ST|OMR_SR);\
+ OUTL(dev, omr, DE4X5_OMR); /* Disable the TX and/or RX */ \
+}
+
+#define NUM_RX_DESC PKTBUFSRX
+#define NUM_TX_DESC 1 /* Number of TX descriptors */
+#define RX_BUFF_SZ PKTSIZE_ALIGN
+
+#define TOUT_LOOP 1000000
+
+#define SETUP_FRAME_LEN 192
+#define ETH_ALEN 6
+
+
+struct de4x5_desc {
+ volatile s32 status;
+ u32 des1;
+ u32 buf;
+ u32 next;
+};
+
+static struct de4x5_desc rx_ring[NUM_RX_DESC]; /* RX descriptor ring */
+static struct de4x5_desc tx_ring[NUM_TX_DESC]; /* TX descriptor ring */
+static int rx_new; /* RX descriptor ring pointer */
+static int tx_new; /* TX descriptor ring pointer */
+
+static char rxRingSize;
+static char txRingSize;
+
+static void sendto_srom(struct eth_device* dev, u_int command, u_long addr);
+static int getfrom_srom(struct eth_device* dev, u_long addr);
+static int do_eeprom_cmd(struct eth_device *dev, u_long ioaddr, int cmd, int cmd_len);
+static int do_read_eeprom(struct eth_device *dev, u_long ioaddr, int location, int addr_len);
+static int read_srom(struct eth_device *dev, u_long ioaddr, int index);
+#ifdef UPDATE_SROM
+static int write_srom(struct eth_device *dev, u_long ioaddr, int index, int new_value);
+static void update_srom(struct eth_device *dev, bd_t *bis);
+#endif
+static void read_hw_addr(struct eth_device* dev, bd_t * bis);
+static void send_setup_frame(struct eth_device* dev, bd_t * bis);
+
+static int dc21x4x_init(struct eth_device* dev, bd_t* bis);
+static int dc21x4x_send(struct eth_device* dev, volatile void *packet, int length);
+static int dc21x4x_recv(struct eth_device* dev);
+static void dc21x4x_halt(struct eth_device* dev);
+#ifdef CONFIG_TULIP_SELECT_MEDIA
+extern void dc21x4x_select_media(struct eth_device* dev);
+#endif
+
+#define phys_to_bus(a) pci_phys_to_mem((pci_dev_t)dev->priv, a)
+
+static int INL(struct eth_device* dev, u_long addr)
+{
+ return le32_to_cpu(*(volatile u_long *)(addr + dev->iobase));
+}
+
+static void OUTL(struct eth_device* dev, int command, u_long addr)
+{
+ *(volatile u_long *)(addr + dev->iobase) = cpu_to_le32(command);
+}
+
+static struct pci_device_id supported[] = {
+ { PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_TULIP_FAST },
+ { PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_21142 },
+ { }
+};
+
+int dc21x4x_initialize(bd_t *bis)
+{
+ int idx=0;
+ int card_number = 0;
+ int cfrv;
+ unsigned char timer;
+ pci_dev_t devbusfn;
+ unsigned int iobase;
+ unsigned short status;
+ struct eth_device* dev;
+
+ while(1) {
+ devbusfn = pci_find_devices(supported, idx++);
+ if (devbusfn == -1) {
+ break;
+ }
+
+ /* Get the chip configuration revision register. */
+ pci_read_config_dword(devbusfn, PCI_REVISION_ID, &cfrv);
+
+ if ((cfrv & CFRV_RN) < DC2114x_BRK ) {
+ printf("Error: The chip is not DC21143.\n");
+ continue;
+ }
+
+ pci_read_config_word(devbusfn, PCI_COMMAND, &status);
+ status |=
+#ifdef CONFIG_TULIP_USE_IO
+ PCI_COMMAND_IO |
+#else
+ PCI_COMMAND_MEMORY |
+#endif
+ PCI_COMMAND_MASTER;
+ pci_write_config_word(devbusfn, PCI_COMMAND, status);
+
+ pci_read_config_word(devbusfn, PCI_COMMAND, &status);
+ if (!(status & PCI_COMMAND_IO)) {
+ printf("Error: Can not enable I/O access.\n");
+ continue;
+ }
+
+ if (!(status & PCI_COMMAND_IO)) {
+ printf("Error: Can not enable I/O access.\n");
+ continue;
+ }
+
+ if (!(status & PCI_COMMAND_MASTER)) {
+ printf("Error: Can not enable Bus Mastering.\n");
+ continue;
+ }
+
+ /* Check the latency timer for values >= 0x60. */
+ pci_read_config_byte(devbusfn, PCI_LATENCY_TIMER, &timer);
+
+ if (timer < 0x60) {
+ pci_write_config_byte(devbusfn, PCI_LATENCY_TIMER, 0x60);
+ }
+
+#ifdef CONFIG_TULIP_USE_IO
+ /* read BAR for memory space access */
+ pci_read_config_dword(devbusfn, PCI_BASE_ADDRESS_0, &iobase);
+ iobase &= PCI_BASE_ADDRESS_IO_MASK;
+#else
+ /* read BAR for memory space access */
+ pci_read_config_dword(devbusfn, PCI_BASE_ADDRESS_1, &iobase);
+ iobase &= PCI_BASE_ADDRESS_MEM_MASK;
+#endif
+
+#ifdef DEBUG
+ printf("dc21x4x: DEC 21142 PCI Device @0x%x\n", iobase);
+#endif
+
+ dev = (struct eth_device*) malloc(sizeof *dev);
+
+ sprintf(dev->name, "dc21x4x#%d", card_number);
+#ifdef CONFIG_TULIP_USE_IO
+ dev->iobase = pci_io_to_phys(devbusfn, iobase);
+#else
+ dev->iobase = pci_mem_to_phys(devbusfn, iobase);
+#endif
+ dev->priv = (void*) devbusfn;
+ dev->init = dc21x4x_init;
+ dev->halt = dc21x4x_halt;
+ dev->send = dc21x4x_send;
+ dev->recv = dc21x4x_recv;
+
+ /* Ensure we're not sleeping. */
+ pci_write_config_byte(devbusfn, PCI_CFDA_PSM, WAKEUP);
+
+ udelay(10 * 1000);
+
+ read_hw_addr(dev, bis);
+
+ eth_register(dev);
+
+ card_number++;
+ }
+
+ return card_number;
+}
+
+static int dc21x4x_init(struct eth_device* dev, bd_t* bis)
+{
+ int i;
+ int devbusfn = (int) dev->priv;
+
+ /* Ensure we're not sleeping. */
+ pci_write_config_byte(devbusfn, PCI_CFDA_PSM, WAKEUP);
+
+ RESET_DE4X5(dev);
+
+ if ((INL(dev, DE4X5_STS) & (STS_TS | STS_RS)) != 0) {
+ printf("Error: Cannot reset ethernet controller.\n");
+ return 0;
+ }
+
+#ifdef CONFIG_TULIP_SELECT_MEDIA
+ dc21x4x_select_media(dev);
+#else
+ OUTL(dev, OMR_SDP | OMR_PS | OMR_PM, DE4X5_OMR);
+#endif
+
+ for (i = 0; i < NUM_RX_DESC; i++) {
+ rx_ring[i].status = cpu_to_le32(R_OWN);
+ rx_ring[i].des1 = cpu_to_le32(RX_BUFF_SZ);
+ rx_ring[i].buf = cpu_to_le32(phys_to_bus((u32) NetRxPackets[i]));
+ rx_ring[i].next = 0;
+ }
+
+ for (i=0; i < NUM_TX_DESC; i++) {
+ tx_ring[i].status = 0;
+ tx_ring[i].des1 = 0;
+ tx_ring[i].buf = 0;
+ tx_ring[i].next = 0;
+ }
+
+ rxRingSize = NUM_RX_DESC;
+ txRingSize = NUM_TX_DESC;
+
+ /* Write the end of list marker to the descriptor lists. */
+ rx_ring[rxRingSize - 1].des1 |= cpu_to_le32(RD_RER);
+ tx_ring[txRingSize - 1].des1 |= cpu_to_le32(TD_TER);
+
+ /* Tell the adapter where the TX/RX rings are located. */
+ OUTL(dev, phys_to_bus((u32) &rx_ring), DE4X5_RRBA);
+ OUTL(dev, phys_to_bus((u32) &tx_ring), DE4X5_TRBA);
+
+ START_DE4X5(dev);
+
+ tx_new = 0;
+ rx_new = 0;
+
+ send_setup_frame(dev, bis);
+
+ return 1;
+}
+
+static int dc21x4x_send(struct eth_device* dev, volatile void *packet, int length)
+{
+ int status = -1;
+ int i;
+
+ if (length <= 0) {
+ printf("%s: bad packet size: %d\n", dev->name, length);
+ goto Done;
+ }
+
+ for(i = 0; tx_ring[tx_new].status & cpu_to_le32(T_OWN); i++) {
+ if (i >= TOUT_LOOP) {
+ printf("%s: tx error buffer not ready\n", dev->name);
+ goto Done;
+ }
+ }
+
+ tx_ring[tx_new].buf = cpu_to_le32(phys_to_bus((u32) packet));
+ tx_ring[tx_new].des1 = cpu_to_le32(TD_TER | TD_LS | TD_FS | length);
+ tx_ring[tx_new].status = cpu_to_le32(T_OWN);
+
+ OUTL(dev, POLL_DEMAND, DE4X5_TPD);
+
+ for(i = 0; tx_ring[tx_new].status & cpu_to_le32(T_OWN); i++) {
+ if (i >= TOUT_LOOP) {
+ printf(".%s: tx buffer not ready\n", dev->name);
+ goto Done;
+ }
+ }
+
+ if (le32_to_cpu(tx_ring[tx_new].status) & TD_ES) {
+#if 0 /* test-only */
+ printf("TX error status = 0x%08X\n",
+ le32_to_cpu(tx_ring[tx_new].status));
+#endif
+ goto Done;
+ }
+
+ status = length;
+
+ Done:
+ return status;
+}
+
+static int dc21x4x_recv(struct eth_device* dev)
+{
+ s32 status;
+ int length = 0;
+
+ for ( ; ; ) {
+ status = (s32)le32_to_cpu(rx_ring[rx_new].status);
+
+ if (status & R_OWN) {
+ break;
+ }
+
+ if (status & RD_LS) {
+ /* Valid frame status.
+ */
+ if (status & RD_ES) {
+
+ /* There was an error.
+ */
+ printf("RX error status = 0x%08X\n", status);
+ } else {
+ /* A valid frame received.
+ */
+ length = (le32_to_cpu(rx_ring[rx_new].status) >> 16);
+
+ /* Pass the packet up to the protocol
+ * layers.
+ */
+ NetReceive(NetRxPackets[rx_new], length - 4);
+ }
+
+ /* Change buffer ownership for this frame, back
+ * to the adapter.
+ */
+ rx_ring[rx_new].status = cpu_to_le32(R_OWN);
+ }
+
+ /* Update entry information.
+ */
+ rx_new = (rx_new + 1) % rxRingSize;
+ }
+
+ return length;
+}
+
+static void dc21x4x_halt(struct eth_device* dev)
+{
+ int devbusfn = (int) dev->priv;
+
+ STOP_DE4X5(dev);
+ OUTL(dev, 0, DE4X5_SICR);
+
+ pci_write_config_byte(devbusfn, PCI_CFDA_PSM, SLEEP);
+}
+
+static void send_setup_frame(struct eth_device* dev, bd_t *bis)
+{
+ int i;
+ char setup_frame[SETUP_FRAME_LEN];
+ char *pa = &setup_frame[0];
+
+ memset(pa, 0xff, SETUP_FRAME_LEN);
+
+ for (i = 0; i < ETH_ALEN; i++) {
+ *(pa + (i & 1)) = dev->enetaddr[i];
+ if (i & 0x01) {
+ pa += 4;
+ }
+ }
+
+ for(i = 0; tx_ring[tx_new].status & cpu_to_le32(T_OWN); i++) {
+ if (i >= TOUT_LOOP) {
+ printf("%s: tx error buffer not ready\n", dev->name);
+ goto Done;
+ }
+ }
+
+ tx_ring[tx_new].buf = cpu_to_le32(phys_to_bus((u32) &setup_frame[0]));
+ tx_ring[tx_new].des1 = cpu_to_le32(TD_TER | TD_SET| SETUP_FRAME_LEN);
+ tx_ring[tx_new].status = cpu_to_le32(T_OWN);
+
+ OUTL(dev, POLL_DEMAND, DE4X5_TPD);
+
+ for(i = 0; tx_ring[tx_new].status & cpu_to_le32(T_OWN); i++) {
+ if (i >= TOUT_LOOP) {
+ printf("%s: tx buffer not ready\n", dev->name);
+ goto Done;
+ }
+ }
+
+ if (le32_to_cpu(tx_ring[tx_new].status) != 0x7FFFFFFF) {
+ printf("TX error status2 = 0x%08X\n", le32_to_cpu(tx_ring[tx_new].status));
+ }
+Done:
+ return;
+}
+
+/* SROM Read and write routines.
+ */
+
+static void
+sendto_srom(struct eth_device* dev, u_int command, u_long addr)
+{
+ OUTL(dev, command, addr);
+ udelay(1);
+}
+
+static int
+getfrom_srom(struct eth_device* dev, u_long addr)
+{
+ s32 tmp;
+
+ tmp = INL(dev, addr);
+ udelay(1);
+
+ return tmp;
+}
+
+/* Note: this routine returns extra data bits for size detection. */
+static int do_read_eeprom(struct eth_device *dev, u_long ioaddr, int location, int addr_len)
+{
+ int i;
+ unsigned retval = 0;
+ int read_cmd = location | (SROM_READ_CMD << addr_len);
+
+ sendto_srom(dev, SROM_RD | SROM_SR, ioaddr);
+ sendto_srom(dev, SROM_RD | SROM_SR | DT_CS, ioaddr);
+
+#ifdef DEBUG_SROM
+ printf(" EEPROM read at %d ", location);
+#endif
+
+ /* Shift the read command bits out. */
+ for (i = 4 + addr_len; i >= 0; i--) {
+ short dataval = (read_cmd & (1 << i)) ? EE_DATA_WRITE : 0;
+ sendto_srom(dev, SROM_RD | SROM_SR | DT_CS | dataval, ioaddr);
+ udelay(10);
+ sendto_srom(dev, SROM_RD | SROM_SR | DT_CS | dataval | DT_CLK, ioaddr);
+ udelay(10);
+#ifdef DEBUG_SROM2
+ printf("%X", getfrom_srom(dev, ioaddr) & 15);
+#endif
+ retval = (retval << 1) | ((getfrom_srom(dev, ioaddr) & EE_DATA_READ) ? 1 : 0);
+ }
+
+ sendto_srom(dev, SROM_RD | SROM_SR | DT_CS, ioaddr);
+
+#ifdef DEBUG_SROM2
+ printf(" :%X:", getfrom_srom(dev, ioaddr) & 15);
+#endif
+
+ for (i = 16; i > 0; i--) {
+ sendto_srom(dev, SROM_RD | SROM_SR | DT_CS | DT_CLK, ioaddr);
+ udelay(10);
+#ifdef DEBUG_SROM2
+ printf("%X", getfrom_srom(dev, ioaddr) & 15);
+#endif
+ retval = (retval << 1) | ((getfrom_srom(dev, ioaddr) & EE_DATA_READ) ? 1 : 0);
+ sendto_srom(dev, SROM_RD | SROM_SR | DT_CS, ioaddr);
+ udelay(10);
+ }
+
+ /* Terminate the EEPROM access. */
+ sendto_srom(dev, SROM_RD | SROM_SR, ioaddr);
+
+#ifdef DEBUG_SROM2
+ printf(" EEPROM value at %d is %5.5x.\n", location, retval);
+#endif
+
+ return retval;
+}
+
+/* This executes a generic EEPROM command, typically a write or write enable.
+ It returns the data output from the EEPROM, and thus may also be used for
+ reads. */
+static int do_eeprom_cmd(struct eth_device *dev, u_long ioaddr, int cmd, int cmd_len)
+{
+ unsigned retval = 0;
+
+#ifdef DEBUG_SROM
+ printf(" EEPROM op 0x%x: ", cmd);
+#endif
+
+ sendto_srom(dev,SROM_RD | SROM_SR | DT_CS | DT_CLK, ioaddr);
+
+ /* Shift the command bits out. */
+ do {
+ short dataval = (cmd & (1 << cmd_len)) ? EE_WRITE_1 : EE_WRITE_0;
+ sendto_srom(dev,dataval, ioaddr);
+ udelay(10);
+
+#ifdef DEBUG_SROM2
+ printf("%X", getfrom_srom(dev,ioaddr) & 15);
+#endif
+
+ sendto_srom(dev,dataval | DT_CLK, ioaddr);
+ udelay(10);
+ retval = (retval << 1) | ((getfrom_srom(dev,ioaddr) & EE_DATA_READ) ? 1 : 0);
+ } while (--cmd_len >= 0);
+ sendto_srom(dev,SROM_RD | SROM_SR | DT_CS, ioaddr);
+
+ /* Terminate the EEPROM access. */
+ sendto_srom(dev,SROM_RD | SROM_SR, ioaddr);
+
+#ifdef DEBUG_SROM
+ printf(" EEPROM result is 0x%5.5x.\n", retval);
+#endif
+
+ return retval;
+}
+
+static int read_srom(struct eth_device *dev, u_long ioaddr, int index)
+{
+ int ee_addr_size = do_read_eeprom(dev, ioaddr, 0xff, 8) & 0x40000 ? 8 : 6;
+
+ return do_eeprom_cmd(dev, ioaddr,
+ (((SROM_READ_CMD << ee_addr_size) | index) << 16)
+ | 0xffff, 3 + ee_addr_size + 16);
+}
+
+#ifdef UPDATE_SROM
+static int write_srom(struct eth_device *dev, u_long ioaddr, int index, int new_value)
+{
+ int ee_addr_size = do_read_eeprom(dev, ioaddr, 0xff, 8) & 0x40000 ? 8 : 6;
+ int i;
+ unsigned short newval;
+
+ udelay(10*1000); /* test-only */
+
+#ifdef DEBUG_SROM
+ printf("ee_addr_size=%d.\n", ee_addr_size);
+ printf("Writing new entry 0x%4.4x to offset %d.\n", new_value, index);
+#endif
+
+ /* Enable programming modes. */
+ do_eeprom_cmd(dev, ioaddr, (0x4f << (ee_addr_size-4)), 3+ee_addr_size);
+
+ /* Do the actual write. */
+ do_eeprom_cmd(dev, ioaddr,
+ (((SROM_WRITE_CMD<<ee_addr_size)|index) << 16) | new_value,
+ 3 + ee_addr_size + 16);
+
+ /* Poll for write finished. */
+ sendto_srom(dev, SROM_RD | SROM_SR | DT_CS, ioaddr);
+ for (i = 0; i < 10000; i++) /* Typical 2000 ticks */
+ if (getfrom_srom(dev, ioaddr) & EE_DATA_READ)
+ break;
+
+#ifdef DEBUG_SROM
+ printf(" Write finished after %d ticks.\n", i);
+#endif
+
+ /* Disable programming. */
+ do_eeprom_cmd(dev, ioaddr, (0x40 << (ee_addr_size-4)), 3 + ee_addr_size);
+
+ /* And read the result. */
+ newval = do_eeprom_cmd(dev, ioaddr,
+ (((SROM_READ_CMD<<ee_addr_size)|index) << 16)
+ | 0xffff, 3 + ee_addr_size + 16);
+#ifdef DEBUG_SROM
+ printf(" New value at offset %d is %4.4x.\n", index, newval);
+#endif
+ return 1;
+}
+#endif
+
+static void read_hw_addr(struct eth_device *dev, bd_t *bis)
+{
+ u_short tmp, *p = (short *)(&dev->enetaddr[0]);
+ int i, j = 0;
+
+ for (i = 0; i < (ETH_ALEN >> 1); i++) {
+ tmp = read_srom(dev, DE4X5_APROM, ((SROM_HWADD >> 1) + i));
+ *p = le16_to_cpu(tmp);
+ j += *p++;
+ }
+
+ if ((j == 0) || (j == 0x2fffd)) {
+ memset (dev->enetaddr, 0, ETH_ALEN);
+#ifdef DEBUG
+ printf("Warning: can't read HW address from SROM.\n");
+#endif
+ goto Done;
+ }
+
+ return;
+
+Done:
+#ifdef UPDATE_SROM
+ update_srom(dev, bis);
+#endif
+ return;
+}
+
+#ifdef UPDATE_SROM
+static void update_srom(struct eth_device *dev, bd_t *bis)
+{
+ int i;
+ static unsigned short eeprom[0x40] = {
+ 0x140b, 0x6610, 0x0000, 0x0000, /* 00 */
+ 0x0000, 0x0000, 0x0000, 0x0000, /* 04 */
+ 0x00a3, 0x0103, 0x0000, 0x0000, /* 08 */
+ 0x0000, 0x1f00, 0x0000, 0x0000, /* 0c */
+ 0x0108, 0x038d, 0x0000, 0x0000, /* 10 */
+ 0xe078, 0x0001, 0x0040, 0x0018, /* 14 */
+ 0x0000, 0x0000, 0x0000, 0x0000, /* 18 */
+ 0x0000, 0x0000, 0x0000, 0x0000, /* 1c */
+ 0x0000, 0x0000, 0x0000, 0x0000, /* 20 */
+ 0x0000, 0x0000, 0x0000, 0x0000, /* 24 */
+ 0x0000, 0x0000, 0x0000, 0x0000, /* 28 */
+ 0x0000, 0x0000, 0x0000, 0x0000, /* 2c */
+ 0x0000, 0x0000, 0x0000, 0x0000, /* 30 */
+ 0x0000, 0x0000, 0x0000, 0x0000, /* 34 */
+ 0x0000, 0x0000, 0x0000, 0x0000, /* 38 */
+ 0x0000, 0x0000, 0x0000, 0x4e07, /* 3c */
+ };
+
+ /* Ethernet Addr... */
+ eeprom[0x0a] = ((bis->bi_enetaddr[1] & 0xff) << 8) | (bis->bi_enetaddr[0] & 0xff);
+ eeprom[0x0b] = ((bis->bi_enetaddr[3] & 0xff) << 8) | (bis->bi_enetaddr[2] & 0xff);
+ eeprom[0x0c] = ((bis->bi_enetaddr[5] & 0xff) << 8) | (bis->bi_enetaddr[4] & 0xff);
+
+ for (i=0; i<0x40; i++)
+ {
+ write_srom(dev, DE4X5_APROM, i, eeprom[i]);
+ }
+}
+#endif
+
+#endif
--- /dev/null
+/*
+ * (C) Copyright 2002 ELTEC Elektronik AG
+ * Frank Gottschling <fgottschling@eltec.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
+ */
+
+/* i8042.c - Intel 8042 keyboard driver routines */
+
+/* includes */
+
+#include <common.h>
+
+#ifdef CONFIG_I8042_KBD
+
+#include <i8042.h>
+
+/* defines */
+
+#ifdef CONFIG_CONSOLE_CURSOR
+extern void console_cursor (int state);
+static int blinkCount = CFG_CONSOLE_BLINK_COUNT;
+static int cursor_state = 0;
+#endif
+
+/* locals */
+
+static int kbd_input = -1; /* no input yet */
+static int kbd_mapping = KBD_US; /* default US keyboard */
+static int kbd_flags = NORMAL; /* after reset */
+static int kbd_state = 0; /* unshift code */
+
+static void kbd_conv_char (unsigned char scan_code);
+static void kbd_led_set (void);
+static void kbd_normal (unsigned char scan_code);
+static void kbd_shift (unsigned char scan_code);
+static void kbd_ctrl (unsigned char scan_code);
+static void kbd_num (unsigned char scan_code);
+static void kbd_caps (unsigned char scan_code);
+static void kbd_scroll (unsigned char scan_code);
+static void kbd_alt (unsigned char scan_code);
+static int kbd_input_empty (void);
+static int kbd_reset (void);
+
+static unsigned char kbd_fct_map [144] =
+ { /* kbd_fct_map table for scan code */
+ 0, AS, AS, AS, AS, AS, AS, AS, /* scan 0- 7 */
+ AS, AS, AS, AS, AS, AS, AS, AS, /* scan 8- F */
+ AS, AS, AS, AS, AS, AS, AS, AS, /* scan 10-17 */
+ AS, AS, AS, AS, AS, CN, AS, AS, /* scan 18-1F */
+ AS, AS, AS, AS, AS, AS, AS, AS, /* scan 20-27 */
+ AS, AS, SH, AS, AS, AS, AS, AS, /* scan 28-2F */
+ AS, AS, AS, AS, AS, AS, SH, AS, /* scan 30-37 */
+ AS, AS, CP, 0, 0, 0, 0, 0, /* scan 38-3F */
+ 0, 0, 0, 0, 0, NM, ST, ES, /* scan 40-47 */
+ ES, ES, ES, ES, ES, ES, ES, ES, /* scan 48-4F */
+ ES, ES, ES, ES, 0, 0, AS, 0, /* scan 50-57 */
+ 0, 0, 0, 0, 0, 0, 0, 0, /* scan 58-5F */
+ 0, 0, 0, 0, 0, 0, 0, 0, /* scan 60-67 */
+ 0, 0, 0, 0, 0, 0, 0, 0, /* scan 68-6F */
+ AS, 0, 0, AS, 0, 0, AS, 0, /* scan 70-77 */
+ 0, AS, 0, 0, 0, AS, 0, 0, /* scan 78-7F */
+ AS, CN, AS, AS, AK, ST, EX, EX, /* enhanced */
+ AS, EX, EX, AS, EX, AS, EX, EX /* enhanced */
+ };
+
+static unsigned char kbd_key_map [2][5][144] =
+ {
+ { /* US keyboard */
+ { /* unshift code */
+ 0, 0x1b, '1', '2', '3', '4', '5', '6', /* scan 0- 7 */
+ '7', '8', '9', '0', '-', '=', 0x08, '\t', /* scan 8- F */
+ 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', /* scan 10-17 */
+ 'o', 'p', '[', ']', '\r', CN, 'a', 's', /* scan 18-1F */
+ 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', /* scan 20-27 */
+ '\'', '`', SH, '\\', 'z', 'x', 'c', 'v', /* scan 28-2F */
+ 'b', 'n', 'm', ',', '.', '/', SH, '*', /* scan 30-37 */
+ ' ', ' ', CP, 0, 0, 0, 0, 0, /* scan 38-3F */
+ 0, 0, 0, 0, 0, NM, ST, '7', /* scan 40-47 */
+ '8', '9', '-', '4', '5', '6', '+', '1', /* scan 48-4F */
+ '2', '3', '0', '.', 0, 0, 0, 0, /* scan 50-57 */
+ 0, 0, 0, 0, 0, 0, 0, 0, /* scan 58-5F */
+ 0, 0, 0, 0, 0, 0, 0, 0, /* scan 60-67 */
+ 0, 0, 0, 0, 0, 0, 0, 0, /* scan 68-6F */
+ 0, 0, 0, 0, 0, 0, 0, 0, /* scan 70-77 */
+ 0, 0, 0, 0, 0, 0, 0, 0, /* scan 78-7F */
+ '\r', CN, '/', '*', ' ', ST, 'F', 'A', /* extended */
+ 0, 'D', 'C', 0, 'B', 0, '@', 'P' /* extended */
+ },
+ { /* shift code */
+ 0, 0x1b, '!', '@', '#', '$', '%', '^', /* scan 0- 7 */
+ '&', '*', '(', ')', '_', '+', 0x08, '\t', /* scan 8- F */
+ 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', /* scan 10-17 */
+ 'O', 'P', '{', '}', '\r', CN, 'A', 'S', /* scan 18-1F */
+ 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', /* scan 20-27 */
+ '"', '~', SH, '|', 'Z', 'X', 'C', 'V', /* scan 28-2F */
+ 'B', 'N', 'M', '<', '>', '?', SH, '*', /* scan 30-37 */
+ ' ', ' ', CP, 0, 0, 0, 0, 0, /* scan 38-3F */
+ 0, 0, 0, 0, 0, NM, ST, '7', /* scan 40-47 */
+ '8', '9', '-', '4', '5', '6', '+', '1', /* scan 48-4F */
+ '2', '3', '0', '.', 0, 0, 0, 0, /* scan 50-57 */
+ 0, 0, 0, 0, 0, 0, 0, 0, /* scan 58-5F */
+ 0, 0, 0, 0, 0, 0, 0, 0, /* scan 60-67 */
+ 0, 0, 0, 0, 0, 0, 0, 0, /* scan 68-6F */
+ 0, 0, 0, 0, 0, 0, 0, 0, /* scan 70-77 */
+ 0, 0, 0, 0, 0, 0, 0, 0, /* scan 78-7F */
+ '\r', CN, '/', '*', ' ', ST, 'F', 'A', /* extended */
+ 0, 'D', 'C', 0, 'B', 0, '@', 'P' /* extended */
+ },
+ { /* control code */
+ 0xff, 0x1b, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, /* scan 0- 7 */
+ 0x1e, 0xff, 0xff, 0xff, 0x1f, 0xff, 0xff, '\t', /* scan 8- F */
+ 0x11, 0x17, 0x05, 0x12, 0x14, 0x19, 0x15, 0x09, /* scan 10-17 */
+ 0x0f, 0x10, 0x1b, 0x1d, '\r', CN, 0x01, 0x13, /* scan 18-1F */
+ 0x04, 0x06, 0x07, 0x08, 0x0a, 0x0b, 0x0c, 0xff, /* scan 20-27 */
+ 0xff, 0x1c, SH, 0xff, 0x1a, 0x18, 0x03, 0x16, /* scan 28-2F */
+ 0x02, 0x0e, 0x0d, 0xff, 0xff, 0xff, SH, 0xff, /* scan 30-37 */
+ 0xff, 0xff, CP, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 38-3F */
+ 0xff, 0xff, 0xff, 0xff, 0xff, NM, ST, 0xff, /* scan 40-47 */
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 48-4F */
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 50-57 */
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 58-5F */
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 60-67 */
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 68-6F */
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 70-77 */
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 78-7F */
+ '\r', CN, '/', '*', ' ', ST, 0xff, 0xff, /* extended */
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff /* extended */
+ },
+ { /* non numeric code */
+ 0, 0x1b, '1', '2', '3', '4', '5', '6', /* scan 0- 7 */
+ '7', '8', '9', '0', '-', '=', 0x08, '\t', /* scan 8- F */
+ 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', /* scan 10-17 */
+ 'o', 'p', '[', ']', '\r', CN, 'a', 's', /* scan 18-1F */
+ 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', /* scan 20-27 */
+ '\'', '`', SH, '\\', 'z', 'x', 'c', 'v', /* scan 28-2F */
+ 'b', 'n', 'm', ',', '.', '/', SH, '*', /* scan 30-37 */
+ ' ', ' ', CP, 0, 0, 0, 0, 0, /* scan 38-3F */
+ 0, 0, 0, 0, 0, NM, ST, 'w', /* scan 40-47 */
+ 'x', 'y', 'l', 't', 'u', 'v', 'm', 'q', /* scan 48-4F */
+ 'r', 's', 'p', 'n', 0, 0, 0, 0, /* scan 50-57 */
+ 0, 0, 0, 0, 0, 0, 0, 0, /* scan 58-5F */
+ 0, 0, 0, 0, 0, 0, 0, 0, /* scan 60-67 */
+ 0, 0, 0, 0, 0, 0, 0, 0, /* scan 68-6F */
+ 0, 0, 0, 0, 0, 0, 0, 0, /* scan 70-77 */
+ 0, 0, 0, 0, 0, 0, 0, 0, /* scan 78-7F */
+ '\r', CN, '/', '*', ' ', ST, 'F', 'A', /* extended */
+ 0, 'D', 'C', 0, 'B', 0, '@', 'P' /* extended */
+ },
+ { /* right alt mode - not used in US keyboard */
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 0 - 7 */
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 8 - F */
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 10 -17 */
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 18 -1F */
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 20 -27 */
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 28 -2F */
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 30 -37 */
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 38 -3F */
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 40 -47 */
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 48 -4F */
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 50 -57 */
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 58 -5F */
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 60 -67 */
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 68 -6F */
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 70 -77 */
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 78 -7F */
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* extended */
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff /* extended */
+ }
+ },
+ { /* german keyboard */
+ { /* unshift code */
+ 0, 0x1b, '1', '2', '3', '4', '5', '6', /* scan 0- 7 */
+ '7', '8', '9', '0', 0xe1, '\'', 0x08, '\t', /* scan 8- F */
+ 'q', 'w', 'e', 'r', 't', 'z', 'u', 'i', /* scan 10-17 */
+ 'o', 'p', 0x81, '+', '\r', CN, 'a', 's', /* scan 18-1F */
+ 'd', 'f', 'g', 'h', 'j', 'k', 'l', 0x94, /* scan 20-27 */
+ 0x84, '^', SH, '#', 'y', 'x', 'c', 'v', /* scan 28-2F */
+ 'b', 'n', 'm', ',', '.', '-', SH, '*', /* scan 30-37 */
+ ' ', ' ', CP, 0, 0, 0, 0, 0, /* scan 38-3F */
+ 0, 0, 0, 0, 0, NM, ST, '7', /* scan 40-47 */
+ '8', '9', '-', '4', '5', '6', '+', '1', /* scan 48-4F */
+ '2', '3', '0', ',', 0, 0, '<', 0, /* scan 50-57 */
+ 0, 0, 0, 0, 0, 0, 0, 0, /* scan 58-5F */
+ 0, 0, 0, 0, 0, 0, 0, 0, /* scan 60-67 */
+ 0, 0, 0, 0, 0, 0, 0, 0, /* scan 68-6F */
+ 0, 0, 0, 0, 0, 0, 0, 0, /* scan 70-77 */
+ 0, 0, 0, 0, 0, 0, 0, 0, /* scan 78-7F */
+ '\r', CN, '/', '*', ' ', ST, 'F', 'A', /* extended */
+ 0, 'D', 'C', 0, 'B', 0, '@', 'P' /* extended */
+ },
+ { /* shift code */
+ 0, 0x1b, '!', '"', 0x15, '$', '%', '&', /* scan 0- 7 */
+ '/', '(', ')', '=', '?', '`', 0x08, '\t', /* scan 8- F */
+ 'Q', 'W', 'E', 'R', 'T', 'Z', 'U', 'I', /* scan 10-17 */
+ 'O', 'P', 0x9a, '*', '\r', CN, 'A', 'S', /* scan 18-1F */
+ 'D', 'F', 'G', 'H', 'J', 'K', 'L', 0x99, /* scan 20-27 */
+ 0x8e, 0xf8, SH, '\'', 'Y', 'X', 'C', 'V', /* scan 28-2F */
+ 'B', 'N', 'M', ';', ':', '_', SH, '*', /* scan 30-37 */
+ ' ', ' ', CP, 0, 0, 0, 0, 0, /* scan 38-3F */
+ 0, 0, 0, 0, 0, NM, ST, '7', /* scan 40-47 */
+ '8', '9', '-', '4', '5', '6', '+', '1', /* scan 48-4F */
+ '2', '3', '0', ',', 0, 0, '>', 0, /* scan 50-57 */
+ 0, 0, 0, 0, 0, 0, 0, 0, /* scan 58-5F */
+ 0, 0, 0, 0, 0, 0, 0, 0, /* scan 60-67 */
+ 0, 0, 0, 0, 0, 0, 0, 0, /* scan 68-6F */
+ 0, 0, 0, 0, 0, 0, 0, 0, /* scan 70-77 */
+ 0, 0, 0, 0, 0, 0, 0, 0, /* scan 78-7F */
+ '\r', CN, '/', '*', ' ', ST, 'F', 'A', /* extended */
+ 0, 'D', 'C', 0, 'B', 0, '@', 'P' /* extended */
+ },
+ { /* control code */
+ 0xff, 0x1b, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, /* scan 0- 7 */
+ 0x1e, 0xff, 0xff, 0xff, 0x1f, 0xff, 0xff, '\t', /* scan 8- F */
+ 0x11, 0x17, 0x05, 0x12, 0x14, 0x19, 0x15, 0x09, /* scan 10-17 */
+ 0x0f, 0x10, 0x1b, 0x1d, '\r', CN, 0x01, 0x13, /* scan 18-1F */
+ 0x04, 0x06, 0x07, 0x08, 0x0a, 0x0b, 0x0c, 0xff, /* scan 20-27 */
+ 0xff, 0x1c, SH, 0xff, 0x1a, 0x18, 0x03, 0x16, /* scan 28-2F */
+ 0x02, 0x0e, 0x0d, 0xff, 0xff, 0xff, SH, 0xff, /* scan 30-37 */
+ 0xff, 0xff, CP, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 38-3F */
+ 0xff, 0xff, 0xff, 0xff, 0xff, NM, ST, 0xff, /* scan 40-47 */
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 48-4F */
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 50-57 */
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 58-5F */
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 60-67 */
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 68-6F */
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 70-77 */
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 78-7F */
+ '\r', CN, '/', '*', ' ', ST, 0xff, 0xff, /* extended */
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff /* extended */
+ },
+ { /* non numeric code */
+ 0, 0x1b, '1', '2', '3', '4', '5', '6', /* scan 0- 7 */
+ '7', '8', '9', '0', 0xe1, '\'', 0x08, '\t', /* scan 8- F */
+ 'q', 'w', 'e', 'r', 't', 'z', 'u', 'i', /* scan 10-17 */
+ 'o', 'p', 0x81, '+', '\r', CN, 'a', 's', /* scan 18-1F */
+ 'd', 'f', 'g', 'h', 'j', 'k', 'l', 0x94, /* scan 20-27 */
+ 0x84, '^', SH, 0, 'y', 'x', 'c', 'v', /* scan 28-2F */
+ 'b', 'n', 'm', ',', '.', '-', SH, '*', /* scan 30-37 */
+ ' ', ' ', CP, 0, 0, 0, 0, 0, /* scan 38-3F */
+ 0, 0, 0, 0, 0, NM, ST, 'w', /* scan 40-47 */
+ 'x', 'y', 'l', 't', 'u', 'v', 'm', 'q', /* scan 48-4F */
+ 'r', 's', 'p', 'n', 0, 0, '<', 0, /* scan 50-57 */
+ 0, 0, 0, 0, 0, 0, 0, 0, /* scan 58-5F */
+ 0, 0, 0, 0, 0, 0, 0, 0, /* scan 60-67 */
+ 0, 0, 0, 0, 0, 0, 0, 0, /* scan 68-6F */
+ 0, 0, 0, 0, 0, 0, 0, 0, /* scan 70-77 */
+ 0, 0, 0, 0, 0, 0, 0, 0, /* scan 78-7F */
+ '\r', CN, '/', '*', ' ', ST, 'F', 'A', /* extended */
+ 0, 'D', 'C', 0, 'B', 0, '@', 'P' /* extended */
+ },
+ { /* Right alt mode - is used in German keyboard */
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 0 - 7 */
+ '{', '[', ']', '}', '\\', 0xff, 0xff, 0xff, /* scan 8 - F */
+ '@', 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 10 -17 */
+ 0xff, 0xff, 0xff, '~', 0xff, 0xff, 0xff, 0xff, /* scan 18 -1F */
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 20 -27 */
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 28 -2F */
+ 0xff, 0xff, 0xe6, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 30 -37 */
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 38 -3F */
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 40 -47 */
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 48 -4F */
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, '|', 0xff, /* scan 50 -57 */
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 58 -5F */
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 60 -67 */
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 68 -6F */
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 70 -77 */
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 78 -7F */
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* extended */
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff /* extended */
+ }
+ }
+ };
+
+static unsigned char ext_key_map [] =
+ {
+ 0x1c, /* keypad enter */
+ 0x1d, /* right control */
+ 0x35, /* keypad slash */
+ 0x37, /* print screen */
+ 0x38, /* right alt */
+ 0x46, /* break */
+ 0x47, /* editpad home */
+ 0x48, /* editpad up */
+ 0x49, /* editpad pgup */
+ 0x4b, /* editpad left */
+ 0x4d, /* editpad right */
+ 0x4f, /* editpad end */
+ 0x50, /* editpad dn */
+ 0x51, /* editpad pgdn */
+ 0x52, /* editpad ins */
+ 0x53, /* editpad del */
+ 0x00 /* map end */
+ };
+
+/*******************************************************************************
+ *
+ * i8042_kbd_init - reset keyboard and init state flags
+ */
+int i8042_kbd_init (void)
+{
+ int keymap, try;
+ char *penv;
+
+ /* Init keyboard device (default US layout) */
+ keymap = KBD_US;
+ if ((penv = getenv ("keymap")) != NULL)
+ {
+ if (strncmp (penv, "de", 3) == 0)
+ keymap = KBD_GER;
+ }
+
+ for (try = 0; try < KBD_RESET_TRIES; try++)
+ {
+ if (kbd_reset() == 0)
+ {
+ kbd_mapping = keymap;
+ kbd_flags = NORMAL;
+ kbd_state = 0;
+ kbd_led_set();
+ return 0;
+ }
+ }
+ return -1;
+}
+
+
+/*******************************************************************************
+ *
+ * i8042_tstc - test if keyboard input is available
+ * option: cursor blinking if called in a loop
+ */
+int i8042_tstc (void)
+{
+ unsigned char scan_code = 0;
+
+#ifdef CONFIG_CONSOLE_CURSOR
+ if (--blinkCount == 0)
+ {
+ cursor_state ^= 1;
+ console_cursor (cursor_state);
+ blinkCount = CFG_CONSOLE_BLINK_COUNT;
+ udelay (10);
+ }
+#endif
+
+ if ((in8 (I8042_STATUS_REG) & 0x01) == 0)
+ return 0;
+ else
+ {
+ scan_code = in8 (I8042_DATA_REG);
+ if (scan_code == 0xfa)
+ return 0;
+
+ kbd_conv_char(scan_code);
+
+ if (kbd_input != -1)
+ return 1;
+ }
+ return 0;
+}
+
+
+/*******************************************************************************
+ *
+ * i8042_getc - wait till keyboard input is available
+ * option: turn on/off cursor while waiting
+ */
+int i8042_getc (void)
+{
+ int ret_chr;
+ unsigned char scan_code;
+
+ while (kbd_input == -1)
+ {
+ while ((in8 (I8042_STATUS_REG) & 0x01) == 0)
+ {
+#ifdef CONFIG_CONSOLE_CURSOR
+ if (--blinkCount==0)
+ {
+ cursor_state ^= 1;
+ console_cursor (cursor_state);
+ blinkCount = CFG_CONSOLE_BLINK_COUNT;
+ }
+ udelay (10);
+#endif
+ }
+
+ scan_code = in8 (I8042_DATA_REG);
+
+ if (scan_code != 0xfa)
+ kbd_conv_char (scan_code);
+ }
+ ret_chr = kbd_input;
+ kbd_input = -1;
+ return ret_chr;
+}
+
+
+/******************************************************************************/
+
+static void kbd_conv_char (unsigned char scan_code)
+{
+ if (scan_code == 0xe0)
+ {
+ kbd_flags |= EXT;
+ return;
+ }
+
+ /* if high bit of scan_code, set break flag */
+ if (scan_code & 0x80)
+ kbd_flags |= BRK;
+ else
+ kbd_flags &= ~BRK;
+
+ if ((scan_code == 0xe1) || (kbd_flags & E1))
+ {
+ if (scan_code == 0xe1)
+ {
+ kbd_flags ^= BRK; /* reset the break flag */
+ kbd_flags ^= E1; /* bitwise EXOR with E1 flag */
+ }
+ return;
+ }
+
+ scan_code &= 0x7f;
+
+ if (kbd_flags & EXT)
+ {
+ int i;
+
+ kbd_flags ^= EXT;
+ for (i=0; ext_key_map[i]; i++)
+ {
+ if (ext_key_map[i] == scan_code)
+ {
+ scan_code = 0x80 + i;
+ break;
+ }
+ }
+ /* not found ? */
+ if (!ext_key_map[i])
+ return;
+ }
+
+ switch (kbd_fct_map [scan_code])
+ {
+ case AS: kbd_normal (scan_code);
+ break;
+ case SH: kbd_shift (scan_code);
+ break;
+ case CN: kbd_ctrl (scan_code);
+ break;
+ case NM: kbd_num (scan_code);
+ break;
+ case CP: kbd_caps (scan_code);
+ break;
+ case ST: kbd_scroll (scan_code);
+ break;
+ case AK: kbd_alt (scan_code);
+ break;
+ }
+ return;
+}
+
+
+/******************************************************************************/
+
+static void kbd_normal (unsigned char scan_code)
+{
+ unsigned char chr;
+
+ if ((kbd_flags & BRK) == NORMAL)
+ {
+ chr = kbd_key_map [kbd_mapping][kbd_state][scan_code];
+ if ((chr == 0xff) || (chr == 0x00))
+ {
+ return;
+ }
+
+ /* if caps lock convert upper to lower */
+ if (((kbd_flags & CAPS) == CAPS) && (chr >= 'a' && chr <= 'z'))
+ {
+ chr -= 'a' - 'A';
+ }
+ kbd_input = chr;
+ }
+}
+
+
+/******************************************************************************/
+
+static void kbd_shift (unsigned char scan_code)
+{
+ if ((kbd_flags & BRK) == BRK)
+ {
+ kbd_state = AS;
+ kbd_flags &= (~SHIFT);
+ }
+ else
+ {
+ kbd_state = SH;
+ kbd_flags |= SHIFT;
+ }
+}
+
+
+/******************************************************************************/
+
+static void kbd_ctrl (unsigned char scan_code)
+{
+ if ((kbd_flags & BRK) == BRK)
+ {
+ kbd_state = AS;
+ kbd_flags &= (~CTRL);
+ }
+ else
+ {
+ kbd_state = CN;
+ kbd_flags |= CTRL;
+ }
+}
+
+
+/******************************************************************************/
+
+static void kbd_caps (unsigned char scan_code)
+{
+ if ((kbd_flags & BRK) == NORMAL)
+ {
+ kbd_flags ^= CAPS;
+ kbd_led_set (); /* update keyboard LED */
+ }
+}
+
+
+/******************************************************************************/
+
+static void kbd_num (unsigned char scan_code)
+{
+ if ((kbd_flags & BRK) == NORMAL)
+ {
+ kbd_flags ^= NUM;
+ kbd_state = (kbd_flags & NUM) ? AS : NM;
+ kbd_led_set (); /* update keyboard LED */
+ }
+}
+
+
+/******************************************************************************/
+
+static void kbd_scroll (unsigned char scan_code)
+{
+ if ((kbd_flags & BRK) == NORMAL)
+ {
+ kbd_flags ^= STP;
+ kbd_led_set (); /* update keyboard LED */
+ if (kbd_flags & STP)
+ kbd_input = 0x13;
+ else
+ kbd_input = 0x11;
+ }
+}
+
+/******************************************************************************/
+
+static void kbd_alt (unsigned char scan_code)
+{
+ if ((kbd_flags & BRK) == BRK)
+ {
+ kbd_state = AS;
+ kbd_flags &= (~ALT);
+ }
+ else
+ {
+ kbd_state = AK;
+ kbd_flags &= ALT;
+ }
+}
+
+
+/******************************************************************************/
+
+static void kbd_led_set (void)
+{
+ kbd_input_empty();
+ out8 (I8042_DATA_REG, 0xed); /* SET LED command */
+ kbd_input_empty();
+ out8 (I8042_DATA_REG, (kbd_flags & 0x7)); /* LED bits only */
+}
+
+
+/******************************************************************************/
+
+static int kbd_input_empty (void)
+{
+ int kbdTimeout = KBD_TIMEOUT;
+
+ /* wait for input buf empty */
+ while ((in8 (I8042_STATUS_REG) & 0x02) && kbdTimeout--)
+ udelay(1000);
+
+ return kbdTimeout;
+}
+
+/******************************************************************************/
+
+static int kbd_reset (void)
+{
+ if (kbd_input_empty() == 0)
+ return -1;
+
+ out8 (I8042_DATA_REG, 0xff);
+
+ udelay(250000);
+
+ if (kbd_input_empty() == 0)
+ return -1;
+
+ out8 (I8042_DATA_REG, 0x60);
+
+ if (kbd_input_empty() == 0)
+ return -1;
+
+ out8 (I8042_DATA_REG, 0x45);
+
+
+ if (kbd_input_empty() == 0)
+ return -1;
+
+ out8 (I8042_COMMAND_REG, 0xae);
+
+ if (kbd_input_empty() == 0)
+ return -1;
+
+ return 0;
+}
+
+#endif /* CONFIG_I8042_KBD */
--- /dev/null
+/*
+ * (C) Copyright 2000
+ * Rob Taylor, Flying Pig Systems. robt@flyingpig.com.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <config.h>
+
+#ifdef CFG_NS87308
+
+#include <ns87308.h>
+
+void initialise_ns87308 (void)
+{
+#ifdef CFG_NS87308_PS2MOD
+ unsigned char data;
+
+ /*
+ * Switch floppy drive to PS/2 mode.
+ */
+ read_pnp_config(SUPOERIO_CONF1, &data);
+ data &= 0xFB;
+ write_pnp_config(SUPOERIO_CONF1, data);
+#endif
+
+#if (CFG_NS87308_DEVS & CFG_NS87308_KBC1)
+ PNP_SET_DEVICE_BASE(LDEV_KBC1, CFG_NS87308_KBC1_BASE);
+ write_pnp_config(LUN_CONFIG_REG, 0);
+ write_pnp_config(CBASE_HIGH, 0x00);
+ write_pnp_config(CBASE_LOW, 0x64);
+#endif
+
+#if (CFG_NS87308_DEVS & CFG_NS87308_MOUSE)
+ PNP_ACTIVATE_DEVICE(LDEV_MOUSE);
+#endif
+
+#if (CFG_NS87308_DEVS & CFG_NS87308_RTC_APC)
+ PNP_SET_DEVICE_BASE(LDEV_RTC_APC, CFG_NS87308_RTC_BASE);
+#endif
+
+#if (CFG_NS87308_DEVS & CFG_NS87308_FDC)
+ PNP_SET_DEVICE_BASE(LDEV_FDC, CFG_NS87308_FDC_BASE);
+ write_pnp_config(LUN_CONFIG_REG, 0x40);
+#endif
+
+#if (CFG_NS87308_DEVS & CFG_NS87308_RARP)
+ PNP_SET_DEVICE_BASE(LDEV_PARP, CFG_NS87308_LPT_BASE);
+#endif
+
+#if (CFG_NS87308_DEVS & CFG_NS87308_UART1)
+ PNP_SET_DEVICE_BASE(LDEV_UART1, CFG_NS87308_UART1_BASE);
+#endif
+
+#if (CFG_NS87308_DEVS & CFG_NS87308_UART2)
+ PNP_SET_DEVICE_BASE(LDEV_UART2, CFG_NS87308_UART2_BASE);
+#endif
+
+#if (CFG_NS87308_DEVS & CFG_NS87308_GPIO)
+ PNP_SET_DEVICE_BASE(LDEV_GPIO, CFG_NS87308_GPIO_BASE);
+#endif
+
+#if (CFG_NS87308_DEVS & CFG_NS87308_POWRMAN)
+#ifndef CFG_NS87308_PWMAN_BASE
+ PNP_ACTIVATE_DEVICE(LDEV_POWRMAN);
+#else
+ PNP_SET_DEVICE_BASE(LDEV_POWRMAN, CFG_NS87308_PWMAN_BASE);
+
+ /*
+ * Enable all units
+ */
+ write_pm_reg(CFG_NS87308_PWMAN_BASE, PWM_FER1, 0x7d);
+ write_pm_reg(CFG_NS87308_PWMAN_BASE, PWM_FER2, 0x87);
+
+#ifdef CFG_NS87308_PMC1
+ write_pm_reg(CFG_NS87308_PWMAN_BASE, PWM_PMC1, CFG_NS87308_PMC1);
+#endif
+
+#ifdef CFG_NS87308_PMC2
+ write_pm_reg(CFG_NS87308_PWMAN_BASE, PWM_PMC2, CFG_NS87308_PMC2);
+#endif
+
+#ifdef CFG_NS87308_PMC3
+ write_pm_reg(CFG_NS87308_PWMAN_BASE, PWM_PMC3, CFG_NS87308_PMC3);
+#endif
+#endif
+#endif
+
+#ifdef CFG_NS87308_CS0_BASE
+ PNP_PGCS_CSLINE_BASE(0, CFG_NS87308_CS0_BASE);
+ PNP_PGCS_CSLINE_CONF(0, CFG_NS87308_CS0_CONF);
+#endif
+
+#ifdef CFG_NS87308_CS1_BASE
+ PNP_PGCS_CSLINE_BASE(1, CFG_NS87308_CS1_BASE);
+ PNP_PGCS_CSLINE_CONF(1, CFG_NS87308_CS1_CONF);
+#endif
+
+#ifdef CFG_NS87308_CS2_BASE
+ PNP_PGCS_CSLINE_BASE(2, CFG_NS87308_CS2_BASE);
+ PNP_PGCS_CSLINE_CONF(2, CFG_NS87308_CS2_CONF);
+#endif
+}
+
+#endif
--- /dev/null
+/*
+ * (C) Copyright 2001 Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Andreas Heppel <aheppel@sysgo.de>
+ *
+ * (C) Copyright 2002
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/*
+ * PCI routines
+ */
+
+#include <common.h>
+
+#ifdef CONFIG_PCI
+
+#include <command.h>
+#include <cmd_boot.h>
+#include <asm/processor.h>
+#include <asm/io.h>
+#include <pci.h>
+
+#ifdef DEBUG
+#define DEBUGF(x...) printf(x)
+#else
+#define DEBUGF(x...)
+#endif /* DEBUG */
+
+/*
+ *
+ */
+
+#define PCI_HOSE_OP(rw, size, type) \
+int pci_hose_##rw##_config_##size(struct pci_controller *hose, \
+ pci_dev_t dev, \
+ int offset, type value) \
+{ \
+ return hose->rw##_##size(hose, dev, offset, value); \
+}
+
+PCI_HOSE_OP(read, byte, u8 *)
+PCI_HOSE_OP(read, word, u16 *)
+PCI_HOSE_OP(read, dword, u32 *)
+PCI_HOSE_OP(write, byte, u8)
+PCI_HOSE_OP(write, word, u16)
+PCI_HOSE_OP(write, dword, u32)
+
+#define PCI_OP(rw, size, type, error_code) \
+int pci_##rw##_config_##size(pci_dev_t dev, int offset, type value) \
+{ \
+ struct pci_controller *hose = pci_bus_to_hose(PCI_BUS(dev)); \
+ \
+ if (!hose) \
+ { \
+ error_code; \
+ return -1; \
+ } \
+ \
+ return pci_hose_##rw##_config_##size(hose, dev, offset, value); \
+}
+
+PCI_OP(read, byte, u8 *, *value = 0xff)
+PCI_OP(read, word, u16 *, *value = 0xffff)
+PCI_OP(read, dword, u32 *, *value = 0xffffffff)
+PCI_OP(write, byte, u8, )
+PCI_OP(write, word, u16, )
+PCI_OP(write, dword, u32, )
+
+#define PCI_READ_VIA_DWORD_OP(size, type, off_mask) \
+int pci_hose_read_config_##size##_via_dword(struct pci_controller *hose, \
+ pci_dev_t dev, \
+ int offset, type val) \
+{ \
+ u32 val32; \
+ \
+ if (pci_hose_read_config_dword(hose, dev, offset & 0xfc, &val32) < 0) \
+ return -1; \
+ \
+ *val = (val32 >> ((offset & (int)off_mask) * 8)); \
+ \
+ return 0; \
+}
+
+#define PCI_WRITE_VIA_DWORD_OP(size, type, off_mask, val_mask) \
+int pci_hose_write_config_##size##_via_dword(struct pci_controller *hose, \
+ pci_dev_t dev, \
+ int offset, type val) \
+{ \
+ u32 val32, mask, ldata; \
+ \
+ 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); \
+ val32 = (val32 & ~mask) | ldata; \
+ \
+ if (pci_hose_write_config_dword(hose, dev, offset & 0xfc, val32) < 0) \
+ return -1; \
+ \
+ return 0; \
+}
+
+PCI_READ_VIA_DWORD_OP(byte, u8 *, 0x03)
+PCI_READ_VIA_DWORD_OP(word, u16 *, 0x02)
+PCI_WRITE_VIA_DWORD_OP(byte, u8, 0x03, 0x000000ff)
+PCI_WRITE_VIA_DWORD_OP(word, u16, 0x02, 0x0000ffff)
+
+/*
+ *
+ */
+
+static struct pci_controller* hose_head = NULL;
+
+void pci_register_hose(struct pci_controller* hose)
+{
+ struct pci_controller **phose = &hose_head;
+
+ while(*phose)
+ phose = &(*phose)->next;
+
+ hose->next = NULL;
+
+ *phose = hose;
+}
+
+struct pci_controller* pci_bus_to_hose(int bus)
+{
+ struct pci_controller *hose;
+
+ for (hose = hose_head; hose; hose = hose->next)
+ if (bus >= hose->first_busno &&
+ bus <= hose->last_busno)
+ return hose;
+
+ return NULL;
+}
+
+pci_dev_t pci_find_devices(struct pci_device_id *ids, int index)
+{
+ struct pci_controller * hose;
+ u16 vendor, device;
+ u8 header_type;
+ pci_dev_t bdf;
+ int i, bus, found_multi = 0;
+
+ for (hose = hose_head; hose; hose = hose->next)
+ {
+#if CFG_SCSI_SCAN_BUS_REVERSE
+ for (bus = hose->last_busno; bus >= hose->first_busno; bus--)
+#else
+ for (bus = hose->first_busno; bus <= hose->last_busno; bus++)
+#endif
+ for (bdf = PCI_BDF(bus,0,0);
+#ifdef CONFIG_ELPPC
+ bdf < PCI_BDF(bus,PCI_MAX_PCI_DEVICES-1,PCI_MAX_PCI_FUNCTIONS-1);
+#else
+ bdf < PCI_BDF(bus+1,0,0);
+#endif
+ bdf += PCI_BDF(0,0,1))
+ {
+ if (!PCI_FUNC(bdf))
+ {
+ pci_read_config_byte(bdf,
+ PCI_HEADER_TYPE,
+ &header_type);
+
+ found_multi = header_type & 0x80;
+ }
+ else
+ {
+ if (!found_multi)
+ continue;
+ }
+
+ pci_read_config_word(bdf,
+ PCI_VENDOR_ID,
+ &vendor);
+ pci_read_config_word(bdf,
+ PCI_DEVICE_ID,
+ &device);
+
+ for (i=0; ids[i].vendor != 0; i++)
+ if (vendor == ids[i].vendor &&
+ device == ids[i].device)
+ {
+ if (index <= 0)
+ return bdf;
+
+ index--;
+ }
+ }
+ }
+
+ return (-1);
+}
+
+pci_dev_t pci_find_device(unsigned int vendor, unsigned int device, int index)
+{
+ static struct pci_device_id ids[2] = {{}, {0, 0}};
+
+ ids[0].vendor = vendor;
+ ids[0].device = device;
+
+ return pci_find_devices(ids, index);
+}
+
+/*
+ *
+ */
+
+unsigned long pci_hose_phys_to_bus(struct pci_controller* hose,
+ unsigned long phys_addr,
+ unsigned long flags)
+{
+ struct pci_region *res;
+ unsigned long bus_addr;
+ int i;
+
+ if (!hose)
+ {
+ printf("pci_hose_phys_to_bus: %s\n", "invalid hose");
+ goto Done;
+ }
+
+ for (i=0; i<hose->region_count; i++)
+ {
+ res = &hose->regions[i];
+
+ if (((res->flags ^ flags) & PCI_REGION_TYPE) != 0)
+ continue;
+
+ bus_addr = phys_addr - res->phys_start + res->bus_start;
+
+ if (bus_addr >= res->bus_start &&
+ bus_addr < res->bus_start + res->size)
+ {
+ return bus_addr;
+ }
+ }
+
+ printf("pci_hose_phys_to_bus: %s\n", "invalid physical address");
+
+ Done:
+ return 0;
+}
+
+unsigned long pci_hose_bus_to_phys(struct pci_controller* hose,
+ unsigned long bus_addr,
+ unsigned long flags)
+{
+ struct pci_region *res;
+ int i;
+
+ if (!hose)
+ {
+ printf("pci_hose_bus_to_phys: %s\n", "invalid hose");
+ goto Done;
+ }
+
+ for (i=0; i<hose->region_count; i++)
+ {
+ res = &hose->regions[i];
+
+ if (((res->flags ^ flags) & PCI_REGION_TYPE) != 0)
+ continue;
+
+ if (bus_addr >= res->bus_start &&
+ bus_addr < res->bus_start + res->size)
+ {
+ return bus_addr - res->bus_start + res->phys_start;
+ }
+ }
+
+ printf("pci_hose_bus_to_phys: %s\n", "invalid physical address");
+
+ Done:
+ return 0;
+}
+
+/*
+ *
+ */
+
+int pci_hose_config_device(struct pci_controller *hose,
+ pci_dev_t dev,
+ unsigned long io,
+ unsigned long mem,
+ unsigned long command)
+{
+ unsigned int bar_response, bar_size, bar_value, old_command;
+ unsigned char pin;
+ int bar, found_mem64;
+
+ DEBUGF("PCI Config: I/O=0x%lx, Memory=0x%lx, Command=0x%lx\n", io, mem, command);
+
+ pci_hose_write_config_dword(hose, dev, PCI_COMMAND, 0);
+
+ for (bar = PCI_BASE_ADDRESS_0; bar < PCI_BASE_ADDRESS_5; bar += 4)
+ {
+ pci_hose_write_config_dword(hose, dev, bar, 0xffffffff);
+ pci_hose_read_config_dword(hose, dev, bar, &bar_response);
+
+ if (!bar_response)
+ continue;
+
+ found_mem64 = 0;
+
+ /* Check the BAR type and set our address mask */
+ if (bar_response & PCI_BASE_ADDRESS_SPACE)
+ {
+ bar_size = ~(bar_response & PCI_BASE_ADDRESS_IO_MASK) + 1;
+ bar_value = io;
+
+ io = ((io - 1) | (bar_size - 1)) + 1;
+ }
+ else
+ {
+ if ( (bar_response & PCI_BASE_ADDRESS_MEM_TYPE_MASK) ==
+ PCI_BASE_ADDRESS_MEM_TYPE_64)
+ found_mem64 = 1;
+
+ bar_size = ~(bar_response & PCI_BASE_ADDRESS_MEM_MASK) + 1;
+ bar_value = mem;
+
+ mem = ((mem - 1) | (bar_size - 1)) + 1;
+ }
+
+ /* Write it out and update our limit */
+ pci_hose_write_config_dword(hose, dev, bar, bar_value);
+
+ if (found_mem64)
+ {
+ bar += 4;
+ pci_hose_write_config_dword(hose, dev, bar, 0x00000000);
+ }
+ }
+
+ /* Configure Cache Line Size Register */
+ pci_hose_write_config_byte(hose, dev, PCI_CACHE_LINE_SIZE, 0x08);
+
+ /* Configure Latency Timer */
+ pci_hose_write_config_byte(hose, dev, PCI_LATENCY_TIMER, 0x80);
+
+ /* Disable interrupt line, if device says it wants to use interrupts */
+ pci_hose_read_config_byte(hose, dev, PCI_INTERRUPT_PIN, &pin);
+ if (pin != 0)
+ {
+ pci_hose_write_config_byte(hose, dev, PCI_INTERRUPT_LINE, 0xff);
+ }
+
+ pci_hose_read_config_dword(hose, dev, PCI_COMMAND, &old_command);
+ pci_hose_write_config_dword(hose, dev, PCI_COMMAND,
+ (old_command & 0xffff0000) | command );
+
+ return 0;
+}
+
+/*
+ *
+ */
+
+struct pci_config_table *pci_find_config(struct pci_controller *hose,
+ unsigned short class,
+ unsigned int vendor,
+ unsigned int device,
+ unsigned int bus,
+ unsigned int dev,
+ unsigned int func)
+{
+ struct pci_config_table *table;
+
+ for (table = hose->config_table; table && table->vendor; table++)
+ {
+ if ((table->vendor == PCI_ANY_ID || table->vendor == vendor) &&
+ (table->device == PCI_ANY_ID || table->device == device) &&
+ (table->class == PCI_ANY_ID || table->class == class) &&
+ (table->bus == PCI_ANY_ID || table->bus == bus) &&
+ (table->dev == PCI_ANY_ID || table->dev == dev) &&
+ (table->func == PCI_ANY_ID || table->func == func))
+ {
+ return table;
+ }
+ }
+
+ return NULL;
+}
+
+void pci_cfgfunc_config_device(struct pci_controller *hose,
+ pci_dev_t dev,
+ struct pci_config_table *entry)
+{
+ pci_hose_config_device(hose, dev, entry->priv[0], entry->priv[1], entry->priv[2]);
+}
+
+void pci_cfgfunc_do_nothing(struct pci_controller *hose,
+ pci_dev_t dev, struct pci_config_table *entry)
+{
+}
+
+/*
+ *
+ */
+
+extern void pciauto_config_init(struct pci_controller *hose);
+extern void pciauto_config_device(struct pci_controller *hose, pci_dev_t dev);
+
+int pci_hose_scan_bus(struct pci_controller *hose, int bus)
+{
+ unsigned int sub_bus, found_multi=0;
+ unsigned short vendor, device, class;
+ unsigned char header_type;
+ struct pci_config_table *cfg;
+ pci_dev_t dev;
+
+ sub_bus = bus;
+
+ for (dev = PCI_BDF(bus,0,0);
+ dev < PCI_BDF(bus,PCI_MAX_PCI_DEVICES-1,PCI_MAX_PCI_FUNCTIONS-1);
+ dev += PCI_BDF(0,0,1))
+ {
+#ifndef CONFIG_405GP /* don't skip host bridge on ppc405gp */
+ /* Skip our host bridge */
+ if ( dev == PCI_BDF(hose->first_busno,0,0) )
+ continue;
+#endif
+
+ if (PCI_FUNC(dev) && !found_multi)
+ continue;
+
+ pci_hose_read_config_byte(hose, dev, PCI_HEADER_TYPE, &header_type);
+
+ pci_hose_read_config_word(hose, dev, PCI_VENDOR_ID, &vendor);
+
+ if (vendor != 0xffff && vendor != 0x0000)
+ {
+
+ if (!PCI_FUNC(dev))
+ found_multi = header_type & 0x80;
+
+ DEBUGF("PCI Scan: Found Bus %d, Device %d, Function %d\n",
+ PCI_BUS(dev), PCI_DEV(dev), PCI_FUNC(dev) );
+
+ pci_hose_read_config_word(hose, dev, PCI_DEVICE_ID, &device);
+ pci_hose_read_config_word(hose, dev, PCI_CLASS_DEVICE, &class);
+
+ cfg = pci_find_config(hose, class, vendor, device,
+ PCI_BUS(dev), PCI_DEV(dev), PCI_FUNC(dev));
+ if (cfg)
+ cfg->config_device(hose, dev, cfg);
+#ifdef CONFIG_PCI_PNP
+ else
+ pciauto_config_device(hose, dev);
+#endif
+ if (hose->fixup_irq)
+ hose->fixup_irq(hose, dev);
+
+#ifdef CONFIG_PCI_SCAN_SHOW
+ /* Skip our host bridge */
+ if ( dev != PCI_BDF(hose->first_busno,0,0) ) {
+ unsigned char int_line;
+
+ pci_hose_read_config_byte(hose, dev, PCI_INTERRUPT_LINE,
+ &int_line);
+ printf(" %02x %02x %04x %04x %04x %02x\n",
+ PCI_BUS(dev), PCI_DEV(dev), vendor, device, class,
+ int_line);
+ }
+#endif
+ }
+ }
+
+ return sub_bus;
+}
+
+int pci_hose_scan(struct pci_controller *hose)
+{
+#ifdef CONFIG_PCI_PNP
+ pciauto_config_init(hose);
+#endif
+ return pci_hose_scan_bus(hose, hose->first_busno);
+}
+
+#endif /* CONFIG_PCI */
--- /dev/null
+/*
+ * arch/ppc/kernel/pci_auto.c
+ *
+ * PCI autoconfiguration library
+ *
+ * Author: Matt Porter <mporter@mvista.com>
+ *
+ * Copyright 2000 MontaVista Software Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include <common.h>
+
+#ifdef CONFIG_PCI
+
+#include <pci.h>
+
+#undef DEBUG
+#ifdef DEBUG
+#define DEBUGF(x...) printf(x)
+#else
+#define DEBUGF(x...)
+#endif /* DEBUG */
+
+#define PCIAUTO_IDE_MODE_MASK 0x05
+
+/*
+ *
+ */
+
+void pciauto_region_init(struct pci_region* res)
+{
+ res->bus_lower = res->bus_start;
+}
+
+void pciauto_region_align(struct pci_region *res, unsigned long size)
+{
+ res->bus_lower = ((res->bus_lower - 1) | (size - 1)) + 1;
+}
+
+int pciauto_region_allocate(struct pci_region* res, unsigned int size, unsigned int *bar)
+{
+ unsigned long addr;
+
+ if (!res)
+ {
+ DEBUGF("No resource");
+ goto error;
+ }
+
+ addr = ((res->bus_lower - 1) | (size - 1)) + 1;
+
+ if (addr - res->bus_start + size > res->size)
+ {
+ DEBUGF("No room in resource");
+ goto error;
+ }
+
+ res->bus_lower = addr + size;
+
+ DEBUGF("address=0x%lx", addr);
+
+ *bar = addr;
+ return 0;
+
+ error:
+ *bar = 0xffffffff;
+ return -1;
+}
+
+/*
+ *
+ */
+
+void pciauto_setup_device(struct pci_controller *hose,
+ pci_dev_t dev, int bars_num,
+ struct pci_region *mem,
+ struct pci_region *io)
+{
+ unsigned int bar_value, bar_response, bar_size;
+ unsigned int cmdstat = 0;
+ struct pci_region *bar_res;
+ int bar, bar_nr = 0;
+ int found_mem64 = 0;
+
+ pci_hose_read_config_dword(hose, dev, PCI_COMMAND, &cmdstat);
+ cmdstat = (cmdstat & ~(PCI_COMMAND_IO | PCI_COMMAND_MEMORY)) | PCI_COMMAND_MASTER;
+
+ for (bar = PCI_BASE_ADDRESS_0; bar <= PCI_BASE_ADDRESS_0 + (bars_num*4); bar += 4)
+ {
+ /* Tickle the BAR and get the response */
+ pci_hose_write_config_dword(hose, dev, bar, 0xffffffff);
+ pci_hose_read_config_dword(hose, dev, bar, &bar_response);
+
+ /* If BAR is not implemented go to the next BAR */
+ if (!bar_response)
+ continue;
+
+ found_mem64 = 0;
+
+ /* Check the BAR type and set our address mask */
+ if (bar_response & PCI_BASE_ADDRESS_SPACE)
+ {
+ bar_size = ~(bar_response & PCI_BASE_ADDRESS_IO_MASK) + 1;
+ bar_res = io;
+
+ DEBUGF("PCI Autoconfig: BAR %d, I/O, size=0x%x, ", bar_nr, bar_size);
+ }
+ else
+ {
+ if ( (bar_response & PCI_BASE_ADDRESS_MEM_TYPE_MASK) ==
+ PCI_BASE_ADDRESS_MEM_TYPE_64)
+ found_mem64 = 1;
+
+ bar_size = ~(bar_response & PCI_BASE_ADDRESS_MEM_MASK) + 1;
+ bar_res = mem;
+
+ DEBUGF("PCI Autoconfig: BAR %d, Mem, size=0x%x, ", bar_nr, bar_size);
+ }
+
+ if (pciauto_region_allocate(bar_res, bar_size, &bar_value) == 0)
+ {
+ /* Write it out and update our limit */
+ pci_hose_write_config_dword(hose, dev, bar, bar_value);
+
+ /*
+ * If we are a 64-bit decoder then increment to the
+ * upper 32 bits of the bar and force it to locate
+ * in the lower 4GB of memory.
+ */
+ if (found_mem64)
+ {
+ bar += 4;
+ pci_hose_write_config_dword(hose, dev, bar, 0x00000000);
+ }
+
+ cmdstat |= (bar_response & PCI_BASE_ADDRESS_SPACE) ?
+ PCI_COMMAND_IO : PCI_COMMAND_MEMORY;
+ }
+
+ DEBUGF("\n");
+
+ bar_nr++;
+ }
+
+ pci_hose_write_config_dword(hose, dev, PCI_COMMAND, cmdstat);
+ pci_hose_write_config_byte(hose, dev, PCI_CACHE_LINE_SIZE, 0x08);
+ pci_hose_write_config_byte(hose, dev, PCI_LATENCY_TIMER, 0x80);
+}
+
+static void pciauto_prescan_setup_bridge(struct pci_controller *hose,
+ pci_dev_t dev, int sub_bus)
+{
+ struct pci_region *pci_mem = hose->pci_mem;
+ struct pci_region *pci_io = hose->pci_io;
+ unsigned int cmdstat;
+
+ pci_hose_read_config_dword(hose, dev, PCI_COMMAND, &cmdstat);
+
+ /* Configure bus number registers */
+ pci_hose_write_config_byte(hose, dev, PCI_PRIMARY_BUS, PCI_BUS(dev));
+ pci_hose_write_config_byte(hose, dev, PCI_SECONDARY_BUS, sub_bus + 1);
+ pci_hose_write_config_byte(hose, dev, PCI_SUBORDINATE_BUS, 0xff);
+
+ if (pci_mem)
+ {
+ /* Round memory allocator to 1MB boundary */
+ pciauto_region_align(pci_mem, 0x100000);
+
+ /* Set up memory and I/O filter limits, assume 32-bit I/O space */
+ pci_hose_write_config_word(hose, dev, PCI_MEMORY_BASE,
+ (pci_mem->bus_lower & 0xfff00000) >> 16);
+
+ cmdstat |= PCI_COMMAND_MEMORY;
+ }
+
+ if (pci_io)
+ {
+ /* Round I/O allocator to 4KB boundary */
+ pciauto_region_align(pci_io, 0x1000);
+
+ pci_hose_write_config_byte(hose, dev, PCI_IO_BASE,
+ (pci_io->bus_lower & 0x0000f000) >> 8);
+ pci_hose_write_config_word(hose, dev, PCI_IO_BASE_UPPER16,
+ (pci_io->bus_lower & 0xffff0000) >> 16);
+
+ cmdstat |= PCI_COMMAND_IO;
+ }
+
+ /* We don't support prefetchable memory for now, so disable */
+ pci_hose_write_config_word(hose, dev, PCI_PREF_MEMORY_BASE, 0x1000);
+ pci_hose_write_config_word(hose, dev, PCI_PREF_MEMORY_LIMIT, 0x1000);
+
+ /* Enable memory and I/O accesses, enable bus master */
+ pci_hose_write_config_dword(hose, dev, PCI_COMMAND, cmdstat | PCI_COMMAND_MASTER);
+}
+
+static void pciauto_postscan_setup_bridge(struct pci_controller *hose,
+ pci_dev_t dev, int sub_bus)
+{
+ struct pci_region *pci_mem = hose->pci_mem;
+ struct pci_region *pci_io = hose->pci_io;
+
+ /* Configure bus number registers */
+ pci_hose_write_config_byte(hose, dev, PCI_SUBORDINATE_BUS, sub_bus);
+
+ if (pci_mem)
+ {
+ /* Round memory allocator to 1MB boundary */
+ pciauto_region_align(pci_mem, 0x100000);
+
+ pci_hose_write_config_word(hose, dev, PCI_MEMORY_LIMIT,
+ (pci_mem->bus_lower-1) >> 16);
+ }
+
+ if (pci_io)
+ {
+ /* Round I/O allocator to 4KB boundary */
+ pciauto_region_align(pci_io, 0x1000);
+
+ pci_hose_write_config_byte(hose, dev, PCI_IO_LIMIT,
+ ((pci_io->bus_lower-1) & 0x0000f000) >> 8);
+ pci_hose_write_config_word(hose, dev, PCI_IO_LIMIT_UPPER16,
+ ((pci_io->bus_lower-1) & 0xffff0000) >> 16);
+ }
+}
+
+/*
+ *
+ */
+
+void pciauto_config_init(struct pci_controller *hose)
+{
+ int i;
+
+ hose->pci_io = hose->pci_mem = NULL;
+
+ for (i=0; i<hose->region_count; i++)
+ {
+ switch(hose->regions[i].flags)
+ {
+ case PCI_REGION_IO:
+ if (!hose->pci_io ||
+ hose->pci_io->size < hose->regions[i].size)
+ hose->pci_io = hose->regions + i;
+ break;
+ case PCI_REGION_MEM:
+ if (!hose->pci_mem ||
+ hose->pci_mem->size < hose->regions[i].size)
+ hose->pci_mem = hose->regions + i;
+ break;
+ }
+ }
+
+
+
+ if (hose->pci_mem)
+ {
+ pciauto_region_init(hose->pci_mem);
+
+ DEBUGF("PCI Autoconfig: Memory region: [%lx-%lx]\n",
+ hose->pci_mem->bus_start,
+ hose->pci_mem->bus_start + hose->pci_mem->size - 1);
+ }
+
+ if (hose->pci_io)
+ {
+ pciauto_region_init(hose->pci_io);
+
+ DEBUGF("PCI Autoconfig: I/O region: [%lx-%lx]\n",
+ hose->pci_io->bus_start,
+ hose->pci_io->bus_start + hose->pci_io->size - 1);
+ }
+}
+
+void pciauto_config_device(struct pci_controller *hose, pci_dev_t dev)
+{
+ unsigned int sub_bus;
+ unsigned short class;
+ unsigned char prg_iface;
+
+ pci_hose_read_config_word(hose, dev, PCI_CLASS_DEVICE, &class);
+
+ switch(class)
+ {
+ case PCI_CLASS_BRIDGE_PCI:
+ pciauto_setup_device(hose, dev, 2, hose->pci_mem, hose->pci_io);
+
+ DEBUGF("PCI Autoconfig: Found P2P bridge, device %d\n", PCI_DEV(dev));
+
+ pciauto_prescan_setup_bridge(hose, dev, PCI_BUS(dev));
+
+ sub_bus = pci_hose_scan_bus(hose, PCI_BUS(dev)+1);
+
+ pciauto_postscan_setup_bridge(hose, dev, sub_bus);
+ break;
+
+ case PCI_CLASS_STORAGE_IDE:
+ pci_hose_read_config_byte(hose, dev, PCI_CLASS_PROG, &prg_iface);
+ if (!(prg_iface & PCIAUTO_IDE_MODE_MASK))
+ {
+ DEBUGF("PCI Autoconfig: Skipping legacy mode IDE controller\n");
+ return;
+ }
+
+ pciauto_setup_device(hose, dev, 6, hose->pci_mem, hose->pci_io);
+ break;
+
+ default:
+ pciauto_setup_device(hose, dev, 6, hose->pci_mem, hose->pci_io);
+ break;
+ }
+}
+
+#endif /* CONFIG_PCI */
--- /dev/null
+/*
+ * (C) Copyright 2002 Wolfgang Grandegger, wg@denx.de.
+ *
+ * This driver for AMD PCnet network controllers is derived from the
+ * Linux driver pcnet32.c written 1996-1999 by Thomas Bogendoerfer.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <malloc.h>
+#include <net.h>
+#include <asm/io.h>
+#include <pci.h>
+
+#if 0
+#define PCNET_DEBUG_LEVEL 0 /* 0=off, 1=init, 2=rx/tx */
+#endif
+
+#if PCNET_DEBUG_LEVEL > 0
+#define DEBUG1(fmt,args...) printf (fmt ,##args)
+#if PCNET_DEBUG_LEVEL > 1
+#define DEBUG2(fmt,args...) printf (fmt ,##args)
+#else
+#define DEBUG2(fmt,args...)
+#endif
+#else
+#define DEBUG1(fmt,args...)
+#define DEBUG2(fmt,args...)
+#endif
+
+#if (CONFIG_COMMANDS & CFG_CMD_NET) && defined(CONFIG_NET_MULTI) \
+ && defined(CONFIG_PCNET)
+
+#if !defined(CONF_PCNET_79C973) && defined(CONF_PCNET_79C975)
+#error "Macro for PCnet chip version is not defined!"
+#endif
+
+/*
+ * Set the number of Tx and Rx buffers, using Log_2(# buffers).
+ * Reasonable default values are 4 Tx buffers, and 16 Rx buffers.
+ * That translates to 2 (4 == 2^^2) and 4 (16 == 2^^4).
+ */
+#define PCNET_LOG_TX_BUFFERS 0
+#define PCNET_LOG_RX_BUFFERS 2
+
+#define TX_RING_SIZE (1 << (PCNET_LOG_TX_BUFFERS))
+#define TX_RING_LEN_BITS ((PCNET_LOG_TX_BUFFERS) << 12)
+
+#define RX_RING_SIZE (1 << (PCNET_LOG_RX_BUFFERS))
+#define RX_RING_LEN_BITS ((PCNET_LOG_RX_BUFFERS) << 4)
+
+#define PKT_BUF_SZ 1544
+
+/* The PCNET Rx and Tx ring descriptors. */
+struct pcnet_rx_head {
+ u32 base;
+ s16 buf_length;
+ s16 status;
+ u32 msg_length;
+ u32 reserved;
+};
+
+struct pcnet_tx_head {
+ u32 base;
+ s16 length;
+ s16 status;
+ u32 misc;
+ u32 reserved;
+};
+
+/* The PCNET 32-Bit initialization block, described in databook. */
+struct pcnet_init_block {
+ u16 mode;
+ u16 tlen_rlen;
+ u8 phys_addr[6];
+ u16 reserved;
+ u32 filter[2];
+ /* Receive and transmit ring base, along with extra bits. */
+ u32 rx_ring;
+ u32 tx_ring;
+ u32 reserved2;
+};
+
+typedef struct pcnet_priv {
+ struct pcnet_rx_head rx_ring[RX_RING_SIZE];
+ struct pcnet_tx_head tx_ring[TX_RING_SIZE];
+ struct pcnet_init_block init_block;
+ /* Receive Buffer space */
+ unsigned char rx_buf[RX_RING_SIZE][PKT_BUF_SZ + 4];
+ int cur_rx;
+ int cur_tx;
+} pcnet_priv_t;
+
+static pcnet_priv_t *lp;
+
+/* Offsets from base I/O address for WIO mode */
+#define PCNET_RDP 0x10
+#define PCNET_RAP 0x12
+#define PCNET_RESET 0x14
+#define PCNET_BDP 0x16
+
+static u16 pcnet_read_csr (struct eth_device *dev, int index)
+{
+ outw (index, dev->iobase+PCNET_RAP);
+ return inw (dev->iobase+PCNET_RDP);
+}
+
+static void pcnet_write_csr (struct eth_device *dev, int index, u16 val)
+{
+ outw (index, dev->iobase+PCNET_RAP);
+ outw (val, dev->iobase+PCNET_RDP);
+}
+
+static u16 pcnet_read_bcr (struct eth_device *dev, int index)
+{
+ outw (index, dev->iobase+PCNET_RAP);
+ return inw (dev->iobase+PCNET_BDP);
+}
+
+static void pcnet_write_bcr (struct eth_device *dev, int index, u16 val)
+{
+ outw (index, dev->iobase+PCNET_RAP);
+ outw (val, dev->iobase+PCNET_BDP);
+}
+
+static void pcnet_reset (struct eth_device *dev)
+{
+ inw (dev->iobase+PCNET_RESET);
+}
+
+static int pcnet_check (struct eth_device *dev)
+{
+ outw (88, dev->iobase+PCNET_RAP);
+ return (inw (dev->iobase+PCNET_RAP) == 88);
+}
+
+static int pcnet_init( struct eth_device* dev, bd_t *bis);
+static int pcnet_send (struct eth_device* dev, volatile void *packet,
+ int length);
+static int pcnet_recv (struct eth_device* dev);
+static void pcnet_halt (struct eth_device* dev);
+static int pcnet_probe(struct eth_device* dev, bd_t *bis, int dev_num);
+
+#define PCI_TO_MEM(d,a) pci_phys_to_mem((pci_dev_t)d->priv, (u_long)(a))
+#define PCI_TO_MEM_LE(d,a) (u32)(cpu_to_le32(PCI_TO_MEM(d,a)))
+
+static struct pci_device_id supported[] = {
+ { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_LANCE },
+ { }
+};
+
+
+int pcnet_initialize(bd_t *bis)
+{
+ pci_dev_t devbusfn;
+ struct eth_device* dev;
+ u16 command, status;
+ int dev_nr = 0;
+
+ DEBUG1("\npcnet_initialize...\n");
+
+ for (dev_nr = 0; ; dev_nr++) {
+
+ /*
+ * Find the PCnet PCI device(s).
+ */
+ if ((devbusfn = pci_find_devices(supported, dev_nr)) < 0) {
+ break;
+ }
+
+ /*
+ * Allocate and pre-fill the device structure.
+ */
+ dev = (struct eth_device*) malloc(sizeof *dev);
+ dev->priv = (void *)devbusfn;
+ sprintf(dev->name, "pcnet#%d", dev_nr);
+
+ /*
+ * Setup the PCI device.
+ */
+ pci_read_config_dword(devbusfn, PCI_BASE_ADDRESS_0, &dev->iobase);
+ dev->iobase &= ~0xf;
+
+ DEBUG1("%s: devbusfn=0x%x iobase=0x%x: ",
+ dev->name, devbusfn, dev->iobase);
+
+ command = PCI_COMMAND_IO | PCI_COMMAND_MASTER;
+ pci_write_config_word(devbusfn, PCI_COMMAND, command);
+ pci_read_config_word(devbusfn, PCI_COMMAND, &status);
+ if ((status & command) != command) {
+ printf("%s: Couldn't enable IO access or Bus Mastering\n",
+ dev->name);
+ free(dev);
+ continue;
+ }
+
+ pci_write_config_byte(devbusfn, PCI_LATENCY_TIMER, 0x40);
+
+ /*
+ * Probe the PCnet chip.
+ */
+ if (pcnet_probe(dev, bis, dev_nr) < 0) {
+ free(dev);
+ continue;
+ }
+
+ /*
+ * Setup device structure and register the driver.
+ */
+ dev->init = pcnet_init;
+ dev->halt = pcnet_halt;
+ dev->send = pcnet_send;
+ dev->recv = pcnet_recv;
+
+ eth_register(dev);
+ }
+
+ udelay(10 * 1000);
+
+ return dev_nr;
+}
+
+static int pcnet_probe(struct eth_device* dev, bd_t *bis, int dev_nr)
+{
+ int chip_version;
+ char *chipname;
+#ifdef PCNET_HAS_PROM
+ int i;
+#endif
+
+ /* Reset the PCnet controller */
+ pcnet_reset(dev);
+
+ /* Check if register access is working */
+ if (pcnet_read_csr(dev, 0) != 4 || !pcnet_check(dev)) {
+ printf("%s: CSR register access check failed\n", dev->name);
+ return -1;
+ }
+
+ /* Identify the chip */
+ chip_version = pcnet_read_csr(dev, 88) | (pcnet_read_csr(dev,89) << 16);
+ if ((chip_version & 0xfff) != 0x003)
+ return -1;
+ chip_version = (chip_version >> 12) & 0xffff;
+ switch (chip_version) {
+#ifdef CONFIG_PCNET_79C973
+ case 0x2625:
+ chipname = "PCnet/FAST III 79C973"; /* PCI */
+ break;
+#endif
+#ifdef CONFIG_PCNET_79C975
+ case 0x2627:
+ chipname = "PCnet/FAST III 79C975"; /* PCI */
+ break;
+#endif
+ default:
+ printf("%s: PCnet version %#x not supported\n",
+ dev->name, chip_version);
+ return -1;
+ }
+
+ DEBUG1("AMD %s\n", chipname);
+
+#ifdef PCNET_HAS_PROM
+ /*
+ * In most chips, after a chip reset, the ethernet address is read from
+ * the station address PROM at the base address and programmed into the
+ * "Physical Address Registers" CSR12-14.
+ */
+ for (i = 0; i < 3; i++) {
+ unsigned int val;
+ val = pcnet_read_csr(dev, i+12) & 0x0ffff;
+ /* There may be endianness issues here. */
+ dev->dev_addr[2*i] = val & 0x0ff;
+ dev->dev_addr[2*i+1] = (val >> 8) & 0x0ff;
+ }
+#endif /* PCNET_HAS_PROM */
+
+ return 0;
+}
+
+static int pcnet_init(struct eth_device* dev, bd_t *bis)
+{
+ int i, val;
+ u32 addr;
+
+ DEBUG1("%s: pcnet_init...\n", dev->name);
+
+ /* Switch pcnet to 32bit mode */
+ pcnet_write_bcr (dev, 20, 2);
+
+#ifdef CONFIG_PN62
+ /* Setup LED registers */
+ val = pcnet_read_bcr (dev, 2) | 0x1000;
+ pcnet_write_bcr (dev, 2, val); /* enable LEDPE */
+ pcnet_write_bcr (dev, 4, 0x5080); /* 100MBit */
+ pcnet_write_bcr (dev, 5, 0x40c0); /* LNKSE */
+ pcnet_write_bcr (dev, 6, 0x4090); /* TX Activity */
+ pcnet_write_bcr (dev, 7, 0x4084); /* RX Activity */
+#endif
+
+ /* Set/reset autoselect bit */
+ val = pcnet_read_bcr (dev, 2) & ~2;
+ val |= 2;
+ pcnet_write_bcr (dev, 2, val);
+
+ /* Enable auto negotiate, setup, disable fd */
+ val = pcnet_read_bcr(dev, 32) & ~0x98;
+ val |= 0x20;
+ pcnet_write_bcr(dev, 32, val);
+
+ /*
+ * We only maintain one structure because the drivers will never
+ * be used concurrently. In 32bit mode the RX and TX ring entries
+ * must be aligned on 16-byte boundaries.
+ */
+ if (lp == NULL) {
+ addr = (u32)malloc(sizeof(pcnet_priv_t) + 0x10);
+ addr = (addr + 0xf) & ~0xf;
+ lp = (pcnet_priv_t *)addr;
+ }
+
+ lp->init_block.mode = cpu_to_le16(0x0000);
+ lp->init_block.filter[0] = 0x00000000;
+ lp->init_block.filter[1] = 0x00000000;
+
+ /*
+ * Initialize the Rx ring.
+ */
+ lp->cur_rx = 0;
+ for (i = 0; i < RX_RING_SIZE; i++) {
+ lp->rx_ring[i].base = PCI_TO_MEM_LE(dev, lp->rx_buf[i]);
+ lp->rx_ring[i].buf_length = cpu_to_le16(-PKT_BUF_SZ);
+ lp->rx_ring[i].status = cpu_to_le16(0x8000);
+ DEBUG1("Rx%d: base=0x%x buf_length=0x%x status=0x%x\n",
+ i, lp->rx_ring[i].base, lp->rx_ring[i].buf_length,
+ lp->rx_ring[i].status);
+ }
+
+ /*
+ * Initialize the Tx ring. The Tx buffer address is filled in as
+ * needed, but we do need to clear the upper ownership bit.
+ */
+ lp->cur_tx = 0;
+ for (i = 0; i < TX_RING_SIZE; i++) {
+ lp->tx_ring[i].base = 0;
+ lp->tx_ring[i].status = 0;
+ }
+
+ /*
+ * Setup Init Block.
+ */
+ DEBUG1("Init block at 0x%p: MAC", &lp->init_block);
+
+ for (i = 0; i < 6; i++) {
+ lp->init_block.phys_addr[i] = dev->enetaddr[i];
+ DEBUG1(" %02x", lp->init_block.phys_addr[i]);
+ }
+
+ lp->init_block.tlen_rlen = cpu_to_le16(TX_RING_LEN_BITS |
+ RX_RING_LEN_BITS);
+ lp->init_block.rx_ring = PCI_TO_MEM_LE(dev, lp->rx_ring);
+ lp->init_block.tx_ring = PCI_TO_MEM_LE(dev, lp->tx_ring);
+
+ DEBUG1("\ntlen_rlen=0x%x rx_ring=0x%x tx_ring=0x%x\n",
+ lp->init_block.tlen_rlen,
+ lp->init_block.rx_ring, lp->init_block.tx_ring);
+
+ /*
+ * Tell the controller where the Init Block is located.
+ */
+ addr = PCI_TO_MEM(dev, &lp->init_block);
+ pcnet_write_csr(dev, 1, addr & 0xffff);
+ pcnet_write_csr(dev, 2, (addr >> 16) & 0xffff);
+
+ pcnet_write_csr (dev, 4, 0x0915);
+ pcnet_write_csr (dev, 0, 0x0001); /* start */
+
+ /* Wait for Init Done bit */
+ for (i = 10000; i > 0; i--) {
+ if (pcnet_read_csr (dev, 0) & 0x0100)
+ break;
+ udelay(10);
+ }
+ if (i <= 0) {
+ printf("%s: TIMEOUT: controller init failed\n", dev->name);
+ pcnet_reset (dev);
+ return 0;
+ }
+
+ /*
+ * Finally start network controller operation.
+ */
+ pcnet_write_csr (dev, 0, 0x0002);
+
+ return 1;
+}
+
+static int pcnet_send(struct eth_device* dev, volatile void *packet, int pkt_len)
+{
+ int i, status;
+ struct pcnet_tx_head *entry = &lp->tx_ring[lp->cur_tx];
+
+ DEBUG2("Tx%d: %d bytes from 0x%p ", lp->cur_tx, pkt_len, packet);
+
+ /* Wait for completion by testing the OWN bit */
+ for (i = 1000; i > 0; i--) {
+ status = le16_to_cpu(entry->status);
+ if ((status & 0x8000) == 0)
+ break;
+ udelay(100);
+ DEBUG2(".");
+ }
+ if (i <= 0) {
+ printf("%s: TIMEOUT: Tx%d failed (status = 0x%x)\n",
+ dev->name, lp->cur_tx, status);
+ pkt_len = 0;
+ goto failure;
+ }
+
+ /*
+ * Setup Tx ring. Caution: the write order is important here,
+ * set the status with the "ownership" bits last.
+ */
+ status = 0x8300;
+ entry->length = le16_to_cpu(-pkt_len);
+ entry->misc = 0x00000000;
+ entry->base = PCI_TO_MEM_LE(dev, packet);
+ entry->status = le16_to_cpu(status);
+
+ /* Trigger an immediate send poll. */
+ pcnet_write_csr (dev, 0, 0x0008);
+
+ failure:
+ if (++lp->cur_tx >= TX_RING_SIZE)
+ lp->cur_tx = 0;
+
+ DEBUG2("done\n");
+ return pkt_len;
+}
+
+static int pcnet_recv(struct eth_device* dev)
+{
+ struct pcnet_rx_head *entry;
+ int pkt_len = 0;
+ u16 status;
+
+ while (1) {
+ entry = &lp->rx_ring[lp->cur_rx];
+ /*
+ * If we own the next entry, it's a new packet. Send it up.
+ */
+ if (((status = le16_to_cpu(entry->status)) & 0x8000) != 0) {
+ break;
+ }
+ status >>= 8;
+
+ if (status != 0x03) { /* There was an error. */
+
+ printf("%s: Rx%d", dev->name, lp->cur_rx);
+ DEBUG1(" (status=0x%x)", status);
+ if (status & 0x20) printf(" Frame");
+ if (status & 0x10) printf(" Overflow");
+ if (status & 0x08) printf(" CRC");
+ if (status & 0x04) printf(" Fifo");
+ printf(" Error\n");
+ entry->status &= le16_to_cpu(0x03ff);
+
+ } else {
+
+ pkt_len = (le32_to_cpu(entry->msg_length) & 0xfff) - 4;
+ if (pkt_len < 60) {
+ printf("%s: Rx%d: invalid packet length %d\n",
+ dev->name, lp->cur_rx, pkt_len);
+ } else {
+ NetReceive(lp->rx_buf[lp->cur_rx], pkt_len);
+ DEBUG2("Rx%d: %d bytes from 0x%p\n",
+ lp->cur_rx, pkt_len, lp->rx_buf[lp->cur_rx]);
+ }
+ }
+ entry->status |= cpu_to_le16(0x8000);
+
+ if (++lp->cur_rx >= RX_RING_SIZE)
+ lp->cur_rx = 0;
+ }
+ return pkt_len;
+}
+
+static void pcnet_halt(struct eth_device* dev)
+{
+ int i;
+
+ DEBUG1("%s: pcnet_halt...\n", dev->name);
+
+ /* Reset the PCnet controller */
+ pcnet_reset (dev);
+
+ /* Wait for Stop bit */
+ for (i = 1000; i > 0; i--) {
+ if (pcnet_read_csr (dev, 0) & 0x4)
+ break;
+ udelay(10);
+ }
+ if (i <= 0) {
+ printf("%s: TIMEOUT: controller reset failed\n", dev->name);
+ }
+}
+
+#endif
--- /dev/null
+/*
+ * (C) Copyright 1997-2002 ELTEC Elektronik AG
+ * Frank Gottschling <fgottschling@eltec.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
+ */
+
+/*
+ * smiLynxEM.c
+ *
+ * Silicon Motion graphic interface for sm810/sm710/sm712 accelerator
+ *
+ * modification history
+ * --------------------
+ * 04-18-2002 Rewritten for U-Boot <fgottschling@eltec.de>.
+ *
+ */
+
+#include <common.h>
+
+#if defined(CONFIG_VIDEO_SMI_LYNXEM)
+
+#include <pci.h>
+#include <video_fb.h>
+
+/*
+ * Export Graphic Device
+ */
+GraphicDevice smi;
+
+/*
+ * SMI 710/712 have 4MB internal RAM; SMI 810 2MB internal + 2MB external
+ */
+#define VIDEO_MEM_SIZE 0x400000
+
+/*
+ * Supported video modes for SMI Lynx E/EM/EM+
+ */
+#define VIDEO_MODES 7
+#define DUAL_800_600 0 /* SMI710:VGA1:75Hz (pitch=1600) */
+ /* VGA2:60/120Hz (pitch=1600) */
+ /* SMI810:VGA1:75Hz (pitch=1600) */
+ /* VGA2:75Hz (pitch=1600) */
+#define DUAL_1024_768 1 /* VGA1:75Hz VGA2:73Hz (pitch=2048) */
+#define SINGLE_800_600 2 /* VGA1:75Hz (pitch=800) */
+#define SINGLE_1024_768 3 /* VGA1:75Hz (pitch=1024) */
+#define SINGLE_1280_1024 4 /* VGA1:75Hz (pitch=1280) */
+#define TV_MODE_CCIR 5 /* VGA1:50Hz (h=720;v=576;pitch=720) */
+#define TV_MODE_EIA 6 /* VGA1:60Hz (h=720;v=484;pitch=720) */
+
+
+/*
+ * ISA mapped regs
+ */
+#define SMI_INDX_C4 (pGD->isaBase + 0x03c4) /* index reg */
+#define SMI_DATA_C5 (pGD->isaBase + 0x03c5) /* data reg */
+#define SMI_INDX_D4 (pGD->isaBase + 0x03d4) /* index reg */
+#define SMI_DATA_D5 (pGD->isaBase + 0x03d5) /* data reg */
+#define SMI_INDX_CE (pGD->isaBase + 0x03ce) /* index reg */
+#define SMI_DATA_CF (pGD->isaBase + 0x03cf) /* data reg */
+#define SMI_LOCK_REG (pGD->isaBase + 0x03c3) /* unlock/lock ext crt reg */
+#define SMI_MISC_REG (pGD->isaBase + 0x03c2) /* misc reg */
+#define SMI_LUT_MASK (pGD->isaBase + 0x03c6) /* lut mask reg */
+#define SMI_LUT_START (pGD->isaBase + 0x03c8) /* lut start index */
+#define SMI_LUT_RGB (pGD->isaBase + 0x03c9) /* lut colors auto incr.*/
+
+
+/*
+ * Video processor control
+*/
+typedef struct {
+ unsigned int control;
+ unsigned int colorKey;
+ unsigned int colorKeyMask;
+ unsigned int start;
+ unsigned short offset;
+ unsigned short width;
+ unsigned int fifoPrio;
+ unsigned int fifoERL;
+ unsigned int YUVtoRGB;
+} SmiVideoProc;
+
+/*
+ * Video window control
+ */
+typedef struct {
+ unsigned short top;
+ unsigned short left;
+ unsigned short bottom;
+ unsigned short right;
+ unsigned int srcStart;
+ unsigned short width;
+ unsigned short offset;
+ unsigned char hStretch;
+ unsigned char vStretch;
+} SmiVideoWin;
+
+/*
+ * Capture port control
+ */
+typedef struct {
+ unsigned int control;
+ unsigned short topClip;
+ unsigned short leftClip;
+ unsigned short srcHeight;
+ unsigned short srcWidth;
+ unsigned int srcBufStart1;
+ unsigned int srcBufStart2;
+ unsigned short srcOffset;
+ unsigned short fifoControl;
+} SmiCapturePort;
+
+
+
+/*
+ * Register values for common video modes
+ */
+static char SMI_SCR[22] = {
+ /* all modes */
+ 0x10, 0xff, 0x11, 0xff, 0x12, 0xff, 0x13, 0xff, 0x14, 0x00, 0x15, 0x90,
+ 0x16, 0x10, 0x17, 0x2c, 0x18, 0xb1, 0x19, 0x20, 0x1a, 0x01
+};
+
+static char SMI_EXT_CRT[VIDEO_MODES][24] = {
+ { /* DUAL_800_600_8 */
+ 0x30, 0x00, 0x31, 0x00, 0x32, 0x00, 0x33, 0x00, 0x34, 0x00, 0x35, 0x00,
+ 0x36, 0x00, 0x3b, 0x00, 0x3c, 0x00, 0x3d, 0x00, 0x3e, 0x00, 0x3f, 0x00
+ },
+ { /* DUAL_1024_768_8 */
+ 0x30, 0x00, 0x31, 0x00, 0x32, 0x00, 0x33, 0x00, 0x34, 0x00, 0x35, 0x00,
+ 0x36, 0x00, 0x3b, 0x00, 0x3c, 0x00, 0x3d, 0x00, 0x3e, 0x00, 0x3f, 0x00
+ },
+ { /* SINGLE_800_600_8 */
+ 0x30, 0x00, 0x31, 0x00, 0x32, 0x00, 0x33, 0x00, 0x34, 0x00, 0x35, 0x00,
+ 0x36, 0x00, 0x3b, 0x00, 0x3c, 0x00, 0x3d, 0x00, 0x3e, 0x00, 0x3f, 0x00
+ },
+ { /* SINGLE_1024_768_8 */
+ 0x30, 0x00, 0x31, 0x00, 0x32, 0x00, 0x33, 0x00, 0x34, 0x00, 0x35, 0x00,
+ 0x36, 0x00, 0x3b, 0x00, 0x3c, 0x00, 0x3d, 0x00, 0x3e, 0x00, 0x3f, 0x00
+ },
+ { /* SINGLE_1280_1024_8 */
+ 0x30, 0x09, 0x31, 0x00, 0x32, 0x00, 0x33, 0x00, 0x34, 0x00, 0x35, 0x00,
+ 0x36, 0x00, 0x3b, 0x00, 0x3c, 0x00, 0x3d, 0x00, 0x3e, 0x00, 0x3f, 0x00
+ },
+ { /* TV_MODE_CCIR */
+ 0x30, 0x80, 0x31, 0x2b, 0x32, 0x06, 0x33, 0x01, 0x34, 0x26, 0x35, 0x88,
+ 0x36, 0x02, 0x38, 0x11, 0x39, 0x11, 0x3a, 0x20, 0x3e, 0xa3, 0x3f, 0x00
+ },
+ { /* TV_MODE_EIA */
+ 0x30, 0x80, 0x31, 0x2b, 0x32, 0x06, 0x33, 0x00, 0x34, 0xf8, 0x35, 0x88,
+ 0x36, 0x02, 0x38, 0x11, 0x39, 0x11, 0x3a, 0x20, 0x3e, 0xa3, 0x3f, 0x00
+ },
+};
+
+static char SMI_CRTCR[VIDEO_MODES][50] = {
+ { /* DUAL_800_600_8 */
+ 0x00, 0x7f, 0x01, 0x63, 0x02, 0x63, 0x03, 0x00, 0x04, 0x68, 0x05, 0x12,
+ 0x06, 0x6f, 0x07, 0xf0, 0x08, 0x00, 0x09, 0x60, 0x0a, 0x00, 0x0b, 0x00,
+ 0x0c, 0x00, 0x0d, 0x00, 0x0e, 0x00, 0x0f, 0x00, 0x10, 0x59, 0x11, 0x2c,
+ 0x12, 0x57, 0x13, 0x64, 0x14, 0x40, 0x15, 0x57, 0x16, 0x00, 0x17, 0xe3,
+ 0x18, 0xff
+ },
+ { /* DUAL_1024_768_8 */
+ 0x00, 0x9f, 0x01, 0x7f, 0x02, 0x7f, 0x03, 0x00, 0x04, 0x82, 0x05, 0x0e,
+ 0x06, 0x1e, 0x07, 0xf5, 0x08, 0x00, 0x09, 0x60, 0x0a, 0x00, 0x0b, 0x00,
+ 0x0c, 0x00, 0x0d, 0x00, 0x0e, 0x00, 0x0f, 0x00, 0x10, 0x01, 0x11, 0x24,
+ 0x12, 0xff, 0x13, 0x80, 0x14, 0x40, 0x15, 0xff, 0x16, 0x00, 0x17, 0xe3,
+ 0x18, 0xff
+ },
+ { /* SINGLE_800_600_8 */
+ 0x00, 0x7f, 0x01, 0x63, 0x02, 0x63, 0x03, 0x00, 0x04, 0x68, 0x05, 0x12,
+ 0x06, 0x6f, 0x07, 0xf0, 0x08, 0x00, 0x09, 0x60, 0x0a, 0x00, 0x0b, 0x00,
+ 0x0c, 0x00, 0x0d, 0x00, 0x0e, 0x00, 0x0f, 0x00, 0x10, 0x59, 0x11, 0x2c,
+ 0x12, 0x57, 0x13, 0x32, 0x14, 0x40, 0x15, 0x57, 0x16, 0x00, 0x17, 0xe3,
+ 0x18, 0xff
+ },
+ { /* SINGLE_1024_768_8 */
+ 0x00, 0x9f, 0x01, 0x7f, 0x02, 0x7f, 0x03, 0x00, 0x04, 0x82, 0x05, 0x0e,
+ 0x06, 0x1e, 0x07, 0xf5, 0x08, 0x00, 0x09, 0x60, 0x0a, 0x00, 0x0b, 0x00,
+ 0x0c, 0x00, 0x0d, 0x00, 0x0e, 0x00, 0x0f, 0x00, 0x10, 0x01, 0x11, 0x24,
+ 0x12, 0xff, 0x13, 0x40, 0x14, 0x40, 0x15, 0xff, 0x16, 0x00, 0x17, 0xe3,
+ 0x18, 0xff
+ },
+ { /* SINGLE_1280_1024_8 */
+ 0x00, 0xce, 0x01, 0x9f, 0x02, 0x9f, 0x03, 0x00, 0x04, 0xa2, 0x05, 0x12,
+ 0x06, 0x2a, 0x07, 0x5a, 0x08, 0x00, 0x09, 0x60, 0x0a, 0x00, 0x0b, 0x00,
+ 0x0c, 0x00, 0x0d, 0x00, 0x0e, 0x00, 0x0f, 0x00, 0x10, 0x01, 0x11, 0x23,
+ 0x12, 0xff, 0x13, 0x50, 0x14, 0x40, 0x15, 0xff, 0x16, 0x00, 0x17, 0xe3,
+ 0x18, 0xff
+ },
+ { /* TV_MODE_CCIR */
+ 0x00, 0x00, 0x01, 0x59, 0x02, 0x63, 0x03, 0x00, 0x04, 0x69, 0x05, 0x10,
+ 0x06, 0x72, 0x07, 0xf0, 0x08, 0x00, 0x09, 0x60, 0x0a, 0x00, 0x0b, 0x00,
+ 0x0c, 0x00, 0x0d, 0x00, 0x0e, 0x00, 0x0f, 0x00, 0x10, 0x58, 0x11, 0x2c,
+ 0x12, 0x57, 0x13, 0x2d, 0x14, 0x40, 0x15, 0x57, 0x16, 0x00, 0x17, 0xe3,
+ 0x18, 0xff
+ },
+ { /* TV_MODE_EIA */
+ 0x00, 0x00, 0x01, 0x59, 0x02, 0x63, 0x03, 0x00, 0x04, 0x69, 0x05, 0x10,
+ 0x06, 0x72, 0x07, 0xf0, 0x08, 0x00, 0x09, 0x60, 0x0a, 0x00, 0x0b, 0x00,
+ 0x0c, 0x00, 0x0d, 0x00, 0x0e, 0x00, 0x0f, 0x00, 0x10, 0x58, 0x11, 0x2c,
+ 0x12, 0x57, 0x13, 0x2d, 0x14, 0x40, 0x15, 0x57, 0x16, 0x00, 0x17, 0xe3,
+ 0x18, 0xff
+ },
+};
+
+static char SMI_SEQR[10] = {
+ 0x00, 0x03, 0x01, 0x01, 0x02, 0x0f, 0x03, 0x03, 0x04, 0x0e
+};
+
+static char SMI_PCR[VIDEO_MODES][8] = {
+ { /* DUAL_800_600_8 */
+ 0x20, 0x04, 0x21, 0x20, 0x22, 0x00, 0x23, 0x00
+ },
+ { /* DUAL_1024_768_8 */
+ 0x20, 0x04, 0x21, 0x20, 0x22, 0x00, 0x23, 0x00
+ },
+ { /* SINGLE_800_600_8 */
+ 0x20, 0x04, 0x21, 0x30, 0x22, 0x02, 0x23, 0x00
+ },
+ { /* SINGLE_1024_768_8 */
+ 0x20, 0x04, 0x21, 0x30, 0x22, 0x02, 0x23, 0x00
+ },
+ { /* SINGLE_1280_1024_8 */
+ 0x20, 0x04, 0x21, 0x30, 0x22, 0x02, 0x23, 0x00
+ },
+ { /* TV_MODE_CCIR */
+ 0x20, 0x04, 0x21, 0x30, 0x22, 0x02, 0x23, 0x00
+ },
+ { /* TV_MODE_EIA */
+ 0x20, 0x04, 0x21, 0x30, 0x22, 0x02, 0x23, 0x00
+ },
+};
+
+static char SMI_MCR[VIDEO_MODES][6] = {
+ { /* DUAL_800_600_8 */
+ 0x60, 0x01, 0x61, 0x00, 0x62, 0x7a
+ },
+ { /* DUAL_1024_768_8 */
+ 0x60, 0x01, 0x61, 0x00, 0x62, 0x7a
+ },
+ { /* SINGLE_800_600_8 */
+ 0x60, 0x00, 0x61, 0x00, 0x62, 0x34
+ },
+ { /* SINGLE_1024_768_8 */
+ 0x60, 0x00, 0x61, 0x00, 0x62, 0xfe
+ },
+ { /* SINGLE_1280_1024_8 */
+ 0x60, 0x00, 0x61, 0x00, 0x62, 0xfe
+ },
+ { /* TV_MODE_CCIR */
+ 0x60, 0x00, 0x61, 0x00, 0x62, 0x34
+ },
+ { /* TV_MODE_EIA */
+ 0x60, 0x00, 0x61, 0x00, 0x62, 0x34
+ },
+};
+
+static char SMI_CCR[VIDEO_MODES][18] = {
+ { /* DUAL_800_600_8 */
+ 0x65, 0x34, 0x68, 0x50, 0x69, 0x05, 0x6a, 0x53, 0x6b, 0x15, 0x6c, 0x15,
+ 0x6d, 0x06, 0x6e, 0x3d, 0x6f, 0x12
+ },
+ { /* DUAL_1024_768_8 */
+ 0x65, 0x00, 0x68, 0x50, 0x69, 0x06, 0x6a, 0x53, 0x6b, 0x15, 0x6c, 0x0b,
+ 0x6d, 0x02, 0x6e, 0x0b, 0x6f, 0x02
+ },
+ { /* SINGLE_800_600_8 */
+ 0x65, 0x34, 0x68, 0x40, 0x69, 0x03, 0x6a, 0x53, 0x6b, 0x15, 0x6c, 0x15,
+ 0x6d, 0x06, 0x6e, 0x3d, 0x6f, 0x12
+ },
+ { /* SINGLE_1024_768_8 */
+ 0x65, 0x00, 0x68, 0x50, 0x69, 0x03, 0x6a, 0x53, 0x6b, 0x15, 0x6c, 0x0b,
+ 0x6d, 0x02, 0x6e, 0x0b, 0x6f, 0x02
+ },
+ { /* SINGLE_1280_1024_8 */
+ 0x65, 0x00, 0x68, 0x50, 0x69, 0x03, 0x6a, 0x53, 0x6b, 0x15, 0x6c, 0xd9,
+ 0x6d, 0x17, 0x6e, 0xd9, 0x6f, 0x17
+ },
+ { /* TV_MODE_CCIR */
+ 0x65, 0x07, 0x68, 0xc0, 0x69, 0x81, 0x6a, 0x53, 0x6b, 0x15, 0x6c, 0x15,
+ 0x6d, 0x06, 0x6e, 0x3d, 0x6f, 0x12
+ },
+ { /* TV_MODE_EIA */
+ 0x65, 0x07, 0x68, 0xc0, 0x69, 0x81, 0x6a, 0x53, 0x6b, 0x15, 0x6c, 0x15,
+ 0x6d, 0x06, 0x6e, 0x3d, 0x6f, 0x12
+ },
+};
+
+static char SMI_SHVGA[VIDEO_MODES][24] = {
+ { /* DUAL_800_600_8 */
+ 0x40, 0x7f, 0x41, 0x63, 0x42, 0x00, 0x43, 0x68, 0x44, 0x12, 0x45, 0x6f,
+ 0x46, 0x57, 0x47, 0x00, 0x48, 0x59, 0x49, 0x0c, 0x4a, 0xa0, 0x4b, 0x20,
+ },
+ { /* DUAL_1024_768_8 */
+ 0x40, 0x9f, 0x41, 0x7f, 0x42, 0x00, 0x43, 0x82, 0x44, 0x0e, 0x45, 0x1e,
+ 0x46, 0xff, 0x47, 0x00, 0x48, 0x00, 0x49, 0x03, 0x4a, 0xe5, 0x4b, 0x20,
+ },
+ { /* SINGLE_800_600_8 */
+ 0x40, 0x7f, 0x41, 0x63, 0x42, 0x00, 0x43, 0x68, 0x44, 0x12, 0x45, 0x6f,
+ 0x46, 0x57, 0x47, 0x00, 0x48, 0x59, 0x49, 0x0c, 0x4a, 0xa0, 0x4b, 0x20,
+ },
+ { /* SINGLE_1024_768_8 */
+ 0x40, 0x9f, 0x41, 0x7f, 0x42, 0x00, 0x43, 0x82, 0x44, 0x0e, 0x45, 0x1e,
+ 0x46, 0xff, 0x47, 0x00, 0x48, 0x01, 0x49, 0x04, 0x4a, 0xa5, 0x4b, 0x20,
+ },
+ { /* SINGLE_1280_1024_8 */
+ 0x40, 0xce, 0x41, 0x9f, 0x42, 0x00, 0x43, 0xa2, 0x44, 0x12, 0x45, 0x2a,
+ 0x46, 0xff, 0x47, 0x00, 0x48, 0x01, 0x49, 0x03, 0x4a, 0x4a, 0x4b, 0x20,
+ },
+ { /* TV_MODE_CCIR */
+ 0x40, 0x6d, 0x41, 0x59, 0x42, 0x00, 0x43, 0x60, 0x44, 0x09, 0x45, 0x38,
+ 0x46, 0x25, 0x47, 0x05, 0x48, 0x2a, 0x49, 0x00, 0x4a, 0x4d, 0x4b, 0x00,
+ },
+ { /* TV_MODE_EIA */
+ 0x40, 0x6d, 0x41, 0x59, 0x42, 0x00, 0x43, 0x60, 0x44, 0x09, 0x45, 0x06,
+ 0x46, 0xf7, 0x47, 0x05, 0x48, 0xfa, 0x49, 0x00, 0x4a, 0x41, 0x4b, 0x00,
+ },
+};
+
+
+static char SMI_GPR[VIDEO_MODES][12] = {
+ { /* DUAL_800_600_8 */
+ 0x70, 0x00, 0x71, 0xa2, 0x72, 0x0f, 0x73, 0x30, 0x74, 0x40, 0x75, 0x00
+ },
+ { /* DUAL_1024_768_8 */
+ 0x70, 0x00, 0x71, 0xa2, 0x72, 0x0f, 0x73, 0x30, 0x74, 0x40, 0x75, 0x00
+ },
+ { /* SINGLE_800_600_8 */
+ 0x70, 0x00, 0x71, 0xa2, 0x72, 0x0f, 0x73, 0x30, 0x74, 0x40, 0x75, 0x00
+ },
+ { /* SINGLE_1024_768_8 */
+ 0x70, 0x00, 0x71, 0xa2, 0x72, 0x0f, 0x73, 0x30, 0x74, 0x40, 0x75, 0x00
+ },
+ { /* SINGLE_1280_1024_8 */
+ 0x70, 0x00, 0x71, 0xa2, 0x72, 0x0f, 0x73, 0x30, 0x74, 0x40, 0x75, 0x00
+ },
+ { /* TV_MODE_CCIR */
+ 0x70, 0x82, 0x71, 0x8d, 0x72, 0x0c, 0x73, 0x32, 0x74, 0x09, 0x75, 0x28
+ },
+ { /* TV_MODE_EIA */
+ 0x70, 0x82, 0x71, 0x8d, 0x72, 0x0c, 0x73, 0x32, 0x74, 0x09, 0x75, 0x28
+ },
+};
+
+static char SMI_HCR[VIDEO_MODES][22] = {
+ { /* DUAL_800_600_8 */
+ 0x80, 0xff, 0x81, 0x07, 0x82, 0x00, 0x83, 0xff, 0x84, 0xff, 0x88, 0x00,
+ 0x89, 0x02, 0x8a, 0x80, 0x8b, 0x01, 0x8c, 0xff, 0x8d, 0x00
+ },
+ { /* DUAL_1024_768_8 */
+ 0x80, 0xff, 0x81, 0x07, 0x82, 0x00, 0x83, 0xff, 0x84, 0xff, 0x88, 0x00,
+ 0x89, 0x02, 0x8a, 0x80, 0x8b, 0x01, 0x8c, 0xff, 0x8d, 0x00
+ },
+ { /* SINGLE_800_600_8 */
+ 0x80, 0xff, 0x81, 0x07, 0x82, 0x00, 0x83, 0xff, 0x84, 0xff, 0x88, 0x00,
+ 0x89, 0x02, 0x8a, 0x80, 0x8b, 0x01, 0x8c, 0xff, 0x8d, 0x00
+ },
+ { /* SINGLE_1024_768_8 */
+ 0x80, 0xff, 0x81, 0x07, 0x82, 0x00, 0x83, 0xff, 0x84, 0xff, 0x88, 0x00,
+ 0x89, 0x02, 0x8a, 0x80, 0x8b, 0x01, 0x8c, 0xff, 0x8d, 0x00
+ },
+ { /* SINGLE_1280_1024_8 */
+ 0x80, 0xff, 0x81, 0x07, 0x82, 0x00, 0x83, 0xff, 0x84, 0xff, 0x88, 0x00,
+ 0x89, 0x02, 0x8a, 0x80, 0x8b, 0x01, 0x8c, 0xff, 0x8d, 0x00
+ },
+ { /* TV_MODE_CCIR */
+ 0x80, 0xff, 0x81, 0x07, 0x82, 0x00, 0x83, 0xff, 0x84, 0xff, 0x88, 0x00,
+ 0x89, 0x02, 0x8a, 0x80, 0x8b, 0x01, 0x8c, 0xff, 0x8d, 0x00
+ },
+ { /* TV_MODE_EIA */
+ 0x80, 0xff, 0x81, 0x07, 0x82, 0x00, 0x83, 0xff, 0x84, 0xff, 0x88, 0x00,
+ 0x89, 0x02, 0x8a, 0x80, 0x8b, 0x01, 0x8c, 0xff, 0x8d, 0x00
+ },
+};
+
+static char SMI_FPR[VIDEO_MODES][88] = {
+ { /* DUAL_800_600_8 */
+ 0x30, 0x36, 0x31, 0x83, 0x32, 0x38, 0x33, 0x00, 0x34, 0x40, 0x3e, 0x03,
+ 0x3f, 0xff, 0x40, 0x64, 0x41, 0x00, 0x42, 0x00, 0x43, 0x00, 0x44, 0xc8,
+ 0x45, 0x02, 0x46, 0x00, 0x47, 0xfc, 0x48, 0x20, 0x49, 0x1c, 0x4a, 0x41,
+ 0x4b, 0xa0, 0x4c, 0x00,
+ 0x50, 0x04, 0x51, 0x48, 0x52, 0x83, 0x53, 0x63, 0x54, 0x67, 0x55, 0x71,
+ 0x56, 0x57, 0x57, 0x59, 0x58, 0x03, 0x59, 0x00, 0x5a, 0x4a,
+ 0xa1, 0x00, 0xa2, 0x00, 0xa3, 0x00, 0xa4, 0x00, 0xa8, 0x00, 0xa9, 0x00,
+ 0xaa, 0xdf, 0xab, 0x7f, 0xac, 0x00, 0xad, 0x41, 0xae, 0x00, 0xaf, 0x00,
+ 0xa0, 0x44
+ },
+ { /* DUAL_1024_768_8 */
+ 0x30, 0x3a, 0x31, 0x83, 0x32, 0x38, 0x33, 0x00, 0x34, 0x40, 0x3e, 0x00,
+ 0x3f, 0x00, 0x40, 0x80, 0x41, 0x00, 0x42, 0x00, 0x43, 0x00, 0x44, 0x00,
+ 0x45, 0x42, 0x46, 0x00, 0x47, 0xfc, 0x48, 0x20, 0x49, 0x1c, 0x4a, 0x41,
+ 0x4b, 0xa0, 0x4c, 0x00,
+ 0x50, 0x06, 0x51, 0x68, 0x52, 0xa7, 0x53, 0x7f, 0x54, 0x83, 0x55, 0x25,
+ 0x56, 0xff, 0x57, 0x03, 0x58, 0x04, 0x59, 0x00, 0x5a, 0xc2,
+ 0xa1, 0x00, 0xa2, 0x00, 0xa3, 0x00, 0xa4, 0x00, 0xa8, 0x00, 0xa9, 0x00,
+ 0xaa, 0xdf, 0xab, 0x7f, 0xac, 0x00, 0xad, 0x41, 0xae, 0x00, 0xaf, 0x00,
+ 0xa0, 0x44
+ },
+ { /* SINGLE_800_600_8 */
+ 0x30, 0x36, 0x31, 0x82, 0x32, 0x38, 0x33, 0x00, 0x34, 0x40, 0x3e, 0x03,
+ 0x3f, 0xff, 0x40, 0x64, 0x41, 0x00, 0x42, 0x00, 0x43, 0x00, 0x44, 0xc8,
+ 0x45, 0x02, 0x46, 0x00, 0x47, 0xfc, 0x48, 0x20, 0x49, 0x1c, 0x4a, 0x00,
+ 0x4b, 0xa0, 0x4c, 0x00,
+ 0x50, 0x04, 0x51, 0x48, 0x52, 0x83, 0x53, 0x63, 0x54, 0x67, 0x55, 0x71,
+ 0x56, 0x57, 0x57, 0x59, 0x58, 0x03, 0x59, 0x00, 0x5a, 0x4a,
+ 0xa1, 0x00, 0xa2, 0x00, 0xa3, 0x00, 0xa4, 0x00, 0xa8, 0x00, 0xa9, 0x00,
+ 0xaa, 0xdf, 0xab, 0x7f, 0xac, 0x00, 0xad, 0x41, 0xae, 0x00, 0xaf, 0x00,
+ 0xa0, 0x44
+ },
+ { /* SINGLE_1024_768_8 */
+ 0x30, 0x3a, 0x31, 0x82, 0x32, 0x38, 0x33, 0x00, 0x34, 0x40, 0x3e, 0x00,
+ 0x3f, 0x00, 0x40, 0x80, 0x41, 0x00, 0x42, 0x00, 0x43, 0x00, 0x44, 0x00,
+ 0x45, 0x42, 0x46, 0x00, 0x47, 0xfc, 0x48, 0x20, 0x49, 0x1c, 0x4a, 0x11,
+ 0x4b, 0xa0, 0x4c, 0x00,
+ 0x50, 0x06, 0x51, 0x68, 0x52, 0xa7, 0x53, 0x7f, 0x54, 0x83, 0x55, 0x24,
+ 0x56, 0xff, 0x57, 0x03, 0x58, 0x04, 0x59, 0x00, 0x5a, 0xc2,
+ 0xa1, 0x00, 0xa2, 0x00, 0xa3, 0x00, 0xa4, 0x00, 0xa8, 0x00, 0xa9, 0x00,
+ 0xaa, 0xdf, 0xab, 0x7f, 0xac, 0x00, 0xad, 0x41, 0xae, 0x00, 0xaf, 0x00,
+ 0xa0, 0x44
+ },
+ { /* SINGLE_1280_1024_8 */
+ 0x30, 0x3e, 0x31, 0x82, 0x32, 0x38, 0x33, 0x00, 0x34, 0x40, 0x3e, 0x00,
+ 0x3f, 0x00, 0x40, 0xa0, 0x41, 0x00, 0x42, 0x00, 0x43, 0x00, 0x44, 0x00,
+ 0x45, 0x42, 0x46, 0x00, 0x47, 0xfc, 0x48, 0x20, 0x49, 0x1c, 0x4a, 0x11,
+ 0x4b, 0xa0, 0x4c, 0x00,
+ 0x50, 0x08, 0x51, 0x88, 0x52, 0xd3, 0x53, 0x9f, 0x54, 0xa3, 0x55, 0x2a,
+ 0x56, 0xff, 0x57, 0x04, 0x58, 0x00, 0x59, 0x00, 0x5a, 0x63,
+ 0xa1, 0x00, 0xa2, 0x00, 0xa3, 0x00, 0xa4, 0x00, 0xa8, 0x00, 0xa9, 0x00,
+ 0xaa, 0xdf, 0xab, 0x7f, 0xac, 0x00, 0xad, 0x41, 0xae, 0x00, 0xaf, 0x00,
+ 0xa0, 0x44
+ },
+ { /* TV_MODE_CCIR */
+ 0x30, 0x24, 0x31, 0x84, 0x32, 0x20, 0x33, 0x09, 0x34, 0xf0, 0x3e, 0x03,
+ 0x3f, 0xff, 0x40, 0x64, 0x41, 0x00, 0x42, 0x00, 0x43, 0x00, 0x44, 0xc8,
+ 0x45, 0x02, 0x46, 0x00, 0x47, 0xfc, 0x48, 0x20, 0x49, 0x1c, 0x4a, 0x00,
+ 0x4b, 0xa0, 0x4c, 0x00,
+ 0x50, 0x04, 0x51, 0x48, 0x52, 0x83, 0x53, 0x63, 0x54, 0x68, 0x55, 0x73,
+ 0x56, 0x57, 0x57, 0x58, 0x58, 0x04, 0x59, 0x57, 0x5a, 0x7b,
+ 0xa1, 0x10, 0xa2, 0xab, 0xa3, 0x98, 0xa4, 0xc1, 0xa8, 0x8c, 0xa9, 0x05,
+ 0xaa, 0x17, 0xab, 0x35, 0xac, 0x41, 0xad, 0x68, 0xae, 0x00, 0xaf, 0x00,
+ 0xa0, 0x00
+ },
+ { /* TV_MODE_EIA */
+ 0x30, 0x24, 0x31, 0x84, 0x32, 0x20, 0x33, 0x09, 0x34, 0xf0, 0x3e, 0x03,
+ 0x3f, 0xff, 0x40, 0x64, 0x41, 0x00, 0x42, 0x00, 0x43, 0x00, 0x44, 0xc8,
+ 0x45, 0x02, 0x46, 0x00, 0x47, 0xfc, 0x48, 0x20, 0x49, 0x1c, 0x4a, 0x00,
+ 0x4b, 0xa0, 0x4c, 0x00,
+ 0x50, 0x04, 0x51, 0x48, 0x52, 0x83, 0x53, 0x63, 0x54, 0x68, 0x55, 0x73,
+ 0x56, 0x57, 0x57, 0x58, 0x58, 0x04, 0x59, 0x57, 0x5a, 0x7b,
+ 0xa1, 0x10, 0xa2, 0xab, 0xa3, 0x98, 0xa4, 0xc1, 0xa8, 0x8c, 0xa9, 0x05,
+ 0xaa, 0x17, 0xab, 0x35, 0xac, 0x41, 0xad, 0x68, 0xae, 0x00, 0xaf, 0x00,
+ 0xa0, 0x00
+ },
+};
+
+static char SMI_GCR[18] = {
+ 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x04, 0x00, 0x05, 0x40,
+ 0x06, 0x05, 0x07, 0x0f, 0x08, 0xff
+};
+
+/*******************************************************************************
+*
+* Read SMI ISA register
+*/
+static char smiRead (unsigned short index, char reg)
+{
+ register GraphicDevice *pGD = (GraphicDevice *)&smi;
+
+ out8 ((pGD->isaBase + index), reg);
+ return (in8 (pGD->isaBase + index + 1));
+}
+
+/*******************************************************************************
+*
+* Write SMI ISA register
+*/
+static void smiWrite (unsigned short index, char reg, char val)
+{
+ register GraphicDevice *pGD = (GraphicDevice *)&smi;
+
+ out8 ((pGD->isaBase + index), reg);
+ out8 ((pGD->isaBase + index + 1), val);
+}
+
+/*******************************************************************************
+*
+* Write a table of SMI ISA register
+*/
+static void smiLoadRegs (
+ unsigned int iReg,
+ unsigned int dReg,
+ char *regTab,
+ unsigned int tabSize
+ )
+{
+ register int i;
+
+ for (i=0; i<tabSize; i+=2)
+ {
+ out8 (iReg, regTab[i]);
+ out8 (dReg, regTab[i+1]);
+ }
+}
+
+/*******************************************************************************
+*
+* Init capture port registers
+*/
+static void smiInitCapturePort (void)
+{
+ SmiCapturePort smiCP = { 0x01400600, 0x30, 0x40, 480, 640, 0, 0, 2560, 6 };
+ register GraphicDevice *pGD = (GraphicDevice *)&smi;
+ register SmiCapturePort *pCP = (SmiCapturePort *)&smiCP;
+
+ out32r ((pGD->cprBase + 0x0004), ((pCP->topClip<<16) | pCP->leftClip));
+ out32r ((pGD->cprBase + 0x0008), ((pCP->srcHeight<<16) | pCP->srcWidth));
+ out32r ((pGD->cprBase + 0x000c), pCP->srcBufStart1/8);
+ out32r ((pGD->cprBase + 0x0010), pCP->srcBufStart2/8);
+ out32r ((pGD->cprBase + 0x0014), pCP->srcOffset/8);
+ out32r ((pGD->cprBase + 0x0018), pCP->fifoControl);
+ out32r ((pGD->cprBase + 0x0000), pCP->control);
+}
+
+
+/*******************************************************************************
+*
+* Init video processor registers
+*/
+static void smiInitVideoProcessor (void)
+{
+ SmiVideoProc smiVP = { 0x100000, 0, 0, 0, 0, 1600, 0x1200543, 4, 0xededed };
+ SmiVideoWin smiVW = { 0, 0, 599, 799, 0, 1600, 0, 0, 0 };
+ register GraphicDevice *pGD = (GraphicDevice *)&smi;
+ register SmiVideoProc *pVP = (SmiVideoProc *)&smiVP;
+ register SmiVideoWin *pVWin = (SmiVideoWin *)&smiVW;
+
+ pVP->width = pGD->plnSizeX * pGD->gdfBytesPP;
+ pVP->control |= pGD->gdfIndex << 16;
+ pVWin->bottom = pGD->winSizeY - 1;
+ pVWin->right = pGD->winSizeX - 1;
+ pVWin->width = pVP->width;
+
+ /* color key */
+ out32r ((pGD->vprBase + 0x0004), pVP->colorKey);
+
+ /* color key mask */
+ out32r ((pGD->vprBase + 0x0008), pVP->colorKeyMask);
+
+ /* data src start adrs */
+ out32r ((pGD->vprBase + 0x000c), pVP->start / 8);
+
+ /* data width and offset */
+ out32r ((pGD->vprBase + 0x0010),
+ ((pVP->offset / 8 * pGD->gdfBytesPP) << 16) |
+ (pGD->plnSizeX / 8 * pGD->gdfBytesPP));
+
+ /* video window 1 */
+ out32r ((pGD->vprBase + 0x0014),
+ ((pVWin->top << 16) | pVWin->left));
+
+ out32r ((pGD->vprBase + 0x0018),
+ ((pVWin->bottom << 16) | pVWin->right));
+
+ out32r ((pGD->vprBase + 0x001c), pVWin->srcStart / 8);
+
+ out32r ((pGD->vprBase + 0x0020),
+ (((pVWin->offset / 8) << 16) | (pVWin->width / 8)));
+
+ out32r ((pGD->vprBase + 0x0024),
+ (((pVWin->hStretch) << 8) | pVWin->vStretch));
+
+ /* video window 2 */
+ out32r ((pGD->vprBase + 0x0028),
+ ((pVWin->top << 16) | pVWin->left));
+
+ out32r ((pGD->vprBase + 0x002c),
+ ((pVWin->bottom << 16) | pVWin->right));
+
+ out32r ((pGD->vprBase + 0x0030),
+ pVWin->srcStart / 8);
+
+ out32r ((pGD->vprBase + 0x0034),
+ (((pVWin->offset / 8) << 16) | (pVWin->width / 8)));
+
+ out32r ((pGD->vprBase + 0x0038),
+ (((pVWin->hStretch) << 8) | pVWin->vStretch));
+
+ /* fifo prio control */
+ out32r ((pGD->vprBase + 0x0054), pVP->fifoPrio);
+
+ /* fifo empty request levell */
+ out32r ((pGD->vprBase + 0x0058), pVP->fifoERL);
+
+ /* conversion constant */
+ out32r ((pGD->vprBase + 0x005c), pVP->YUVtoRGB);
+
+ /* vpr control word */
+ out32r ((pGD->vprBase + 0x0000), pVP->control);
+}
+
+/******************************************************************************
+ *
+ * Init drawing engine registers
+ */
+static void smiInitDrawingEngine (void)
+{
+ GraphicDevice *pGD = (GraphicDevice *)&smi;
+ unsigned int val;
+
+ /* don't start now */
+ out32r ((pGD->dprBase + 0x000c), 0x000f0000);
+
+ /* set rop2 to copypen */
+ val = 0xffff3ff0 & in32r ((pGD->dprBase + 0x000c));
+ out32r ((pGD->dprBase + 0x000c), (val | 0x8000 | 0x0c));
+
+ /* set clip rect */
+ out32r ((pGD->dprBase + 0x002c), 0);
+ out32r ((pGD->dprBase + 0x0030),
+ ((pGD->winSizeY<<16) | pGD->winSizeX * pGD->gdfBytesPP ));
+
+ /* src row pitch */
+ val = 0xffff0000 & (in32r ((pGD->dprBase + 0x0010)));
+ out32r ((pGD->dprBase + 0x0010),
+ (val | pGD->plnSizeX * pGD->gdfBytesPP));
+
+ /* dst row pitch */
+ val = 0x0000ffff & (in32r ((pGD->dprBase + 0x0010)));
+ out32r ((pGD->dprBase + 0x0010),
+ (((pGD->plnSizeX * pGD->gdfBytesPP)<<16) | val));
+
+ /* window width src/dst */
+ out32r ((pGD->dprBase + 0x003c),
+ (((pGD->plnSizeX * pGD->gdfBytesPP & 0x0fff)<<16) |
+ (pGD->plnSizeX * pGD->gdfBytesPP & 0x0fff)));
+ out16r ((pGD->dprBase + 0x001e), 0x0000);
+
+ /* src base adrs */
+ out32r ((pGD->dprBase + 0x0040),
+ (((pGD->frameAdrs/8) & 0x000fffff)));
+
+ /* dst base adrs */
+ out32r ((pGD->dprBase + 0x0044),
+ (((pGD->frameAdrs/8) & 0x000fffff)));
+
+ /* foreground color */
+ out32r ((pGD->dprBase + 0x0014), pGD->fg);
+
+ /* background color */
+ out32r ((pGD->dprBase + 0x0018), pGD->bg);
+
+ /* xcolor */
+ out32r ((pGD->dprBase + 0x0020), 0x00ffffff);
+
+ /* xcolor mask */
+ out32r ((pGD->dprBase + 0x0024), 0x00ffffff);
+
+ /* bit mask */
+ out32r ((pGD->dprBase + 0x0028), 0x00ffffff);
+
+ /* load mono pattern */
+ out32r ((pGD->dprBase + 0x0034), 0);
+ out32r ((pGD->dprBase + 0x0038), 0);
+}
+
+static struct pci_device_id supported[] = {
+ { PCI_VENDOR_ID_SMI, PCI_DEVICE_ID_SMI_710 },
+ { PCI_VENDOR_ID_SMI, PCI_DEVICE_ID_SMI_712 },
+ { PCI_VENDOR_ID_SMI, PCI_DEVICE_ID_SMI_810 },
+ { }
+};
+
+
+/*******************************************************************************
+*
+* Init video chip with common Linux graphic modes (lilo)
+*/
+void *video_hw_init (void)
+{
+ GraphicDevice *pGD = (GraphicDevice *)&smi;
+ unsigned short device_id;
+ pci_dev_t devbusfn;
+ int videomode;
+ unsigned int pci_mem_base, *vm, i;
+ unsigned int gdfTab[] = { 1, 2, 2, 4, 3, 1 };
+ char *penv;
+ char *gdfModes[] =
+ {
+ "8 Bit Index Color",
+ "15 Bit 5-5-5 RGB",
+ "16 Bit 5-6-5 RGB",
+ "32 Bit X-8-8-8 RGB",
+ "24 Bit 8-8-8 RGB",
+ "8 Bit 3-3-2 RGB"
+ };
+ int vgaModes[16][2] =
+ {
+ {769, -1}, {771, 0x00002}, {773, 0x00003}, {775, 0x00004},
+ {784, -1}, {787, 0x10002}, {790, 0x10003}, {793, 0x10004},
+ {785, -1}, {788, 0x20002}, {791, 0x20003}, {794, 0x20004},
+ {786, -1}, {789, 0x40002}, {792, 0x40003}, {795, 0x40004}
+ };
+
+ /* Search for video chip */
+ printf("Video: ");
+
+ if ((devbusfn = pci_find_devices(supported, 0)) < 0)
+ {
+ printf ("Controller not found !\n");
+ return (NULL);
+ }
+
+ /* PCI setup */
+ pci_write_config_dword (devbusfn, PCI_COMMAND, (PCI_COMMAND_MEMORY | PCI_COMMAND_IO));
+ pci_read_config_word (devbusfn, PCI_DEVICE_ID, &device_id);
+ pci_read_config_dword (devbusfn, PCI_BASE_ADDRESS_0, &pci_mem_base);
+ pci_mem_base = pci_mem_to_phys (devbusfn, pci_mem_base);
+
+ /* Initialize the video controller */
+ if ((penv = getenv ("videomode")) != NULL)
+ videomode = (int)simple_strtoul (penv, NULL, 16);
+ else
+ videomode = 0x303; /* Default 800x600 8 bit index color */
+
+ /* Compare with common vga mode numbers */
+ for (i=0; i<16; i++)
+ {
+ if (vgaModes[i][0] == videomode)
+ {
+ if (vgaModes[i][1] == -1)
+ {
+ printf("Videomode not supported !\n");
+ return (NULL); /* mode not supported */
+ }
+ pGD->mode = vgaModes[i][1]; /* use driver int. mode number */
+ break;
+ }
+ }
+
+ /* Extract graphic data format */
+ pGD->gdfIndex = (pGD->mode & 0x00070000) >> 16;
+ if (pGD->gdfIndex > 5)
+ pGD->gdfIndex = 0;
+ pGD->gdfBytesPP = gdfTab[pGD->gdfIndex];
+
+ /* Extract graphic resolution */
+ pGD->mode &= 0xf;
+
+ /* Exit for not supported resolutions */
+ if (((pGD->mode==DUAL_800_600) || (pGD->mode==DUAL_1024_768)) && (pGD->gdfBytesPP > 1))
+ {
+ printf ("Dual screen for 1BPP only !\n");
+ return (NULL);
+ }
+
+ if ((pGD->mode==SINGLE_1280_1024) && (pGD->gdfBytesPP==4))
+ {
+ printf ("Out of memory !\n");
+ return (NULL);
+ }
+
+ /* Set graphic parameters */
+ switch (pGD->mode)
+ {
+ case DUAL_800_600:
+ pGD->winSizeX = 800;
+ pGD->winSizeY = 600;
+ pGD->plnSizeX = 1600;
+ pGD->plnSizeY = 600;
+ sprintf (pGD->modeIdent, "Dual Screen 800x600 with %s", gdfModes[pGD->gdfIndex]);
+ break;
+ case DUAL_1024_768:
+ pGD->winSizeX = 1024;
+ pGD->winSizeY = 768;
+ pGD->plnSizeX = 2048;
+ pGD->plnSizeY = 768;
+ sprintf (pGD->modeIdent, "Dual Screen 1024x768 with %s", gdfModes[pGD->gdfIndex]);
+ break;
+ case SINGLE_800_600:
+ pGD->winSizeX = 800;
+ pGD->winSizeY = 600;
+ pGD->plnSizeX = 800;
+ pGD->plnSizeY = 600;
+ sprintf (pGD->modeIdent, "Single Screen 800x600 with %s", gdfModes[pGD->gdfIndex]);
+ break;
+ case SINGLE_1024_768:
+ pGD->winSizeX = 1024;
+ pGD->winSizeY = 768;
+ pGD->plnSizeX = 1024;
+ pGD->plnSizeY = 768;
+ sprintf (pGD->modeIdent,"Single Screen 1024x768 with %s", gdfModes[pGD->gdfIndex]);
+ break;
+ case TV_MODE_CCIR:
+ pGD->winSizeX = 720;
+ pGD->winSizeY = 576;
+ pGD->plnSizeX = 720;
+ pGD->plnSizeY = 576;
+ sprintf (pGD->modeIdent, "TV Mode CCIR with %s", gdfModes[pGD->gdfIndex]);
+ break;
+ case TV_MODE_EIA:
+ pGD->winSizeX = 720;
+ pGD->winSizeY = 484;
+ pGD->plnSizeX = 720;
+ pGD->plnSizeY = 484;
+ sprintf (pGD->modeIdent, "TV Mode EIA with %s", gdfModes[pGD->gdfIndex]);
+ break;
+ case SINGLE_1280_1024:
+ pGD->winSizeX = 1280;
+ pGD->winSizeY = 1024;
+ pGD->plnSizeX = 1280;
+ pGD->plnSizeY = 1024;
+ sprintf (pGD->modeIdent, "Single Screen 1280x1024 with %s", gdfModes[pGD->gdfIndex]);
+ break;
+ default:
+ printf("Videomode not supported !\n");
+ return (NULL);
+ }
+
+
+ pGD->isaBase = CFG_ISA_IO;
+ pGD->pciBase = pci_mem_base;
+ pGD->dprBase = (pci_mem_base + 0x400000 + 0x8000);
+ pGD->vprBase = (pci_mem_base + 0x400000 + 0xc000);
+ pGD->cprBase = (pci_mem_base + 0x400000 + 0xe000);
+ pGD->frameAdrs = pci_mem_base;
+ pGD->memSize = VIDEO_MEM_SIZE;
+
+ /* Turn off display */
+ smiWrite (0x3c4, 0x01, 0x20);
+
+ /* Unlock ext. crt regs */
+ out8 (SMI_LOCK_REG, 0x40);
+
+ /* Set Register base to isa 3dx for 3?x regs (color mode) */
+ out8 (SMI_MISC_REG, 0x2b);
+
+ /* Unlock crt regs 0-7 */
+ smiWrite (0x3d4, 0x11, 0x0e);
+
+ /* Sytem Control Register */
+ smiLoadRegs (SMI_INDX_C4, SMI_DATA_C5,
+ SMI_SCR, sizeof(SMI_SCR));
+
+ /* extented CRT Register */
+ smiLoadRegs (SMI_INDX_D4, SMI_DATA_D5,
+ SMI_EXT_CRT[pGD->mode], sizeof(SMI_EXT_CRT)/VIDEO_MODES);
+
+ /* Sequencer Register */
+ smiLoadRegs (SMI_INDX_C4, SMI_DATA_C5,
+ SMI_SEQR, sizeof(SMI_SEQR));
+
+ /* Power Control Register */
+ smiLoadRegs (SMI_INDX_C4, SMI_DATA_C5,
+ SMI_PCR[pGD->mode], sizeof(SMI_PCR)/VIDEO_MODES);
+
+ /* Memory Control Register */
+ smiLoadRegs (SMI_INDX_C4, SMI_DATA_C5,
+ SMI_MCR[pGD->mode], sizeof(SMI_MCR)/VIDEO_MODES);
+
+ /* Clock Control Register */
+ smiLoadRegs (SMI_INDX_C4, SMI_DATA_C5,
+ SMI_CCR[pGD->mode], sizeof(SMI_CCR)/VIDEO_MODES);
+
+ /* Shadow VGA Register */
+ smiLoadRegs (SMI_INDX_D4, SMI_DATA_D5,
+ SMI_SHVGA[pGD->mode], sizeof(SMI_SHVGA)/VIDEO_MODES);
+
+ /* General Purpose Register */
+ smiLoadRegs (SMI_INDX_C4, SMI_DATA_C5,
+ SMI_GPR[pGD->mode], sizeof(SMI_GPR)/VIDEO_MODES);
+
+ /* Hardware Cusor Register */
+ smiLoadRegs (SMI_INDX_C4, SMI_DATA_C5,
+ SMI_HCR[pGD->mode], sizeof(SMI_HCR)/VIDEO_MODES);
+
+ /* Flat Panel Register */
+ smiLoadRegs (SMI_INDX_C4, SMI_DATA_C5,
+ SMI_FPR[pGD->mode], sizeof(SMI_FPR)/VIDEO_MODES);
+
+ /* CRTC Register */
+ smiLoadRegs (SMI_INDX_D4, SMI_DATA_D5,
+ SMI_CRTCR[pGD->mode], sizeof(SMI_CRTCR)/VIDEO_MODES);
+
+ /* Graphics Controller Register */
+ smiLoadRegs (SMI_INDX_CE, SMI_DATA_CF,
+ SMI_GCR, sizeof(SMI_GCR));
+
+ /* Patch memory and refresh settings for SMI710 */
+ if (device_id == PCI_DEVICE_ID_SMI_710)
+ {
+ unsigned char reg = smiRead (0x3c4, 0x62);
+
+ /* external memory disabled */
+ smiWrite (0x3c4, 0x62, (reg & 0xfb));
+ /* memory clock */
+ smiWrite (0x3c4, 0x6a, 0x75);
+ }
+
+ /* Patch memory and refresh settings for SMI712 */
+ if (device_id == PCI_DEVICE_ID_SMI_712)
+ {
+ unsigned char reg = smiRead (0x3c4, 0x62);
+
+ /* IL runs at MCLK; 64bit bus; external memory disabled */
+ smiWrite (0x3c4, 0x62, (reg | 0xc4));
+ /* memory clock */
+ smiWrite (0x3c4, 0x6a, 0x80);
+ }
+
+ /* Patch clock settings for SMI810 */
+ if (device_id == PCI_DEVICE_ID_SMI_810)
+ {
+ /* clock control */
+ smiWrite (0x3c4, 0x69, 0x03);
+ }
+
+ /* Video processor default setup */
+ smiInitVideoProcessor ();
+
+ /* Capture port default setup */
+ smiInitCapturePort ();
+
+ /* Drawing engine default setup */
+ smiInitDrawingEngine ();
+
+ /* Turn on display */
+ smiWrite (0x3c4, 0x01, 0x01);
+
+ /* Clear video memory */
+ i = pGD->memSize/4;
+ vm = (unsigned int *)pGD->pciBase;
+ while(i--)
+ *vm++ = 0;
+
+ printf("mode=%x - %s\n", videomode, pGD->modeIdent);
+ return ((void*)&smi);
+}
+
+/*******************************************************************************
+*
+* Drawing engine fill on screen region
+*/
+void video_hw_rectfill (
+ unsigned int bpp, /* bytes per pixel */
+ unsigned int dst_x, /* dest pos x */
+ unsigned int dst_y, /* dest pos y */
+ unsigned int dim_x, /* frame width */
+ unsigned int dim_y, /* frame height */
+ unsigned int color /* fill color */
+ )
+{
+ register GraphicDevice *pGD = (GraphicDevice *)&smi;
+ register unsigned int control;
+
+ dim_x *= bpp;
+
+ out32r ((pGD->dprBase + 0x0014), color);
+ out32r ((pGD->dprBase + 0x0004), ((dst_x<<16) | dst_y));
+ out32r ((pGD->dprBase + 0x0008), ((dim_x<<16) | dim_y));
+
+ control = 0x0000ffff & in32r ((pGD->dprBase + 0x000c));
+
+ control |= 0x80010000;
+
+ out32r ((pGD->dprBase + 0x000c), control);
+
+ /* Wait for drawing processor */
+ do
+ {
+ out8 ((pGD->isaBase + 0x3c4), 0x16);
+ } while (in8 (pGD->isaBase + 0x3c5) & 0x08);
+}
+
+/*******************************************************************************
+*
+* Drawing engine bitblt with screen region
+*/
+void video_hw_bitblt (
+ unsigned int bpp, /* bytes per pixel */
+ unsigned int src_x, /* source pos x */
+ unsigned int src_y, /* source pos y */
+ unsigned int dst_x, /* dest pos x */
+ unsigned int dst_y, /* dest pos y */
+ unsigned int dim_x, /* frame width */
+ unsigned int dim_y /* frame height */
+ )
+{
+ register GraphicDevice *pGD = (GraphicDevice *)&smi;
+ register unsigned int control;
+
+ dim_x *= bpp;
+
+ if ((src_y<dst_y) || ((src_y==dst_y) && (src_x<dst_x)))
+ {
+ out32r ((pGD->dprBase + 0x0000), (((src_x+dim_x-1)<<16) | (src_y+dim_y-1)));
+ out32r ((pGD->dprBase + 0x0004), (((dst_x+dim_x-1)<<16) | (dst_y+dim_y-1)));
+ control = 0x88000000;
+ }
+ else
+ {
+ out32r ((pGD->dprBase + 0x0000), ((src_x<<16) | src_y));
+ out32r ((pGD->dprBase + 0x0004), ((dst_x<<16) | dst_y));
+ control = 0x80000000;
+ }
+
+ out32r ((pGD->dprBase + 0x0008), ((dim_x<<16) | dim_y));
+ control |= (0x0000ffff & in32r ((pGD->dprBase + 0x000c)));
+ out32r ((pGD->dprBase + 0x000c), control);
+
+ /* Wait for drawing processor */
+ do
+ {
+ out8 ((pGD->isaBase + 0x3c4), 0x16);
+ } while (in8 (pGD->isaBase + 0x3c5) & 0x08);
+}
+
+/*******************************************************************************
+*
+* Set a RGB color in the LUT (8 bit index)
+*/
+void video_set_lut (
+ unsigned int index, /* color number */
+ unsigned char r, /* red */
+ unsigned char g, /* green */
+ unsigned char b /* blue */
+ )
+{
+ register GraphicDevice *pGD = (GraphicDevice *)&smi;
+
+ out8 (SMI_LUT_MASK, 0xff);
+
+ out8 (SMI_LUT_START, (char)index);
+
+ out8 (SMI_LUT_RGB, r>>2); /* red */
+ udelay (10);
+ out8 (SMI_LUT_RGB, g>>2); /* green */
+ udelay (10);
+ out8 (SMI_LUT_RGB, b>>2); /* blue */
+ udelay (10);
+}
+
+#endif /* CONFIG_VIDEO_SMI_LYNXEM */
--- /dev/null
+/******************************************************************************/
+/* */
+/* Broadcom BCM5700 Linux Network Driver, Copyright (c) 2000 Broadcom */
+/* Corporation. */
+/* All rights reserved. */
+/* */
+/* 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, located in the file LICENSE. */
+/* */
+/* History: */
+/******************************************************************************/
+#include <common.h>
+#include "bcm570x_mm.h"
+#include <asm/types.h>
+#if (CONFIG_COMMANDS & CFG_CMD_NET) && !defined(CONFIG_NET_MULTI) && \
+ defined(CONFIG_TIGON3)
+#ifdef CONFIG_BMW
+#include <mpc824x.h>
+#endif
+#include <malloc.h>
+#include <linux/byteorder/big_endian.h>
+
+#define EMBEDDED 1
+/******************************************************************************/
+/* Local functions. */
+/******************************************************************************/
+
+LM_STATUS LM_Abort(PLM_DEVICE_BLOCK pDevice);
+LM_STATUS LM_QueueRxPackets(PLM_DEVICE_BLOCK pDevice);
+
+static LM_STATUS LM_TranslateRequestedMediaType(
+ LM_REQUESTED_MEDIA_TYPE RequestedMediaType,
+ PLM_MEDIA_TYPE pMediaType, PLM_LINE_SPEED pLineSpeed,
+ PLM_DUPLEX_MODE pDuplexMode);
+
+static LM_STATUS LM_InitBcm540xPhy(PLM_DEVICE_BLOCK pDevice);
+
+__inline static LM_VOID LM_ServiceRxInterrupt(PLM_DEVICE_BLOCK pDevice);
+__inline static LM_VOID LM_ServiceTxInterrupt(PLM_DEVICE_BLOCK pDevice);
+
+static LM_STATUS LM_ForceAutoNegBcm540xPhy(PLM_DEVICE_BLOCK pDevice,
+ LM_REQUESTED_MEDIA_TYPE RequestedMediaType);
+static LM_STATUS LM_ForceAutoNeg(PLM_DEVICE_BLOCK pDevice,
+ LM_REQUESTED_MEDIA_TYPE RequestedMediaType);
+static LM_UINT32 GetPhyAdFlowCntrlSettings(PLM_DEVICE_BLOCK pDevice);
+STATIC LM_STATUS LM_SetFlowControl(PLM_DEVICE_BLOCK pDevice,
+ LM_UINT32 LocalPhyAd, LM_UINT32 RemotePhyAd);
+#if INCLUDE_TBI_SUPPORT
+STATIC LM_STATUS LM_SetupFiberPhy(PLM_DEVICE_BLOCK pDevice);
+STATIC LM_STATUS LM_InitBcm800xPhy(PLM_DEVICE_BLOCK pDevice);
+#endif
+STATIC LM_STATUS LM_SetupCopperPhy(PLM_DEVICE_BLOCK pDevice);
+STATIC PLM_ADAPTER_INFO LM_GetAdapterInfoBySsid(LM_UINT16 Svid, LM_UINT16 Ssid);
+STATIC LM_STATUS LM_DmaTest(PLM_DEVICE_BLOCK pDevice, PLM_UINT8 pBufferVirt,
+ LM_PHYSICAL_ADDRESS BufferPhy, LM_UINT32 BufferSize);
+STATIC LM_STATUS LM_HaltCpu(PLM_DEVICE_BLOCK pDevice,LM_UINT32 cpu_number);
+STATIC LM_STATUS LM_ResetChip(PLM_DEVICE_BLOCK pDevice);
+STATIC LM_STATUS LM_Test4GBoundary(PLM_DEVICE_BLOCK pDevice, PLM_PACKET pPacket,
+ PT3_SND_BD pSendBd);
+
+/******************************************************************************/
+/* External functions. */
+/******************************************************************************/
+
+LM_STATUS LM_LoadRlsFirmware(PLM_DEVICE_BLOCK pDevice);
+
+
+/******************************************************************************/
+/* Description: */
+/* */
+/* Return: */
+/******************************************************************************/
+LM_UINT32
+LM_RegRdInd(
+PLM_DEVICE_BLOCK pDevice,
+LM_UINT32 Register) {
+ LM_UINT32 Value32;
+
+#if PCIX_TARGET_WORKAROUND
+ MM_ACQUIRE_UNDI_LOCK(pDevice);
+#endif
+ MM_WriteConfig32(pDevice, T3_PCI_REG_ADDR_REG, Register);
+ MM_ReadConfig32(pDevice, T3_PCI_REG_DATA_REG, &Value32);
+#if PCIX_TARGET_WORKAROUND
+ MM_RELEASE_UNDI_LOCK(pDevice);
+#endif
+
+ return Value32;
+} /* LM_RegRdInd */
+
+
+
+/******************************************************************************/
+/* Description: */
+/* */
+/* Return: */
+/******************************************************************************/
+LM_VOID
+LM_RegWrInd(
+PLM_DEVICE_BLOCK pDevice,
+LM_UINT32 Register,
+LM_UINT32 Value32) {
+
+#if PCIX_TARGET_WORKAROUND
+ MM_ACQUIRE_UNDI_LOCK(pDevice);
+#endif
+ MM_WriteConfig32(pDevice, T3_PCI_REG_ADDR_REG, Register);
+ MM_WriteConfig32(pDevice, T3_PCI_REG_DATA_REG, Value32);
+#if PCIX_TARGET_WORKAROUND
+ MM_RELEASE_UNDI_LOCK(pDevice);
+#endif
+} /* LM_RegWrInd */
+
+
+
+/******************************************************************************/
+/* Description: */
+/* */
+/* Return: */
+/******************************************************************************/
+LM_UINT32
+LM_MemRdInd(
+PLM_DEVICE_BLOCK pDevice,
+LM_UINT32 MemAddr) {
+ LM_UINT32 Value32;
+
+ MM_ACQUIRE_UNDI_LOCK(pDevice);
+#ifdef BIG_ENDIAN_HOST
+ MM_WriteConfig32(pDevice, T3_PCI_MEM_WIN_ADDR_REG, MemAddr);
+ Value32 = REG_RD(pDevice, PciCfg.MemWindowData);
+ /* Value32 = REG_RD(pDevice,uIntMem.Mbuf[(MemAddr & 0x7fff)/4]); */
+#else
+ MM_WriteConfig32(pDevice, T3_PCI_MEM_WIN_ADDR_REG, MemAddr);
+ MM_ReadConfig32(pDevice, T3_PCI_MEM_WIN_DATA_REG, &Value32);
+#endif
+ MM_RELEASE_UNDI_LOCK(pDevice);
+
+ return Value32;
+} /* LM_MemRdInd */
+
+
+
+/******************************************************************************/
+/* Description: */
+/* */
+/* Return: */
+/******************************************************************************/
+LM_VOID
+LM_MemWrInd(
+PLM_DEVICE_BLOCK pDevice,
+LM_UINT32 MemAddr,
+LM_UINT32 Value32) {
+ MM_ACQUIRE_UNDI_LOCK(pDevice);
+#ifdef BIG_ENDIAN_HOST
+ REG_WR(pDevice,PciCfg.MemWindowBaseAddr,MemAddr);
+ REG_WR(pDevice,uIntMem.Mbuf[(MemAddr & 0x7fff)/4],Value32);
+#else
+ MM_WriteConfig32(pDevice, T3_PCI_MEM_WIN_ADDR_REG, MemAddr);
+ MM_WriteConfig32(pDevice, T3_PCI_MEM_WIN_DATA_REG, Value32);
+#endif
+ MM_RELEASE_UNDI_LOCK(pDevice);
+} /* LM_MemWrInd */
+
+
+
+/******************************************************************************/
+/* Description: */
+/* */
+/* Return: */
+/******************************************************************************/
+LM_STATUS
+LM_QueueRxPackets(
+PLM_DEVICE_BLOCK pDevice) {
+ LM_STATUS Lmstatus;
+ PLM_PACKET pPacket;
+ PT3_RCV_BD pRcvBd;
+ LM_UINT32 StdBdAdded = 0;
+#if T3_JUMBO_RCV_RCB_ENTRY_COUNT
+ LM_UINT32 JumboBdAdded = 0;
+#endif /* T3_JUMBO_RCV_RCB_ENTRY_COUNT */
+
+ Lmstatus = LM_STATUS_SUCCESS;
+
+ pPacket = (PLM_PACKET) QQ_PopHead(&pDevice->RxPacketFreeQ.Container);
+ while(pPacket) {
+ switch(pPacket->u.Rx.RcvProdRing) {
+#if T3_JUMBO_RCV_RCB_ENTRY_COUNT
+ case T3_JUMBO_RCV_PROD_RING: /* Jumbo Receive Ring. */
+ /* Initialize the buffer descriptor. */
+ pRcvBd =
+ &pDevice->pRxJumboBdVirt[pDevice->RxJumboProdIdx];
+ pRcvBd->Flags = RCV_BD_FLAG_END | RCV_BD_FLAG_JUMBO_RING;
+ pRcvBd->Len = (LM_UINT16) pDevice->RxJumboBufferSize;
+
+ /* Initialize the receive buffer pointer */
+#if 0 /* Jimmy, deleted in new */
+ pRcvBd->HostAddr.Low = pPacket->u.Rx.RxBufferPhy.Low;
+ pRcvBd->HostAddr.High = pPacket->u.Rx.RxBufferPhy.High;
+#endif
+ MM_MapRxDma(pDevice, pPacket, &pRcvBd->HostAddr);
+
+ /* The opaque field may point to an offset from a fix addr. */
+ pRcvBd->Opaque = (LM_UINT32) (MM_UINT_PTR(pPacket) -
+ MM_UINT_PTR(pDevice->pPacketDescBase));
+
+ /* Update the producer index. */
+ pDevice->RxJumboProdIdx = (pDevice->RxJumboProdIdx + 1) &
+ T3_JUMBO_RCV_RCB_ENTRY_COUNT_MASK;
+
+ JumboBdAdded++;
+ break;
+#endif /* T3_JUMBO_RCV_RCB_ENTRY_COUNT */
+
+ case T3_STD_RCV_PROD_RING: /* Standard Receive Ring. */
+ /* Initialize the buffer descriptor. */
+ pRcvBd = &pDevice->pRxStdBdVirt[pDevice->RxStdProdIdx];
+ pRcvBd->Flags = RCV_BD_FLAG_END;
+ pRcvBd->Len = MAX_STD_RCV_BUFFER_SIZE;
+
+ /* Initialize the receive buffer pointer */
+#if 0 /* Jimmy, deleted in new replaced with MM_MapRxDma */
+ pRcvBd->HostAddr.Low = pPacket->u.Rx.RxBufferPhy.Low;
+ pRcvBd->HostAddr.High = pPacket->u.Rx.RxBufferPhy.High;
+#endif
+ MM_MapRxDma(pDevice, pPacket, &pRcvBd->HostAddr);
+
+ /* The opaque field may point to an offset from a fix addr. */
+ pRcvBd->Opaque = (LM_UINT32) (MM_UINT_PTR(pPacket) -
+ MM_UINT_PTR(pDevice->pPacketDescBase));
+
+ /* Update the producer index. */
+ pDevice->RxStdProdIdx = (pDevice->RxStdProdIdx + 1) &
+ T3_STD_RCV_RCB_ENTRY_COUNT_MASK;
+
+ StdBdAdded++;
+ break;
+
+ case T3_UNKNOWN_RCV_PROD_RING:
+ default:
+ Lmstatus = LM_STATUS_FAILURE;
+ break;
+ } /* switch */
+
+ /* Bail out if there is any error. */
+ if(Lmstatus != LM_STATUS_SUCCESS)
+ {
+ break;
+ }
+
+ pPacket = (PLM_PACKET) QQ_PopHead(&pDevice->RxPacketFreeQ.Container);
+ } /* while */
+
+ wmb();
+ /* Update the procedure index. */
+ if(StdBdAdded)
+ {
+ MB_REG_WR(pDevice, Mailbox.RcvStdProdIdx.Low, pDevice->RxStdProdIdx);
+ }
+#if T3_JUMBO_RCV_RCB_ENTRY_COUNT
+ if(JumboBdAdded)
+ {
+ MB_REG_WR(pDevice, Mailbox.RcvJumboProdIdx.Low,
+ pDevice->RxJumboProdIdx);
+ }
+#endif /* T3_JUMBO_RCV_RCB_ENTRY_COUNT */
+
+ return Lmstatus;
+} /* LM_QueueRxPackets */
+
+
+/******************************************************************************/
+/* Description: */
+/* */
+/* Return: */
+/******************************************************************************/
+STATIC LM_VOID
+LM_NvramInit(
+ PLM_DEVICE_BLOCK pDevice)
+{
+ LM_UINT32 Value32;
+ LM_UINT32 j;
+
+ /* Intialize clock period and state machine. */
+ Value32 = SEEPROM_ADDR_CLK_PERD(SEEPROM_CLOCK_PERIOD) |
+ SEEPROM_ADDR_FSM_RESET;
+ REG_WR(pDevice, Grc.EepromAddr, Value32);
+
+ for(j = 0; j < 100; j++)
+ {
+ MM_Wait(10);
+ }
+
+ /* Serial eeprom access using the Grc.EepromAddr/EepromData registers. */
+ Value32 = REG_RD(pDevice, Grc.LocalCtrl);
+ REG_WR(pDevice, Grc.LocalCtrl, Value32 | GRC_MISC_LOCAL_CTRL_AUTO_SEEPROM);
+
+ /* Set the 5701 compatibility mode if we are using EEPROM. */
+ if(T3_ASIC_REV(pDevice->ChipRevId) != T3_ASIC_REV_5700 &&
+ T3_ASIC_REV(pDevice->ChipRevId) != T3_ASIC_REV_5701)
+ {
+ Value32 = REG_RD(pDevice, Nvram.Config1);
+ if((Value32 & FLASH_INTERFACE_ENABLE) == 0)
+ {
+ /* Use the new interface to read EEPROM. */
+ Value32 &= ~FLASH_COMPAT_BYPASS;
+
+ REG_WR(pDevice, Nvram.Config1, Value32);
+ }
+ }
+} /* LM_NvRamInit */
+
+
+/******************************************************************************/
+/* Description: */
+/* */
+/* Return: */
+/******************************************************************************/
+STATIC LM_STATUS
+LM_EepromRead(
+ PLM_DEVICE_BLOCK pDevice,
+ LM_UINT32 Offset,
+ LM_UINT32 *pData)
+{
+ LM_UINT32 Value32;
+ LM_UINT32 Addr;
+ LM_UINT32 Dev;
+ LM_UINT32 j;
+
+ if(Offset > SEEPROM_CHIP_SIZE)
+ {
+ return LM_STATUS_FAILURE;
+ }
+
+ Dev = Offset / SEEPROM_CHIP_SIZE;
+ Addr = Offset % SEEPROM_CHIP_SIZE;
+
+ Value32 = REG_RD(pDevice, Grc.EepromAddr);
+ Value32 &= ~(SEEPROM_ADDR_ADDRESS_MASK | SEEPROM_ADDR_DEV_ID_MASK |
+ SEEPROM_ADDR_RW_MASK);
+ REG_WR(pDevice, Grc.EepromAddr, Value32 | SEEPROM_ADDR_DEV_ID(Dev) |
+ SEEPROM_ADDR_ADDRESS(Addr) | SEEPROM_ADDR_START | SEEPROM_ADDR_READ);
+
+ for(j = 0; j < 1000; j++)
+ {
+ Value32 = REG_RD(pDevice, Grc.EepromAddr);
+ if(Value32 & SEEPROM_ADDR_COMPLETE)
+ {
+ break;
+ }
+ MM_Wait(10);
+ }
+
+ if(Value32 & SEEPROM_ADDR_COMPLETE)
+ {
+ Value32 = REG_RD(pDevice, Grc.EepromData);
+ *pData = Value32;
+
+ return LM_STATUS_SUCCESS;
+ }
+
+ return LM_STATUS_FAILURE;
+} /* LM_EepromRead */
+
+
+
+/******************************************************************************/
+/* Description: */
+/* */
+/* Return: */
+/******************************************************************************/
+STATIC LM_STATUS
+LM_NvramRead(
+ PLM_DEVICE_BLOCK pDevice,
+ LM_UINT32 Offset,
+ LM_UINT32 *pData)
+{
+ LM_UINT32 Value32;
+ LM_STATUS Status;
+ LM_UINT32 j;
+
+ if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700 ||
+ T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5701)
+ {
+ Status = LM_EepromRead(pDevice, Offset, pData);
+ }
+ else
+ {
+ /* Determine if we have flash or EEPROM. */
+ Value32 = REG_RD(pDevice, Nvram.Config1);
+ if(Value32 & FLASH_INTERFACE_ENABLE)
+ {
+ if(Value32 & FLASH_SSRAM_BUFFERRED_MODE)
+ {
+ Offset = ((Offset/BUFFERED_FLASH_PAGE_SIZE) <<
+ BUFFERED_FLASH_PAGE_POS) +
+ (Offset % BUFFERED_FLASH_PAGE_SIZE);
+ }
+ }
+
+ REG_WR(pDevice, Nvram.SwArb, SW_ARB_REQ_SET1);
+ for (j = 0; j < 1000; j++)
+ {
+ if (REG_RD(pDevice, Nvram.SwArb) & SW_ARB_GNT1)
+ {
+ break;
+ }
+ MM_Wait(20);
+ }
+ if (j == 1000)
+ {
+ return LM_STATUS_FAILURE;
+ }
+
+ /* Read from flash or EEPROM with the new 5703/02 interface. */
+ REG_WR(pDevice, Nvram.Addr, Offset & NVRAM_ADDRESS_MASK);
+
+ REG_WR(pDevice, Nvram.Cmd, NVRAM_CMD_RD | NVRAM_CMD_DO_IT |
+ NVRAM_CMD_FIRST | NVRAM_CMD_LAST | NVRAM_CMD_DONE);
+
+ /* Wait for the done bit to clear. */
+ for(j = 0; j < 500; j++)
+ {
+ MM_Wait(10);
+
+ Value32 = REG_RD(pDevice, Nvram.Cmd);
+ if(!(Value32 & NVRAM_CMD_DONE))
+ {
+ break;
+ }
+ }
+
+ /* Wait for the done bit. */
+ if(!(Value32 & NVRAM_CMD_DONE))
+ {
+ for(j = 0; j < 500; j++)
+ {
+ MM_Wait(10);
+
+ Value32 = REG_RD(pDevice, Nvram.Cmd);
+ if(Value32 & NVRAM_CMD_DONE)
+ {
+ MM_Wait(10);
+
+ *pData = REG_RD(pDevice, Nvram.ReadData);
+
+ /* Change the endianess. */
+ *pData = ((*pData & 0xff) << 24)| ((*pData & 0xff00) << 8)|
+ ((*pData & 0xff0000) >> 8) | ((*pData >> 24) & 0xff);
+
+ break;
+ }
+ }
+ }
+
+ REG_WR(pDevice, Nvram.SwArb, SW_ARB_REQ_CLR1);
+ if(Value32 & NVRAM_CMD_DONE)
+ {
+ Status = LM_STATUS_SUCCESS;
+ }
+ else
+ {
+ Status = LM_STATUS_FAILURE;
+ }
+ }
+
+ return Status;
+} /* LM_NvramRead */
+
+
+STATIC void
+LM_ReadVPD(PLM_DEVICE_BLOCK pDevice)
+{
+ LM_UINT32 Vpd_arr[256/4];
+ LM_UINT8 *Vpd = (LM_UINT8 *) &Vpd_arr[0];
+ LM_UINT32 *Vpd_dptr = &Vpd_arr[0];
+ LM_UINT32 Value32;
+ unsigned int j;
+
+ /* Read PN from VPD */
+ for (j = 0; j < 256; j += 4, Vpd_dptr++ )
+ {
+ if (LM_NvramRead(pDevice, 0x100 + j, &Value32) != LM_STATUS_SUCCESS) {
+ printf("BCM570x: LM_ReadVPD: VPD read failed"
+ " (no EEPROM onboard)\n");
+ return;
+ }
+ *Vpd_dptr = cpu_to_le32(Value32);
+ }
+ for (j = 0; j < 256; )
+ {
+ unsigned int Vpd_r_len;
+ unsigned int Vpd_r_end;
+
+ if ((Vpd[j] == 0x82) || (Vpd[j] == 0x91))
+ {
+ j = j + 3 + Vpd[j + 1] + (Vpd[j + 2] << 8);
+ }
+ else if (Vpd[j] == 0x90)
+ {
+ Vpd_r_len = Vpd[j + 1] + (Vpd[j + 2] << 8);
+ j += 3;
+ Vpd_r_end = Vpd_r_len + j;
+ while (j < Vpd_r_end)
+ {
+ if ((Vpd[j] == 'P') && (Vpd[j + 1] == 'N'))
+ {
+ unsigned int len = Vpd[j + 2];
+
+ if (len <= 24)
+ {
+ memcpy(pDevice->PartNo, &Vpd[j + 3], len);
+ }
+ break;
+ }
+ else
+ {
+ if (Vpd[j + 2] == 0)
+ {
+ break;
+ }
+ j = j + Vpd[j + 2];
+ }
+ }
+ break;
+ }
+ else {
+ break;
+ }
+ }
+}
+
+STATIC void
+LM_ReadBootCodeVersion(PLM_DEVICE_BLOCK pDevice)
+{
+ LM_UINT32 Value32, offset, ver_offset;
+ int i;
+
+ if (LM_NvramRead(pDevice, 0x0, &Value32) != LM_STATUS_SUCCESS)
+ return;
+ if (Value32 != 0xaa559966)
+ return;
+ if (LM_NvramRead(pDevice, 0xc, &offset) != LM_STATUS_SUCCESS)
+ return;
+
+ offset = ((offset & 0xff) << 24)| ((offset & 0xff00) << 8)|
+ ((offset & 0xff0000) >> 8) | ((offset >> 24) & 0xff);
+ if (LM_NvramRead(pDevice, offset, &Value32) != LM_STATUS_SUCCESS)
+ return;
+ if ((Value32 == 0x0300000e) &&
+ (LM_NvramRead(pDevice, offset + 4, &Value32) == LM_STATUS_SUCCESS) &&
+ (Value32 == 0)) {
+
+ if (LM_NvramRead(pDevice, offset + 8, &ver_offset) != LM_STATUS_SUCCESS)
+ return;
+ ver_offset = ((ver_offset & 0xff0000) >> 8) |
+ ((ver_offset >> 24) & 0xff);
+ for (i = 0; i < 16; i += 4) {
+ if (LM_NvramRead(pDevice, offset + ver_offset + i, &Value32) !=
+ LM_STATUS_SUCCESS)
+ {
+ return;
+ }
+ *((LM_UINT32 *) &pDevice->BootCodeVer[i]) = cpu_to_le32(Value32);
+ }
+ }
+ else {
+ char c;
+
+ if (LM_NvramRead(pDevice, 0x94, &Value32) != LM_STATUS_SUCCESS)
+ return;
+
+ i = 0;
+ c = ((Value32 & 0xff0000) >> 16);
+
+ if (c < 10) {
+ pDevice->BootCodeVer[i++] = c + '0';
+ }
+ else {
+ pDevice->BootCodeVer[i++] = (c / 10) + '0';
+ pDevice->BootCodeVer[i++] = (c % 10) + '0';
+ }
+ pDevice->BootCodeVer[i++] = '.';
+ c = (Value32 & 0xff000000) >> 24;
+ if (c < 10) {
+ pDevice->BootCodeVer[i++] = c + '0';
+ }
+ else {
+ pDevice->BootCodeVer[i++] = (c / 10) + '0';
+ pDevice->BootCodeVer[i++] = (c % 10) + '0';
+ }
+ pDevice->BootCodeVer[i] = 0;
+ }
+}
+
+STATIC void
+LM_GetBusSpeed(PLM_DEVICE_BLOCK pDevice)
+{
+ LM_UINT32 PciState = pDevice->PciState;
+ LM_UINT32 ClockCtrl;
+ char *SpeedStr = "";
+
+ if (PciState & T3_PCI_STATE_32BIT_PCI_BUS)
+ {
+ strcpy(pDevice->BusSpeedStr, "32-bit ");
+ }
+ else
+ {
+ strcpy(pDevice->BusSpeedStr, "64-bit ");
+ }
+ if (PciState & T3_PCI_STATE_CONVENTIONAL_PCI_MODE)
+ {
+ strcat(pDevice->BusSpeedStr, "PCI ");
+ if (PciState & T3_PCI_STATE_HIGH_BUS_SPEED)
+ {
+ SpeedStr = "66MHz";
+ }
+ else
+ {
+ SpeedStr = "33MHz";
+ }
+ }
+ else
+ {
+ strcat(pDevice->BusSpeedStr, "PCIX ");
+ if (pDevice->BondId == GRC_MISC_BD_ID_5704CIOBE)
+ {
+ SpeedStr = "133MHz";
+ }
+ else
+ {
+ ClockCtrl = REG_RD(pDevice, PciCfg.ClockCtrl) & 0x1f;
+ switch (ClockCtrl)
+ {
+ case 0:
+ SpeedStr = "33MHz";
+ break;
+
+ case 2:
+ SpeedStr = "50MHz";
+ break;
+
+ case 4:
+ SpeedStr = "66MHz";
+ break;
+
+ case 6:
+ SpeedStr = "100MHz";
+ break;
+
+ case 7:
+ SpeedStr = "133MHz";
+ break;
+ }
+ }
+ }
+ strcat(pDevice->BusSpeedStr, SpeedStr);
+}
+
+/******************************************************************************/
+/* Description: */
+/* This routine initializes default parameters and reads the PCI */
+/* configurations. */
+/* */
+/* Return: */
+/* LM_STATUS_SUCCESS */
+/******************************************************************************/
+LM_STATUS
+LM_GetAdapterInfo(
+PLM_DEVICE_BLOCK pDevice)
+{
+ PLM_ADAPTER_INFO pAdapterInfo;
+ LM_UINT32 Value32;
+ LM_STATUS Status;
+ LM_UINT32 j;
+ LM_UINT32 EeSigFound;
+ LM_UINT32 EePhyTypeSerdes = 0;
+ LM_UINT32 EePhyLedMode = 0;
+ LM_UINT32 EePhyId = 0;
+
+ /* Get Device Id and Vendor Id */
+ Status = MM_ReadConfig32(pDevice, PCI_VENDOR_ID_REG, &Value32);
+ if(Status != LM_STATUS_SUCCESS)
+ {
+ return Status;
+ }
+ pDevice->PciVendorId = (LM_UINT16) Value32;
+ pDevice->PciDeviceId = (LM_UINT16) (Value32 >> 16);
+
+ /* If we are not getting the write adapter, exit. */
+ if((Value32 != T3_PCI_ID_BCM5700) &&
+ (Value32 != T3_PCI_ID_BCM5701) &&
+ (Value32 != T3_PCI_ID_BCM5702) &&
+ (Value32 != T3_PCI_ID_BCM5702x) &&
+ (Value32 != T3_PCI_ID_BCM5702FE) &&
+ (Value32 != T3_PCI_ID_BCM5703) &&
+ (Value32 != T3_PCI_ID_BCM5703x) &&
+ (Value32 != T3_PCI_ID_BCM5704))
+ {
+ return LM_STATUS_FAILURE;
+ }
+
+ Status = MM_ReadConfig32(pDevice, PCI_REV_ID_REG, &Value32);
+ if(Status != LM_STATUS_SUCCESS)
+ {
+ return Status;
+ }
+ pDevice->PciRevId = (LM_UINT8) Value32;
+
+ /* Get IRQ. */
+ Status = MM_ReadConfig32(pDevice, PCI_INT_LINE_REG, &Value32);
+ if(Status != LM_STATUS_SUCCESS)
+ {
+ return Status;
+ }
+ pDevice->Irq = (LM_UINT8) Value32;
+
+ /* Get interrupt pin. */
+ pDevice->IntPin = (LM_UINT8) (Value32 >> 8);
+
+ /* Get chip revision id. */
+ Status = MM_ReadConfig32(pDevice, T3_PCI_MISC_HOST_CTRL_REG, &Value32);
+ pDevice->ChipRevId = Value32 >> 16;
+
+ /* Get subsystem vendor. */
+ Status = MM_ReadConfig32(pDevice, PCI_SUBSYSTEM_VENDOR_ID_REG, &Value32);
+ if(Status != LM_STATUS_SUCCESS)
+ {
+ return Status;
+ }
+ pDevice->SubsystemVendorId = (LM_UINT16) Value32;
+
+ /* Get PCI subsystem id. */
+ pDevice->SubsystemId = (LM_UINT16) (Value32 >> 16);
+
+ /* Get the cache line size. */
+ MM_ReadConfig32(pDevice, PCI_CACHE_LINE_SIZE_REG, &Value32);
+ pDevice->CacheLineSize = (LM_UINT8) Value32;
+ pDevice->SavedCacheLineReg = Value32;
+
+ if(pDevice->ChipRevId != T3_CHIP_ID_5703_A1 &&
+ pDevice->ChipRevId != T3_CHIP_ID_5703_A2 &&
+ pDevice->ChipRevId != T3_CHIP_ID_5704_A0)
+ {
+ pDevice->UndiFix = FALSE;
+ }
+#if !PCIX_TARGET_WORKAROUND
+ pDevice->UndiFix = FALSE;
+#endif
+ /* Map the memory base to system address space. */
+ if (!pDevice->UndiFix)
+ {
+ Status = MM_MapMemBase(pDevice);
+ if(Status != LM_STATUS_SUCCESS)
+ {
+ return Status;
+ }
+ /* Initialize the memory view pointer. */
+ pDevice->pMemView = (PT3_STD_MEM_MAP) pDevice->pMappedMemBase;
+ }
+
+#if PCIX_TARGET_WORKAROUND
+ /* store whether we are in PCI are PCI-X mode */
+ pDevice->EnablePciXFix = FALSE;
+
+ MM_ReadConfig32(pDevice, T3_PCI_STATE_REG, &Value32);
+ if((Value32 & T3_PCI_STATE_CONVENTIONAL_PCI_MODE) == 0)
+ {
+ /* Enable PCI-X workaround only if we are running on 5700 BX. */
+ if(T3_CHIP_REV(pDevice->ChipRevId) == T3_CHIP_REV_5700_BX)
+ {
+ pDevice->EnablePciXFix = TRUE;
+ }
+ }
+ if (pDevice->UndiFix)
+ {
+ pDevice->EnablePciXFix = TRUE;
+ }
+#endif
+ /* Bx bug: due to the "byte_enable bug" in PCI-X mode, the power */
+ /* management register may be clobbered which may cause the */
+ /* BCM5700 to go into D3 state. While in this state, we will */
+ /* not have memory mapped register access. As a workaround, we */
+ /* need to restore the device to D0 state. */
+ MM_ReadConfig32(pDevice, T3_PCI_PM_STATUS_CTRL_REG, &Value32);
+ Value32 |= T3_PM_PME_ASSERTED;
+ Value32 &= ~T3_PM_POWER_STATE_MASK;
+ Value32 |= T3_PM_POWER_STATE_D0;
+ MM_WriteConfig32(pDevice, T3_PCI_PM_STATUS_CTRL_REG, Value32);
+
+ /* read the current PCI command word */
+ MM_ReadConfig32(pDevice, PCI_COMMAND_REG, &Value32);
+
+ /* Make sure bus-mastering is enabled. */
+ Value32 |= PCI_BUSMASTER_ENABLE;
+
+#if PCIX_TARGET_WORKAROUND
+ /* if we are in PCI-X mode, also make sure mem-mapping and SERR#/PERR#
+ are enabled */
+ if (pDevice->EnablePciXFix == TRUE) {
+ Value32 |= (PCI_MEM_SPACE_ENABLE | PCI_SYSTEM_ERROR_ENABLE |
+ PCI_PARITY_ERROR_ENABLE);
+ }
+ if (pDevice->UndiFix)
+ {
+ Value32 &= ~PCI_MEM_SPACE_ENABLE;
+ }
+
+#endif
+
+ if(pDevice->EnableMWI)
+ {
+ Value32 |= PCI_MEMORY_WRITE_INVALIDATE;
+ }
+ else {
+ Value32 &= (~PCI_MEMORY_WRITE_INVALIDATE);
+ }
+
+ /* Error out if mem-mapping is NOT enabled for PCI systems */
+ if (!(Value32 | PCI_MEM_SPACE_ENABLE))
+ {
+ return LM_STATUS_FAILURE;
+ }
+
+ /* save the value we are going to write into the PCI command word */
+ pDevice->PciCommandStatusWords = Value32;
+
+ Status = MM_WriteConfig32(pDevice, PCI_COMMAND_REG, Value32);
+ if(Status != LM_STATUS_SUCCESS)
+ {
+ return Status;
+ }
+
+ /* Set power state to D0. */
+ LM_SetPowerState(pDevice, LM_POWER_STATE_D0);
+
+#ifdef BIG_ENDIAN_PCI
+ pDevice->MiscHostCtrl =
+ MISC_HOST_CTRL_MASK_PCI_INT |
+ MISC_HOST_CTRL_ENABLE_INDIRECT_ACCESS |
+ MISC_HOST_CTRL_ENABLE_ENDIAN_WORD_SWAP |
+ MISC_HOST_CTRL_ENABLE_PCI_STATE_REG_RW;
+#else /* No CPU Swap modes for PCI IO */
+
+ /* Setup the mode registers. */
+ pDevice->MiscHostCtrl =
+ MISC_HOST_CTRL_MASK_PCI_INT |
+ MISC_HOST_CTRL_ENABLE_ENDIAN_WORD_SWAP |
+#ifdef BIG_ENDIAN_HOST
+ MISC_HOST_CTRL_ENABLE_ENDIAN_BYTE_SWAP |
+#endif /* BIG_ENDIAN_HOST */
+ MISC_HOST_CTRL_ENABLE_INDIRECT_ACCESS |
+ MISC_HOST_CTRL_ENABLE_PCI_STATE_REG_RW;
+#endif /* !BIG_ENDIAN_PCI */
+
+ /* write to PCI misc host ctr first in order to enable indirect accesses */
+ MM_WriteConfig32(pDevice, T3_PCI_MISC_HOST_CTRL_REG, pDevice->MiscHostCtrl);
+
+ REG_WR(pDevice, PciCfg.MiscHostCtrl, pDevice->MiscHostCtrl);
+
+#ifdef BIG_ENDIAN_PCI
+ Value32 = GRC_MODE_WORD_SWAP_DATA|
+ GRC_MODE_WORD_SWAP_NON_FRAME_DATA;
+#else
+/* No CPU Swap modes for PCI IO */
+#ifdef BIG_ENDIAN_HOST
+ Value32 = GRC_MODE_BYTE_SWAP_NON_FRAME_DATA |
+ GRC_MODE_WORD_SWAP_NON_FRAME_DATA;
+#else
+ Value32 = GRC_MODE_BYTE_SWAP_NON_FRAME_DATA | GRC_MODE_BYTE_SWAP_DATA;
+#endif
+#endif /* !BIG_ENDIAN_PCI */
+
+ REG_WR(pDevice, Grc.Mode, Value32);
+
+ if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700)
+ {
+ REG_WR(pDevice, Grc.LocalCtrl, GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT1 |
+ GRC_MISC_LOCAL_CTRL_GPIO_OE1);
+ }
+ MM_Wait(40);
+
+ /* Enable indirect memory access */
+ REG_WR(pDevice, MemArbiter.Mode, T3_MEM_ARBITER_MODE_ENABLE);
+
+ if (REG_RD(pDevice, PciCfg.ClockCtrl) & T3_PCI_44MHZ_CORE_CLOCK)
+ {
+ REG_WR(pDevice, PciCfg.ClockCtrl, T3_PCI_44MHZ_CORE_CLOCK |
+ T3_PCI_SELECT_ALTERNATE_CLOCK);
+ REG_WR(pDevice, PciCfg.ClockCtrl, T3_PCI_SELECT_ALTERNATE_CLOCK);
+ MM_Wait(40); /* required delay is 27usec */
+ }
+ REG_WR(pDevice, PciCfg.ClockCtrl, 0);
+ REG_WR(pDevice, PciCfg.MemWindowBaseAddr, 0);
+
+#if PCIX_TARGET_WORKAROUND
+ MM_ReadConfig32(pDevice, T3_PCI_STATE_REG, &Value32);
+ if ((pDevice->EnablePciXFix == FALSE) &&
+ ((Value32 & T3_PCI_STATE_CONVENTIONAL_PCI_MODE) == 0))
+ {
+ if (pDevice->ChipRevId == T3_CHIP_ID_5701_A0 ||
+ pDevice->ChipRevId == T3_CHIP_ID_5701_B0 ||
+ pDevice->ChipRevId == T3_CHIP_ID_5701_B2 ||
+ pDevice->ChipRevId == T3_CHIP_ID_5701_B5)
+ {
+ __raw_writel(0, &(pDevice->pMemView->uIntMem.MemBlock32K[0x300]));
+ __raw_writel(0, &(pDevice->pMemView->uIntMem.MemBlock32K[0x301]));
+ __raw_writel(0xffffffff, &(pDevice->pMemView->uIntMem.MemBlock32K[0x301]));
+ if (__raw_readl(&(pDevice->pMemView->uIntMem.MemBlock32K[0x300])))
+ {
+ pDevice->EnablePciXFix = TRUE;
+ }
+ }
+ }
+#endif
+#if 1
+ /*
+ * This code was at the beginning of else block below, but that's
+ * a bug if node address in shared memory.
+ */
+ MM_Wait(50);
+ LM_NvramInit(pDevice);
+#endif
+ /* Get the node address. First try to get in from the shared memory. */
+ /* If the signature is not present, then get it from the NVRAM. */
+ Value32 = MEM_RD_OFFSET(pDevice, T3_MAC_ADDR_HIGH_MAILBOX);
+ if((Value32 >> 16) == 0x484b)
+ {
+
+ pDevice->NodeAddress[0] = (LM_UINT8) (Value32 >> 8);
+ pDevice->NodeAddress[1] = (LM_UINT8) Value32;
+
+ Value32 = MEM_RD_OFFSET(pDevice, T3_MAC_ADDR_LOW_MAILBOX);
+
+ pDevice->NodeAddress[2] = (LM_UINT8) (Value32 >> 24);
+ pDevice->NodeAddress[3] = (LM_UINT8) (Value32 >> 16);
+ pDevice->NodeAddress[4] = (LM_UINT8) (Value32 >> 8);
+ pDevice->NodeAddress[5] = (LM_UINT8) Value32;
+
+ Status = LM_STATUS_SUCCESS;
+ }
+ else
+ {
+ Status = LM_NvramRead(pDevice, 0x7c, &Value32);
+ if(Status == LM_STATUS_SUCCESS)
+ {
+ pDevice->NodeAddress[0] = (LM_UINT8) (Value32 >> 16);
+ pDevice->NodeAddress[1] = (LM_UINT8) (Value32 >> 24);
+
+ Status = LM_NvramRead(pDevice, 0x80, &Value32);
+
+ pDevice->NodeAddress[2] = (LM_UINT8) Value32;
+ pDevice->NodeAddress[3] = (LM_UINT8) (Value32 >> 8);
+ pDevice->NodeAddress[4] = (LM_UINT8) (Value32 >> 16);
+ pDevice->NodeAddress[5] = (LM_UINT8) (Value32 >> 24);
+ }
+ }
+
+ /* Assign a default address. */
+ if(Status != LM_STATUS_SUCCESS)
+ {
+#ifndef EMBEDDED
+ printk(KERN_ERR "Cannot get MAC addr from NVRAM. Using default.\n");
+#endif
+ pDevice->NodeAddress[0] = 0x00; pDevice->NodeAddress[1] = 0x10;
+ pDevice->NodeAddress[2] = 0x18; pDevice->NodeAddress[3] = 0x68;
+ pDevice->NodeAddress[4] = 0x61; pDevice->NodeAddress[5] = 0x76;
+ }
+
+ pDevice->PermanentNodeAddress[0] = pDevice->NodeAddress[0];
+ pDevice->PermanentNodeAddress[1] = pDevice->NodeAddress[1];
+ pDevice->PermanentNodeAddress[2] = pDevice->NodeAddress[2];
+ pDevice->PermanentNodeAddress[3] = pDevice->NodeAddress[3];
+ pDevice->PermanentNodeAddress[4] = pDevice->NodeAddress[4];
+ pDevice->PermanentNodeAddress[5] = pDevice->NodeAddress[5];
+
+ /* Initialize the default values. */
+ pDevice->NoTxPseudoHdrChksum = FALSE;
+ pDevice->NoRxPseudoHdrChksum = FALSE;
+ pDevice->NicSendBd = FALSE;
+ pDevice->TxPacketDescCnt = DEFAULT_TX_PACKET_DESC_COUNT;
+ pDevice->RxStdDescCnt = DEFAULT_STD_RCV_DESC_COUNT;
+ pDevice->RxCoalescingTicks = DEFAULT_RX_COALESCING_TICKS;
+ pDevice->TxCoalescingTicks = DEFAULT_TX_COALESCING_TICKS;
+ pDevice->RxMaxCoalescedFrames = DEFAULT_RX_MAX_COALESCED_FRAMES;
+ pDevice->TxMaxCoalescedFrames = DEFAULT_TX_MAX_COALESCED_FRAMES;
+ pDevice->RxCoalescingTicksDuringInt = BAD_DEFAULT_VALUE;
+ pDevice->TxCoalescingTicksDuringInt = BAD_DEFAULT_VALUE;
+ pDevice->RxMaxCoalescedFramesDuringInt = BAD_DEFAULT_VALUE;
+ pDevice->TxMaxCoalescedFramesDuringInt = BAD_DEFAULT_VALUE;
+ pDevice->StatsCoalescingTicks = DEFAULT_STATS_COALESCING_TICKS;
+ pDevice->EnableMWI = FALSE;
+ pDevice->TxMtu = MAX_ETHERNET_PACKET_SIZE_NO_CRC;
+ pDevice->RxMtu = MAX_ETHERNET_PACKET_SIZE_NO_CRC;
+ pDevice->DisableAutoNeg = FALSE;
+ pDevice->PhyIntMode = T3_PHY_INT_MODE_AUTO;
+ pDevice->LinkChngMode = T3_LINK_CHNG_MODE_AUTO;
+ pDevice->LedMode = LED_MODE_AUTO;
+ pDevice->ResetPhyOnInit = TRUE;
+ pDevice->DelayPciGrant = TRUE;
+ pDevice->UseTaggedStatus = FALSE;
+ pDevice->OneDmaAtOnce = BAD_DEFAULT_VALUE;
+
+ pDevice->DmaMbufLowMark = T3_DEF_DMA_MBUF_LOW_WMARK_JUMBO;
+ pDevice->RxMacMbufLowMark = T3_DEF_RX_MAC_MBUF_LOW_WMARK_JUMBO;
+ pDevice->MbufHighMark = T3_DEF_MBUF_HIGH_WMARK_JUMBO;
+
+ pDevice->RequestedMediaType = LM_REQUESTED_MEDIA_TYPE_AUTO;
+ pDevice->TaskOffloadCap = LM_TASK_OFFLOAD_NONE;
+ pDevice->FlowControlCap = LM_FLOW_CONTROL_AUTO_PAUSE;
+ pDevice->EnableTbi = FALSE;
+#if INCLUDE_TBI_SUPPORT
+ pDevice->PollTbiLink = BAD_DEFAULT_VALUE;
+#endif
+
+ switch (T3_ASIC_REV(pDevice->ChipRevId))
+ {
+ case T3_ASIC_REV_5704:
+ pDevice->MbufBase = T3_NIC_MBUF_POOL_ADDR;
+ pDevice->MbufSize = T3_NIC_MBUF_POOL_SIZE64;
+ break;
+ default:
+ pDevice->MbufBase = T3_NIC_MBUF_POOL_ADDR;
+ pDevice->MbufSize = T3_NIC_MBUF_POOL_SIZE96;
+ break;
+ }
+
+ pDevice->LinkStatus = LM_STATUS_LINK_DOWN;
+ pDevice->QueueRxPackets = TRUE;
+
+ pDevice->EnableWireSpeed = TRUE;
+
+#if T3_JUMBO_RCV_RCB_ENTRY_COUNT
+ pDevice->RxJumboDescCnt = DEFAULT_JUMBO_RCV_DESC_COUNT;
+#endif /* T3_JUMBO_RCV_RCB_ENTRY_COUNT */
+
+ /* Make this is a known adapter. */
+ pAdapterInfo = LM_GetAdapterInfoBySsid(pDevice->SubsystemVendorId,
+ pDevice->SubsystemId);
+
+ pDevice->BondId = REG_RD(pDevice, Grc.MiscCfg) & GRC_MISC_BD_ID_MASK;
+ if (pDevice->BondId != GRC_MISC_BD_ID_5700 &&
+ pDevice->BondId != GRC_MISC_BD_ID_5701 &&
+ pDevice->BondId != GRC_MISC_BD_ID_5702FE &&
+ pDevice->BondId != GRC_MISC_BD_ID_5703 &&
+ pDevice->BondId != GRC_MISC_BD_ID_5703S &&
+ pDevice->BondId != GRC_MISC_BD_ID_5704 &&
+ pDevice->BondId != GRC_MISC_BD_ID_5704CIOBE)
+ {
+ return LM_STATUS_UNKNOWN_ADAPTER;
+ }
+
+ pDevice->SplitModeEnable = SPLIT_MODE_DISABLE;
+ if ((pDevice->ChipRevId == T3_CHIP_ID_5704_A0) &&
+ (pDevice->BondId == GRC_MISC_BD_ID_5704CIOBE))
+ {
+ pDevice->SplitModeEnable = SPLIT_MODE_ENABLE;
+ pDevice->SplitModeMaxReq = SPLIT_MODE_5704_MAX_REQ;
+ }
+
+ /* Get Eeprom info. */
+ Value32 = MEM_RD_OFFSET(pDevice, T3_NIC_DATA_SIG_ADDR);
+ if (Value32 == T3_NIC_DATA_SIG)
+ {
+ EeSigFound = TRUE;
+ Value32 = MEM_RD_OFFSET(pDevice, T3_NIC_DATA_NIC_CFG_ADDR);
+
+ /* Determine PHY type. */
+ switch (Value32 & T3_NIC_CFG_PHY_TYPE_MASK)
+ {
+ case T3_NIC_CFG_PHY_TYPE_COPPER:
+ EePhyTypeSerdes = FALSE;
+ break;
+
+ case T3_NIC_CFG_PHY_TYPE_FIBER:
+ EePhyTypeSerdes = TRUE;
+ break;
+
+ default:
+ EePhyTypeSerdes = FALSE;
+ break;
+ }
+
+ /* Determine PHY led mode. */
+ if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700 ||
+ T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5701)
+ {
+ switch(Value32 & T3_NIC_CFG_LED_MODE_MASK)
+ {
+ case T3_NIC_CFG_LED_MODE_TRIPLE_SPEED:
+ EePhyLedMode = LED_MODE_THREE_LINK;
+ break;
+
+ case T3_NIC_CFG_LED_MODE_LINK_SPEED:
+ EePhyLedMode = LED_MODE_LINK10;
+ break;
+
+ default:
+ EePhyLedMode = LED_MODE_AUTO;
+ break;
+ }
+ }
+ else
+ {
+ switch(Value32 & T3_NIC_CFG_LED_MODE_MASK)
+ {
+ case T3_NIC_CFG_LED_MODE_OPEN_DRAIN:
+ EePhyLedMode = LED_MODE_OPEN_DRAIN;
+ break;
+
+ case T3_NIC_CFG_LED_MODE_OUTPUT:
+ EePhyLedMode = LED_MODE_OUTPUT;
+ break;
+
+ default:
+ EePhyLedMode = LED_MODE_AUTO;
+ break;
+ }
+ }
+ if(pDevice->ChipRevId == T3_CHIP_ID_5703_A1 ||
+ pDevice->ChipRevId == T3_CHIP_ID_5703_A2)
+ {
+ /* Enable EEPROM write protection. */
+ if(Value32 & T3_NIC_EEPROM_WP)
+ {
+ pDevice->EepromWp = TRUE;
+ }
+ }
+
+ /* Get the PHY Id. */
+ Value32 = MEM_RD_OFFSET(pDevice, T3_NIC_DATA_PHY_ID_ADDR);
+ if (Value32)
+ {
+ EePhyId = (((Value32 & T3_NIC_PHY_ID1_MASK) >> 16) &
+ PHY_ID1_OUI_MASK) << 10;
+
+ Value32 = Value32 & T3_NIC_PHY_ID2_MASK;
+
+ EePhyId |= ((Value32 & PHY_ID2_OUI_MASK) << 16) |
+ (Value32 & PHY_ID2_MODEL_MASK) | (Value32 & PHY_ID2_REV_MASK);
+ }
+ else
+ {
+ EePhyId = 0;
+ }
+ }
+ else
+ {
+ EeSigFound = FALSE;
+ }
+
+ /* Set the PHY address. */
+ pDevice->PhyAddr = PHY_DEVICE_ID;
+
+ /* Disable auto polling. */
+ pDevice->MiMode = 0xc0000;
+ REG_WR(pDevice, MacCtrl.MiMode, pDevice->MiMode);
+ MM_Wait(40);
+
+ /* Get the PHY id. */
+ LM_ReadPhy(pDevice, PHY_ID1_REG, &Value32);
+ pDevice->PhyId = (Value32 & PHY_ID1_OUI_MASK) << 10;
+
+ LM_ReadPhy(pDevice, PHY_ID2_REG, &Value32);
+ pDevice->PhyId |= ((Value32 & PHY_ID2_OUI_MASK) << 16) |
+ (Value32 & PHY_ID2_MODEL_MASK) | (Value32 & PHY_ID2_REV_MASK);
+
+ /* Set the EnableTbi flag to false if we have a copper PHY. */
+ switch(pDevice->PhyId & PHY_ID_MASK)
+ {
+ case PHY_BCM5400_PHY_ID:
+ pDevice->EnableTbi = FALSE;
+ break;
+
+ case PHY_BCM5401_PHY_ID:
+ pDevice->EnableTbi = FALSE;
+ break;
+
+ case PHY_BCM5411_PHY_ID:
+ pDevice->EnableTbi = FALSE;
+ break;
+
+ case PHY_BCM5701_PHY_ID:
+ pDevice->EnableTbi = FALSE;
+ break;
+
+ case PHY_BCM5703_PHY_ID:
+ pDevice->EnableTbi = FALSE;
+ break;
+
+ case PHY_BCM5704_PHY_ID:
+ pDevice->EnableTbi = FALSE;
+ break;
+
+ case PHY_BCM8002_PHY_ID:
+ pDevice->EnableTbi = TRUE;
+ break;
+
+ default:
+
+ if (pAdapterInfo)
+ {
+ pDevice->PhyId = pAdapterInfo->PhyId;
+ pDevice->EnableTbi = pAdapterInfo->Serdes;
+ }
+ else if (EeSigFound)
+ {
+ pDevice->PhyId = EePhyId;
+ pDevice->EnableTbi = EePhyTypeSerdes;
+ }
+ break;
+ }
+
+ /* Bail out if we don't know the copper PHY id. */
+ if(UNKNOWN_PHY_ID(pDevice->PhyId) && !pDevice->EnableTbi)
+ {
+ return LM_STATUS_FAILURE;
+ }
+
+ if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5703)
+ {
+ if((pDevice->SavedCacheLineReg & 0xff00) < 0x4000)
+ {
+ pDevice->SavedCacheLineReg &= 0xffff00ff;
+ pDevice->SavedCacheLineReg |= 0x4000;
+ }
+ }
+ /* Change driver parameters. */
+ Status = MM_GetConfig(pDevice);
+ if(Status != LM_STATUS_SUCCESS)
+ {
+ return Status;
+ }
+
+#if INCLUDE_5701_AX_FIX
+ if (pDevice->ChipRevId == T3_CHIP_ID_5701_A0 ||
+ pDevice->ChipRevId == T3_CHIP_ID_5701_B0)
+ {
+ pDevice->ResetPhyOnInit = TRUE;
+ }
+#endif
+
+ /* Save the current phy link status. */
+ if(!pDevice->EnableTbi)
+ {
+ LM_ReadPhy(pDevice, PHY_STATUS_REG, &Value32);
+ LM_ReadPhy(pDevice, PHY_STATUS_REG, &Value32);
+
+ /* If we don't have link reset the PHY. */
+ if(!(Value32 & PHY_STATUS_LINK_PASS) || pDevice->ResetPhyOnInit)
+ {
+
+ LM_WritePhy(pDevice, PHY_CTRL_REG, PHY_CTRL_PHY_RESET);
+
+ for(j = 0; j < 100; j++)
+ {
+ MM_Wait(10);
+
+ LM_ReadPhy(pDevice, PHY_CTRL_REG, &Value32);
+ if(Value32 && !(Value32 & PHY_CTRL_PHY_RESET))
+ {
+ MM_Wait(40);
+ break;
+ }
+ }
+
+
+#if INCLUDE_5701_AX_FIX
+ /* 5701_AX_BX bug: only advertises 10mb speed. */
+ if(pDevice->ChipRevId == T3_CHIP_ID_5701_A0 ||
+ pDevice->ChipRevId == T3_CHIP_ID_5701_B0)
+ {
+
+ Value32 = PHY_AN_AD_PROTOCOL_802_3_CSMA_CD |
+ PHY_AN_AD_10BASET_HALF | PHY_AN_AD_10BASET_FULL |
+ PHY_AN_AD_100BASETX_FULL | PHY_AN_AD_100BASETX_HALF;
+ Value32 |= GetPhyAdFlowCntrlSettings(pDevice);
+ LM_WritePhy(pDevice, PHY_AN_AD_REG, Value32);
+ pDevice->advertising = Value32;
+
+ Value32 = BCM540X_AN_AD_1000BASET_HALF |
+ BCM540X_AN_AD_1000BASET_FULL | BCM540X_CONFIG_AS_MASTER |
+ BCM540X_ENABLE_CONFIG_AS_MASTER;
+ LM_WritePhy(pDevice, BCM540X_1000BASET_CTRL_REG, Value32);
+ pDevice->advertising1000 = Value32;
+
+ LM_WritePhy(pDevice, PHY_CTRL_REG, PHY_CTRL_AUTO_NEG_ENABLE |
+ PHY_CTRL_RESTART_AUTO_NEG);
+ }
+#endif
+ if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5703)
+ {
+ LM_WritePhy(pDevice, 0x18, 0x0c00);
+ LM_WritePhy(pDevice, 0x17, 0x201f);
+ LM_WritePhy(pDevice, 0x15, 0x2aaa);
+ }
+ if(pDevice->ChipRevId == T3_CHIP_ID_5704_A0)
+ {
+ LM_WritePhy(pDevice, 0x1c, 0x8d68);
+ LM_WritePhy(pDevice, 0x1c, 0x8d68);
+ }
+ /* Enable Ethernet@WireSpeed. */
+ if(pDevice->EnableWireSpeed)
+ {
+ LM_WritePhy(pDevice, 0x18, 0x7007);
+ LM_ReadPhy(pDevice, 0x18, &Value32);
+ LM_WritePhy(pDevice, 0x18, Value32 | BIT_15 | BIT_4);
+ }
+ }
+ }
+
+ /* Turn off tap power management. */
+ if((pDevice->PhyId & PHY_ID_MASK) == PHY_BCM5401_PHY_ID)
+ {
+ LM_WritePhy(pDevice, BCM5401_AUX_CTRL, 0x0c20);
+ LM_WritePhy(pDevice, BCM540X_DSP_ADDRESS_REG, 0x0012);
+ LM_WritePhy(pDevice, BCM540X_DSP_RW_PORT, 0x1804);
+ LM_WritePhy(pDevice, BCM540X_DSP_ADDRESS_REG, 0x0013);
+ LM_WritePhy(pDevice, BCM540X_DSP_RW_PORT, 0x1204);
+ LM_WritePhy(pDevice, BCM540X_DSP_ADDRESS_REG, 0x8006);
+ LM_WritePhy(pDevice, BCM540X_DSP_RW_PORT, 0x0132);
+ LM_WritePhy(pDevice, BCM540X_DSP_ADDRESS_REG, 0x8006);
+ LM_WritePhy(pDevice, BCM540X_DSP_RW_PORT, 0x0232);
+ LM_WritePhy(pDevice, BCM540X_DSP_ADDRESS_REG, 0x201f);
+ LM_WritePhy(pDevice, BCM540X_DSP_RW_PORT, 0x0a20);
+
+ MM_Wait(40);
+ }
+
+#if INCLUDE_TBI_SUPPORT
+ pDevice->IgnoreTbiLinkChange = FALSE;
+
+ if(pDevice->EnableTbi)
+ {
+ pDevice->WakeUpModeCap = LM_WAKE_UP_MODE_NONE;
+ pDevice->PhyIntMode = T3_PHY_INT_MODE_LINK_READY;
+ if ((pDevice->PollTbiLink == BAD_DEFAULT_VALUE) ||
+ pDevice->DisableAutoNeg)
+ {
+ pDevice->PollTbiLink = FALSE;
+ }
+ }
+ else
+ {
+ pDevice->PollTbiLink = FALSE;
+ }
+#endif /* INCLUDE_TBI_SUPPORT */
+
+ /* UseTaggedStatus is only valid for 5701 and later. */
+ if (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700)
+ {
+ pDevice->UseTaggedStatus = FALSE;
+
+ pDevice->CoalesceMode = 0;
+ }
+ else
+ {
+ pDevice->CoalesceMode = HOST_COALESCE_CLEAR_TICKS_ON_RX_BD_EVENT |
+ HOST_COALESCE_CLEAR_TICKS_ON_TX_BD_EVENT;
+ }
+
+ /* Set the status block size. */
+ if(T3_CHIP_REV(pDevice->ChipRevId) != T3_CHIP_REV_5700_AX &&
+ T3_CHIP_REV(pDevice->ChipRevId) != T3_CHIP_REV_5700_BX)
+ {
+ pDevice->CoalesceMode |= HOST_COALESCE_32_BYTE_STATUS_MODE;
+ }
+
+ /* Check the DURING_INT coalescing ticks parameters. */
+ if(pDevice->UseTaggedStatus)
+ {
+ if(pDevice->RxCoalescingTicksDuringInt == BAD_DEFAULT_VALUE)
+ {
+ pDevice->RxCoalescingTicksDuringInt =
+ DEFAULT_RX_COALESCING_TICKS_DURING_INT;
+ }
+
+ if(pDevice->TxCoalescingTicksDuringInt == BAD_DEFAULT_VALUE)
+ {
+ pDevice->TxCoalescingTicksDuringInt =
+ DEFAULT_TX_COALESCING_TICKS_DURING_INT;
+ }
+
+ if(pDevice->RxMaxCoalescedFramesDuringInt == BAD_DEFAULT_VALUE)
+ {
+ pDevice->RxMaxCoalescedFramesDuringInt =
+ DEFAULT_RX_MAX_COALESCED_FRAMES_DURING_INT;
+ }
+
+ if(pDevice->TxMaxCoalescedFramesDuringInt == BAD_DEFAULT_VALUE)
+ {
+ pDevice->TxMaxCoalescedFramesDuringInt =
+ DEFAULT_TX_MAX_COALESCED_FRAMES_DURING_INT;
+ }
+ }
+ else
+ {
+ if(pDevice->RxCoalescingTicksDuringInt == BAD_DEFAULT_VALUE)
+ {
+ pDevice->RxCoalescingTicksDuringInt = 0;
+ }
+
+ if(pDevice->TxCoalescingTicksDuringInt == BAD_DEFAULT_VALUE)
+ {
+ pDevice->TxCoalescingTicksDuringInt = 0;
+ }
+
+ if(pDevice->RxMaxCoalescedFramesDuringInt == BAD_DEFAULT_VALUE)
+ {
+ pDevice->RxMaxCoalescedFramesDuringInt = 0;
+ }
+
+ if(pDevice->TxMaxCoalescedFramesDuringInt == BAD_DEFAULT_VALUE)
+ {
+ pDevice->TxMaxCoalescedFramesDuringInt = 0;
+ }
+ }
+
+#if T3_JUMBO_RCV_RCB_ENTRY_COUNT
+ if(pDevice->RxMtu <= (MAX_STD_RCV_BUFFER_SIZE - 8 /* CRC */))
+ {
+ pDevice->RxJumboDescCnt = 0;
+ if(pDevice->RxMtu <= MAX_ETHERNET_PACKET_SIZE_NO_CRC)
+ {
+ pDevice->RxMtu = MAX_ETHERNET_PACKET_SIZE_NO_CRC;
+ }
+ }
+ else
+ {
+ pDevice->RxJumboBufferSize = (pDevice->RxMtu + 8 /* CRC + VLAN */ +
+ COMMON_CACHE_LINE_SIZE-1) & ~COMMON_CACHE_LINE_MASK;
+
+ if(pDevice->RxJumboBufferSize > MAX_JUMBO_RCV_BUFFER_SIZE)
+ {
+ pDevice->RxJumboBufferSize = DEFAULT_JUMBO_RCV_BUFFER_SIZE;
+ pDevice->RxMtu = pDevice->RxJumboBufferSize - 8 /* CRC + VLAN */;
+ }
+ pDevice->TxMtu = pDevice->RxMtu;
+
+ }
+#else
+ pDevice->RxMtu = MAX_ETHERNET_PACKET_SIZE_NO_CRC;
+#endif /* T3_JUMBO_RCV_RCB_ENTRY_COUNT */
+
+ pDevice->RxPacketDescCnt =
+#if T3_JUMBO_RCV_RCB_ENTRY_COUNT
+ pDevice->RxJumboDescCnt +
+#endif /* T3_JUMBO_RCV_RCB_ENTRY_COUNT */
+ pDevice->RxStdDescCnt;
+
+ if(pDevice->TxMtu < MAX_ETHERNET_PACKET_SIZE_NO_CRC)
+ {
+ pDevice->TxMtu = MAX_ETHERNET_PACKET_SIZE_NO_CRC;
+ }
+
+ if(pDevice->TxMtu > MAX_JUMBO_TX_BUFFER_SIZE)
+ {
+ pDevice->TxMtu = MAX_JUMBO_TX_BUFFER_SIZE;
+ }
+
+ /* Configure the proper ways to get link change interrupt. */
+ if(pDevice->PhyIntMode == T3_PHY_INT_MODE_AUTO)
+ {
+ if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700)
+ {
+ pDevice->PhyIntMode = T3_PHY_INT_MODE_MI_INTERRUPT;
+ }
+ else
+ {
+ pDevice->PhyIntMode = T3_PHY_INT_MODE_LINK_READY;
+ }
+ }
+ else if(pDevice->PhyIntMode == T3_PHY_INT_MODE_AUTO_POLLING)
+ {
+ /* Auto-polling does not work on 5700_AX and 5700_BX. */
+ if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700)
+ {
+ pDevice->PhyIntMode = T3_PHY_INT_MODE_MI_INTERRUPT;
+ }
+ }
+
+ /* Determine the method to get link change status. */
+ if(pDevice->LinkChngMode == T3_LINK_CHNG_MODE_AUTO)
+ {
+ /* The link status bit in the status block does not work on 5700_AX */
+ /* and 5700_BX chips. */
+ if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700)
+ {
+ pDevice->LinkChngMode = T3_LINK_CHNG_MODE_USE_STATUS_REG;
+ }
+ else
+ {
+ pDevice->LinkChngMode = T3_LINK_CHNG_MODE_USE_STATUS_BLOCK;
+ }
+ }
+
+ if(pDevice->PhyIntMode == T3_PHY_INT_MODE_MI_INTERRUPT ||
+ T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700)
+ {
+ pDevice->LinkChngMode = T3_LINK_CHNG_MODE_USE_STATUS_REG;
+ }
+
+ /* Configure PHY led mode. */
+ if(pDevice->LedMode == LED_MODE_AUTO)
+ {
+ if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700 ||
+ T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5701)
+ {
+ if(pDevice->SubsystemVendorId == T3_SVID_DELL)
+ {
+ pDevice->LedMode = LED_MODE_LINK10;
+ }
+ else
+ {
+ pDevice->LedMode = LED_MODE_THREE_LINK;
+
+ if(EeSigFound && EePhyLedMode != LED_MODE_AUTO)
+ {
+ pDevice->LedMode = EePhyLedMode;
+ }
+ }
+
+ /* bug? 5701 in LINK10 mode does not seem to work when */
+ /* PhyIntMode is LINK_READY. */
+ if(T3_ASIC_REV(pDevice->ChipRevId) != T3_ASIC_REV_5700 &&
+#if INCLUDE_TBI_SUPPORT
+ pDevice->EnableTbi == FALSE &&
+#endif
+ pDevice->LedMode == LED_MODE_LINK10)
+ {
+ pDevice->PhyIntMode = T3_PHY_INT_MODE_MI_INTERRUPT;
+ pDevice->LinkChngMode = T3_LINK_CHNG_MODE_USE_STATUS_REG;
+ }
+
+ if(pDevice->EnableTbi)
+ {
+ pDevice->LedMode = LED_MODE_THREE_LINK;
+ }
+ }
+ else
+ {
+ if(EeSigFound && EePhyLedMode != LED_MODE_AUTO)
+ {
+ pDevice->LedMode = EePhyLedMode;
+ }
+ else
+ {
+ pDevice->LedMode = LED_MODE_OPEN_DRAIN;
+ }
+ }
+ }
+
+ /* Enable OneDmaAtOnce. */
+ if(pDevice->OneDmaAtOnce == BAD_DEFAULT_VALUE)
+ {
+ pDevice->OneDmaAtOnce = FALSE;
+ }
+
+ if (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700 ||
+ pDevice->ChipRevId == T3_CHIP_ID_5701_A0 ||
+ pDevice->ChipRevId == T3_CHIP_ID_5701_B0 ||
+ pDevice->ChipRevId == T3_CHIP_ID_5701_B2)
+ {
+ pDevice->WolSpeed = WOL_SPEED_10MB;
+ }
+ else
+ {
+ pDevice->WolSpeed = WOL_SPEED_100MB;
+ }
+
+ /* Offloadings. */
+ pDevice->TaskToOffload = LM_TASK_OFFLOAD_NONE;
+
+ /* Turn off task offloading on Ax. */
+ if(pDevice->ChipRevId == T3_CHIP_ID_5700_B0)
+ {
+ pDevice->TaskOffloadCap &= ~(LM_TASK_OFFLOAD_TX_TCP_CHECKSUM |
+ LM_TASK_OFFLOAD_TX_UDP_CHECKSUM);
+ }
+ pDevice->PciState = REG_RD(pDevice, PciCfg.PciState);
+ LM_ReadVPD(pDevice);
+ LM_ReadBootCodeVersion(pDevice);
+ LM_GetBusSpeed(pDevice);
+
+ return LM_STATUS_SUCCESS;
+} /* LM_GetAdapterInfo */
+
+STATIC PLM_ADAPTER_INFO
+LM_GetAdapterInfoBySsid(
+ LM_UINT16 Svid,
+ LM_UINT16 Ssid)
+{
+ static LM_ADAPTER_INFO AdapterArr[] =
+ {
+ { T3_SVID_BROADCOM, T3_SSID_BROADCOM_BCM95700A6, PHY_BCM5401_PHY_ID, 0},
+ { T3_SVID_BROADCOM, T3_SSID_BROADCOM_BCM95701A5, PHY_BCM5701_PHY_ID, 0},
+ { T3_SVID_BROADCOM, T3_SSID_BROADCOM_BCM95700T6, PHY_BCM8002_PHY_ID, 1},
+ { T3_SVID_BROADCOM, T3_SSID_BROADCOM_BCM95700A9, 0, 1 },
+ { T3_SVID_BROADCOM, T3_SSID_BROADCOM_BCM95701T1, PHY_BCM5701_PHY_ID, 0},
+ { T3_SVID_BROADCOM, T3_SSID_BROADCOM_BCM95701T8, PHY_BCM5701_PHY_ID, 0},
+ { T3_SVID_BROADCOM, T3_SSID_BROADCOM_BCM95701A7, 0, 1},
+ { T3_SVID_BROADCOM, T3_SSID_BROADCOM_BCM95701A10, PHY_BCM5701_PHY_ID, 0},
+ { T3_SVID_BROADCOM, T3_SSID_BROADCOM_BCM95701A12, PHY_BCM5701_PHY_ID, 0},
+ { T3_SVID_BROADCOM, T3_SSID_BROADCOM_BCM95703Ax1, PHY_BCM5701_PHY_ID, 0},
+ { T3_SVID_BROADCOM, T3_SSID_BROADCOM_BCM95703Ax2, PHY_BCM5701_PHY_ID, 0},
+
+ { T3_SVID_3COM, T3_SSID_3COM_3C996T, PHY_BCM5401_PHY_ID, 0 },
+ { T3_SVID_3COM, T3_SSID_3COM_3C996BT, PHY_BCM5701_PHY_ID, 0 },
+ { T3_SVID_3COM, T3_SSID_3COM_3C996SX, 0, 1 },
+ { T3_SVID_3COM, T3_SSID_3COM_3C1000T, PHY_BCM5701_PHY_ID, 0 },
+ { T3_SVID_3COM, T3_SSID_3COM_3C940BR01, PHY_BCM5701_PHY_ID, 0 },
+
+ { T3_SVID_DELL, T3_SSID_DELL_VIPER, PHY_BCM5401_PHY_ID, 0 },
+ { T3_SVID_DELL, T3_SSID_DELL_JAGUAR, PHY_BCM5401_PHY_ID, 0 },
+ { T3_SVID_DELL, T3_SSID_DELL_MERLOT, PHY_BCM5411_PHY_ID, 0 },
+ { T3_SVID_DELL, T3_SSID_DELL_SLIM_MERLOT, PHY_BCM5411_PHY_ID, 0 },
+
+ { T3_SVID_COMPAQ, T3_SSID_COMPAQ_BANSHEE, PHY_BCM5701_PHY_ID, 0 },
+ { T3_SVID_COMPAQ, T3_SSID_COMPAQ_BANSHEE_2, PHY_BCM5701_PHY_ID, 0 },
+ { T3_SVID_COMPAQ, T3_SSID_COMPAQ_CHANGELING, 0, 1 },
+ { T3_SVID_COMPAQ, T3_SSID_COMPAQ_NC7780, PHY_BCM5701_PHY_ID, 0 },
+ { T3_SVID_COMPAQ, T3_SSID_COMPAQ_NC7780_2, PHY_BCM5701_PHY_ID, 0 },
+
+ };
+ LM_UINT32 j;
+
+ for(j = 0; j < sizeof(AdapterArr)/sizeof(LM_ADAPTER_INFO); j++)
+ {
+ if(AdapterArr[j].Svid == Svid && AdapterArr[j].Ssid == Ssid)
+ {
+ return &AdapterArr[j];
+ }
+ }
+
+ return NULL;
+}
+
+
+/******************************************************************************/
+/* Description: */
+/* This routine sets up receive/transmit buffer descriptions queues. */
+/* */
+/* Return: */
+/* LM_STATUS_SUCCESS */
+/******************************************************************************/
+LM_STATUS
+LM_InitializeAdapter(
+PLM_DEVICE_BLOCK pDevice)
+{
+ LM_PHYSICAL_ADDRESS MemPhy;
+ PLM_UINT8 pMemVirt;
+ PLM_PACKET pPacket;
+ LM_STATUS Status;
+ LM_UINT32 Size;
+ LM_UINT32 j;
+
+ /* Set power state to D0. */
+ LM_SetPowerState(pDevice, LM_POWER_STATE_D0);
+
+ /* Intialize the queues. */
+ QQ_InitQueue(&pDevice->RxPacketReceivedQ.Container,
+ MAX_RX_PACKET_DESC_COUNT);
+ QQ_InitQueue(&pDevice->RxPacketFreeQ.Container,
+ MAX_RX_PACKET_DESC_COUNT);
+
+ QQ_InitQueue(&pDevice->TxPacketFreeQ.Container,MAX_TX_PACKET_DESC_COUNT);
+ QQ_InitQueue(&pDevice->TxPacketActiveQ.Container,MAX_TX_PACKET_DESC_COUNT);
+ QQ_InitQueue(&pDevice->TxPacketXmittedQ.Container,MAX_TX_PACKET_DESC_COUNT);
+
+ /* Allocate shared memory for: status block, the buffers for receive */
+ /* rings -- standard, mini, jumbo, and return rings. */
+ Size = T3_STATUS_BLOCK_SIZE + sizeof(T3_STATS_BLOCK) +
+ T3_STD_RCV_RCB_ENTRY_COUNT * sizeof(T3_RCV_BD) +
+#if T3_JUMBO_RCV_RCB_ENTRY_COUNT
+ T3_JUMBO_RCV_RCB_ENTRY_COUNT * sizeof(T3_RCV_BD) +
+#endif /* T3_JUMBO_RCV_RCB_ENTRY_COUNT */
+ T3_RCV_RETURN_RCB_ENTRY_COUNT * sizeof(T3_RCV_BD);
+
+ /* Memory for host based Send BD. */
+ if(pDevice->NicSendBd == FALSE)
+ {
+ Size += sizeof(T3_SND_BD) * T3_SEND_RCB_ENTRY_COUNT;
+ }
+
+ /* Allocate the memory block. */
+ Status = MM_AllocateSharedMemory(pDevice, Size, (PLM_VOID) &pMemVirt, &MemPhy, FALSE);
+ if(Status != LM_STATUS_SUCCESS)
+ {
+ return Status;
+ }
+
+ /* Program DMA Read/Write */
+ if (pDevice->PciState & T3_PCI_STATE_NOT_PCI_X_BUS)
+ {
+ pDevice->DmaReadWriteCtrl = 0x763f000f;
+ }
+ else
+ {
+ if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5704)
+ {
+ pDevice->DmaReadWriteCtrl = 0x761f0000;
+ }
+ else
+ {
+ pDevice->DmaReadWriteCtrl = 0x761b000f;
+ }
+ if(pDevice->ChipRevId == T3_CHIP_ID_5703_A1 ||
+ pDevice->ChipRevId == T3_CHIP_ID_5703_A2)
+ {
+ pDevice->OneDmaAtOnce = TRUE;
+ }
+ }
+ if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5703)
+ {
+ pDevice->DmaReadWriteCtrl &= 0xfffffff0;
+ }
+
+ if(pDevice->OneDmaAtOnce)
+ {
+ pDevice->DmaReadWriteCtrl |= DMA_CTRL_WRITE_ONE_DMA_AT_ONCE;
+ }
+ REG_WR(pDevice, PciCfg.DmaReadWriteCtrl, pDevice->DmaReadWriteCtrl);
+
+ if (LM_DmaTest(pDevice, pMemVirt, MemPhy, 0x400) != LM_STATUS_SUCCESS)
+ {
+ return LM_STATUS_FAILURE;
+ }
+
+ /* Status block. */
+ pDevice->pStatusBlkVirt = (PT3_STATUS_BLOCK) pMemVirt;
+ pDevice->StatusBlkPhy = MemPhy;
+ pMemVirt += T3_STATUS_BLOCK_SIZE;
+ LM_INC_PHYSICAL_ADDRESS(&MemPhy, T3_STATUS_BLOCK_SIZE);
+
+ /* Statistics block. */
+ pDevice->pStatsBlkVirt = (PT3_STATS_BLOCK) pMemVirt;
+ pDevice->StatsBlkPhy = MemPhy;
+ pMemVirt += sizeof(T3_STATS_BLOCK);
+ LM_INC_PHYSICAL_ADDRESS(&MemPhy, sizeof(T3_STATS_BLOCK));
+
+ /* Receive standard BD buffer. */
+ pDevice->pRxStdBdVirt = (PT3_RCV_BD) pMemVirt;
+ pDevice->RxStdBdPhy = MemPhy;
+
+ pMemVirt += T3_STD_RCV_RCB_ENTRY_COUNT * sizeof(T3_RCV_BD);
+ LM_INC_PHYSICAL_ADDRESS(&MemPhy,
+ T3_STD_RCV_RCB_ENTRY_COUNT * sizeof(T3_RCV_BD));
+
+#if T3_JUMBO_RCV_RCB_ENTRY_COUNT
+ /* Receive jumbo BD buffer. */
+ pDevice->pRxJumboBdVirt = (PT3_RCV_BD) pMemVirt;
+ pDevice->RxJumboBdPhy = MemPhy;
+
+ pMemVirt += T3_JUMBO_RCV_RCB_ENTRY_COUNT * sizeof(T3_RCV_BD);
+ LM_INC_PHYSICAL_ADDRESS(&MemPhy,
+ T3_JUMBO_RCV_RCB_ENTRY_COUNT * sizeof(T3_RCV_BD));
+#endif /* T3_JUMBO_RCV_RCB_ENTRY_COUNT */
+
+ /* Receive return BD buffer. */
+ pDevice->pRcvRetBdVirt = (PT3_RCV_BD) pMemVirt;
+ pDevice->RcvRetBdPhy = MemPhy;
+
+ pMemVirt += T3_RCV_RETURN_RCB_ENTRY_COUNT * sizeof(T3_RCV_BD);
+ LM_INC_PHYSICAL_ADDRESS(&MemPhy,
+ T3_RCV_RETURN_RCB_ENTRY_COUNT * sizeof(T3_RCV_BD));
+
+ /* Set up Send BD. */
+ if(pDevice->NicSendBd == FALSE)
+ {
+ pDevice->pSendBdVirt = (PT3_SND_BD) pMemVirt;
+ pDevice->SendBdPhy = MemPhy;
+
+ pMemVirt += sizeof(T3_SND_BD) * T3_SEND_RCB_ENTRY_COUNT;
+ LM_INC_PHYSICAL_ADDRESS(&MemPhy,
+ sizeof(T3_SND_BD) * T3_SEND_RCB_ENTRY_COUNT);
+ }
+ else
+ {
+ pDevice->pSendBdVirt = (PT3_SND_BD)
+ pDevice->pMemView->uIntMem.First32k.BufferDesc;
+ pDevice->SendBdPhy.High = 0;
+ pDevice->SendBdPhy.Low = T3_NIC_SND_BUFFER_DESC_ADDR;
+ }
+
+ /* Allocate memory for packet descriptors. */
+ Size = (pDevice->RxPacketDescCnt +
+ pDevice->TxPacketDescCnt) * MM_PACKET_DESC_SIZE;
+ Status = MM_AllocateMemory(pDevice, Size, (PLM_VOID *) &pPacket);
+ if(Status != LM_STATUS_SUCCESS)
+ {
+ return Status;
+ }
+ pDevice->pPacketDescBase = (PLM_VOID) pPacket;
+
+ /* Create transmit packet descriptors from the memory block and add them */
+ /* to the TxPacketFreeQ for each send ring. */
+ for(j = 0; j < pDevice->TxPacketDescCnt; j++)
+ {
+ /* Ring index. */
+ pPacket->Flags = 0;
+
+ /* Queue the descriptor in the TxPacketFreeQ of the 'k' ring. */
+ QQ_PushTail(&pDevice->TxPacketFreeQ.Container, pPacket);
+
+ /* Get the pointer to the next descriptor. MM_PACKET_DESC_SIZE */
+ /* is the total size of the packet descriptor including the */
+ /* os-specific extensions in the UM_PACKET structure. */
+ pPacket = (PLM_PACKET) ((PLM_UINT8) pPacket + MM_PACKET_DESC_SIZE);
+ } /* for(j.. */
+
+ /* Create receive packet descriptors from the memory block and add them */
+ /* to the RxPacketFreeQ. Create the Standard packet descriptors. */
+ for(j = 0; j < pDevice->RxStdDescCnt; j++)
+ {
+ /* Receive producer ring. */
+ pPacket->u.Rx.RcvProdRing = T3_STD_RCV_PROD_RING;
+
+ /* Receive buffer size. */
+ pPacket->u.Rx.RxBufferSize = MAX_STD_RCV_BUFFER_SIZE;
+
+ /* Add the descriptor to RxPacketFreeQ. */
+ QQ_PushTail(&pDevice->RxPacketFreeQ.Container, pPacket);
+
+ /* Get the pointer to the next descriptor. MM_PACKET_DESC_SIZE */
+ /* is the total size of the packet descriptor including the */
+ /* os-specific extensions in the UM_PACKET structure. */
+ pPacket = (PLM_PACKET) ((PLM_UINT8) pPacket + MM_PACKET_DESC_SIZE);
+ } /* for */
+
+#if T3_JUMBO_RCV_RCB_ENTRY_COUNT
+ /* Create the Jumbo packet descriptors. */
+ for(j = 0; j < pDevice->RxJumboDescCnt; j++)
+ {
+ /* Receive producer ring. */
+ pPacket->u.Rx.RcvProdRing = T3_JUMBO_RCV_PROD_RING;
+
+ /* Receive buffer size. */
+ pPacket->u.Rx.RxBufferSize = pDevice->RxJumboBufferSize;
+
+ /* Add the descriptor to RxPacketFreeQ. */
+ QQ_PushTail(&pDevice->RxPacketFreeQ.Container, pPacket);
+
+ /* Get the pointer to the next descriptor. MM_PACKET_DESC_SIZE */
+ /* is the total size of the packet descriptor including the */
+ /* os-specific extensions in the UM_PACKET structure. */
+ pPacket = (PLM_PACKET) ((PLM_UINT8) pPacket + MM_PACKET_DESC_SIZE);
+ } /* for */
+#endif /* T3_JUMBO_RCV_RCB_ENTRY_COUNT */
+
+ /* Initialize the rest of the packet descriptors. */
+ Status = MM_InitializeUmPackets(pDevice);
+ if(Status != LM_STATUS_SUCCESS)
+ {
+ return Status;
+ } /* if */
+
+ /* Default receive mask. */
+ pDevice->ReceiveMask = LM_ACCEPT_MULTICAST | LM_ACCEPT_BROADCAST |
+ LM_ACCEPT_UNICAST;
+
+ /* Make sure we are in the first 32k memory window or NicSendBd. */
+ REG_WR(pDevice, PciCfg.MemWindowBaseAddr, 0);
+
+ /* Initialize the hardware. */
+ Status = LM_ResetAdapter(pDevice);
+ if(Status != LM_STATUS_SUCCESS)
+ {
+ return Status;
+ }
+
+ /* We are done with initialization. */
+ pDevice->InitDone = TRUE;
+
+ return LM_STATUS_SUCCESS;
+} /* LM_InitializeAdapter */
+
+
+
+/******************************************************************************/
+/* Description: */
+/* This function Enables/Disables a given block. */
+/* */
+/* Return: */
+/* LM_STATUS_SUCCESS */
+/******************************************************************************/
+LM_STATUS
+LM_CntrlBlock(
+PLM_DEVICE_BLOCK pDevice,
+LM_UINT32 mask,LM_UINT32 cntrl)
+{
+ LM_UINT32 j,i,data;
+ LM_UINT32 MaxWaitCnt;
+
+ MaxWaitCnt = 2;
+ j = 0;
+
+ for(i = 0 ; i < 32; i++)
+ {
+ if(!(mask & (1 << i)))
+ continue;
+
+ switch (1 << i)
+ {
+ case T3_BLOCK_DMA_RD:
+ data = REG_RD(pDevice, DmaRead.Mode);
+ if (cntrl == LM_DISABLE)
+ {
+ data &= ~DMA_READ_MODE_ENABLE;
+ REG_WR(pDevice, DmaRead.Mode, data);
+ for(j = 0; j < MaxWaitCnt; j++)
+ {
+ if(!(REG_RD(pDevice, DmaRead.Mode) & DMA_READ_MODE_ENABLE))
+ break;
+ MM_Wait(10);
+ }
+ }
+ else
+ REG_WR(pDevice, DmaRead.Mode, data | DMA_READ_MODE_ENABLE);
+ break;
+
+ case T3_BLOCK_DMA_COMP:
+ data = REG_RD(pDevice,DmaComp.Mode);
+ if (cntrl == LM_DISABLE)
+ {
+ data &= ~DMA_COMP_MODE_ENABLE;
+ REG_WR(pDevice, DmaComp.Mode, data);
+ for(j = 0; j < MaxWaitCnt; j++)
+ {
+ if(!(REG_RD(pDevice, DmaComp.Mode) & DMA_COMP_MODE_ENABLE))
+ break;
+ MM_Wait(10);
+ }
+ }
+ else
+ REG_WR(pDevice, DmaComp.Mode, data | DMA_COMP_MODE_ENABLE);
+ break;
+
+ case T3_BLOCK_RX_BD_INITIATOR:
+ data = REG_RD(pDevice, RcvBdIn.Mode);
+ if (cntrl == LM_DISABLE)
+ {
+ data &= ~RCV_BD_IN_MODE_ENABLE;
+ REG_WR(pDevice, RcvBdIn.Mode,data);
+ for(j = 0; j < MaxWaitCnt; j++)
+ {
+ if(!(REG_RD(pDevice, RcvBdIn.Mode) & RCV_BD_IN_MODE_ENABLE))
+ break;
+ MM_Wait(10);
+ }
+ }
+ else
+ REG_WR(pDevice, RcvBdIn.Mode,data | RCV_BD_IN_MODE_ENABLE);
+ break;
+
+ case T3_BLOCK_RX_BD_COMP:
+ data = REG_RD(pDevice, RcvBdComp.Mode);
+ if (cntrl == LM_DISABLE)
+ {
+ data &= ~RCV_BD_COMP_MODE_ENABLE;
+ REG_WR(pDevice, RcvBdComp.Mode,data);
+ for(j = 0; j < MaxWaitCnt; j++)
+ {
+ if(!(REG_RD(pDevice, RcvBdComp.Mode) & RCV_BD_COMP_MODE_ENABLE))
+ break;
+ MM_Wait(10);
+ }
+ }
+ else
+ REG_WR(pDevice, RcvBdComp.Mode,data | RCV_BD_COMP_MODE_ENABLE);
+ break;
+
+ case T3_BLOCK_DMA_WR:
+ data = REG_RD(pDevice, DmaWrite.Mode);
+ if (cntrl == LM_DISABLE)
+ {
+ data &= ~DMA_WRITE_MODE_ENABLE;
+ REG_WR(pDevice, DmaWrite.Mode,data);
+
+ for(j = 0; j < MaxWaitCnt; j++)
+ {
+ if(!(REG_RD(pDevice, DmaWrite.Mode) & DMA_WRITE_MODE_ENABLE))
+ break;
+ MM_Wait(10);
+ }
+ }
+ else
+ REG_WR(pDevice, DmaWrite.Mode,data | DMA_WRITE_MODE_ENABLE);
+ break;
+
+ case T3_BLOCK_MSI_HANDLER:
+ data = REG_RD(pDevice, Msi.Mode);
+ if (cntrl == LM_DISABLE)
+ {
+ data &= ~MSI_MODE_ENABLE;
+ REG_WR(pDevice, Msi.Mode, data);
+ for(j = 0; j < MaxWaitCnt; j++)
+ {
+ if(!(REG_RD(pDevice, Msi.Mode) & MSI_MODE_ENABLE))
+ break;
+ MM_Wait(10);
+ }
+ }
+ else
+ REG_WR(pDevice, Msi.Mode, data |MSI_MODE_ENABLE);
+ break;
+
+ case T3_BLOCK_RX_LIST_PLMT:
+ data = REG_RD(pDevice, RcvListPlmt.Mode);
+ if (cntrl == LM_DISABLE)
+ {
+ data &= ~RCV_LIST_PLMT_MODE_ENABLE;
+ REG_WR(pDevice, RcvListPlmt.Mode,data);
+ for(j = 0; j < MaxWaitCnt; j++)
+ {
+ if(!(REG_RD(pDevice, RcvListPlmt.Mode) & RCV_LIST_PLMT_MODE_ENABLE))
+ break;
+ MM_Wait(10);
+ }
+ }
+ else
+ REG_WR(pDevice, RcvListPlmt.Mode,data | RCV_LIST_PLMT_MODE_ENABLE);
+ break;
+
+ case T3_BLOCK_RX_LIST_SELECTOR:
+ data = REG_RD(pDevice, RcvListSel.Mode);
+ if (cntrl == LM_DISABLE)
+ {
+ data &= ~RCV_LIST_SEL_MODE_ENABLE;
+ REG_WR(pDevice, RcvListSel.Mode,data);
+ for(j = 0; j < MaxWaitCnt; j++)
+ {
+ if(!(REG_RD(pDevice, RcvListSel.Mode) & RCV_LIST_SEL_MODE_ENABLE))
+ break;
+ MM_Wait(10);
+ }
+ }
+ else
+ REG_WR(pDevice, RcvListSel.Mode,data |RCV_LIST_SEL_MODE_ENABLE);
+ break;
+
+ case T3_BLOCK_RX_DATA_INITIATOR:
+ data = REG_RD(pDevice, RcvDataBdIn.Mode);
+ if (cntrl == LM_DISABLE)
+ {
+ data &= ~RCV_DATA_BD_IN_MODE_ENABLE;
+ REG_WR(pDevice, RcvDataBdIn.Mode,data);
+ for(j = 0; j < MaxWaitCnt; j++)
+ {
+ if(!(REG_RD(pDevice, RcvDataBdIn.Mode) & RCV_DATA_BD_IN_MODE_ENABLE))
+ break;
+ MM_Wait(10);
+ }
+ }
+ else
+ REG_WR(pDevice, RcvDataBdIn.Mode, data | RCV_DATA_BD_IN_MODE_ENABLE);
+ break;
+
+ case T3_BLOCK_RX_DATA_COMP:
+ data = REG_RD(pDevice, RcvDataComp.Mode);
+ if (cntrl == LM_DISABLE)
+ {
+ data &= ~RCV_DATA_COMP_MODE_ENABLE;
+ REG_WR(pDevice, RcvDataComp.Mode,data);
+ for(j = 0; j < MaxWaitCnt; j++)
+ {
+ if(!(REG_RD(pDevice, RcvDataBdIn.Mode) & RCV_DATA_COMP_MODE_ENABLE))
+ break;
+ MM_Wait(10);
+ }
+ }
+ else
+ REG_WR(pDevice, RcvDataComp.Mode,data | RCV_DATA_COMP_MODE_ENABLE);
+ break;
+
+ case T3_BLOCK_HOST_COALESING:
+ data = REG_RD(pDevice, HostCoalesce.Mode);
+ if (cntrl == LM_DISABLE)
+ {
+ data &= ~HOST_COALESCE_ENABLE;
+ REG_WR(pDevice, HostCoalesce.Mode, data);
+ for(j = 0; j < MaxWaitCnt; j++)
+ {
+ if(!(REG_RD(pDevice, SndBdIn.Mode) & HOST_COALESCE_ENABLE))
+ break;
+ MM_Wait(10);
+ }
+ }
+ else
+ REG_WR(pDevice, HostCoalesce.Mode, data | HOST_COALESCE_ENABLE);
+ break;
+
+ case T3_BLOCK_MAC_RX_ENGINE:
+ if(cntrl == LM_DISABLE)
+ {
+ pDevice->RxMode &= ~RX_MODE_ENABLE;
+ REG_WR(pDevice, MacCtrl.RxMode, pDevice->RxMode);
+ for(j = 0; j < MaxWaitCnt; j++)
+ {
+ if(!(REG_RD(pDevice, MacCtrl.RxMode) & RX_MODE_ENABLE))
+ {
+ break;
+ }
+ MM_Wait(10);
+ }
+ }
+ else
+ {
+ pDevice->RxMode |= RX_MODE_ENABLE;
+ REG_WR(pDevice, MacCtrl.RxMode, pDevice->RxMode);
+ }
+ break;
+
+ case T3_BLOCK_MBUF_CLUSTER_FREE:
+ data = REG_RD(pDevice, MbufClusterFree.Mode);
+ if (cntrl == LM_DISABLE)
+ {
+ data &= ~MBUF_CLUSTER_FREE_MODE_ENABLE;
+ REG_WR(pDevice, MbufClusterFree.Mode,data);
+ for(j = 0; j < MaxWaitCnt; j++)
+ {
+ if(!(REG_RD(pDevice, MbufClusterFree.Mode) & MBUF_CLUSTER_FREE_MODE_ENABLE))
+ break;
+ MM_Wait(10);
+ }
+ }
+ else
+ REG_WR(pDevice, MbufClusterFree.Mode, data | MBUF_CLUSTER_FREE_MODE_ENABLE);
+ break;
+
+ case T3_BLOCK_SEND_BD_INITIATOR:
+ data = REG_RD(pDevice, SndBdIn.Mode);
+ if (cntrl == LM_DISABLE)
+ {
+ data &= ~SND_BD_IN_MODE_ENABLE;
+ REG_WR(pDevice, SndBdIn.Mode, data);
+ for(j = 0; j < MaxWaitCnt; j++)
+ {
+ if(!(REG_RD(pDevice, SndBdIn.Mode) & SND_BD_IN_MODE_ENABLE))
+ break;
+ MM_Wait(10);
+ }
+ }
+ else
+ REG_WR(pDevice, SndBdIn.Mode, data | SND_BD_IN_MODE_ENABLE);
+ break;
+
+ case T3_BLOCK_SEND_BD_COMP:
+ data = REG_RD(pDevice, SndBdComp.Mode);
+ if (cntrl == LM_DISABLE)
+ {
+ data &= ~SND_BD_COMP_MODE_ENABLE;
+ REG_WR(pDevice, SndBdComp.Mode, data);
+ for(j = 0; j < MaxWaitCnt; j++)
+ {
+ if(!(REG_RD(pDevice, SndBdComp.Mode) & SND_BD_COMP_MODE_ENABLE))
+ break;
+ MM_Wait(10);
+ }
+ }
+ else
+ REG_WR(pDevice, SndBdComp.Mode, data | SND_BD_COMP_MODE_ENABLE);
+ break;
+
+ case T3_BLOCK_SEND_BD_SELECTOR:
+ data = REG_RD(pDevice, SndBdSel.Mode);
+ if (cntrl == LM_DISABLE)
+ {
+ data &= ~SND_BD_SEL_MODE_ENABLE;
+ REG_WR(pDevice, SndBdSel.Mode, data);
+ for(j = 0; j < MaxWaitCnt; j++)
+ {
+ if(!(REG_RD(pDevice, SndBdSel.Mode) & SND_BD_SEL_MODE_ENABLE))
+ break;
+ MM_Wait(10);
+ }
+ }
+ else
+ REG_WR(pDevice, SndBdSel.Mode, data | SND_BD_SEL_MODE_ENABLE);
+ break;
+
+ case T3_BLOCK_SEND_DATA_INITIATOR:
+ data = REG_RD(pDevice, SndDataIn.Mode);
+ if (cntrl == LM_DISABLE)
+ {
+ data &= ~T3_SND_DATA_IN_MODE_ENABLE;
+ REG_WR(pDevice, SndDataIn.Mode,data);
+ for(j = 0; j < MaxWaitCnt; j++)
+ {
+ if(!(REG_RD(pDevice, SndDataIn.Mode) & T3_SND_DATA_IN_MODE_ENABLE))
+ break;
+ MM_Wait(10);
+ }
+ }
+ else
+ REG_WR(pDevice, SndDataIn.Mode,data | T3_SND_DATA_IN_MODE_ENABLE);
+ break;
+
+ case T3_BLOCK_SEND_DATA_COMP:
+ data = REG_RD(pDevice, SndDataComp.Mode);
+ if (cntrl == LM_DISABLE)
+ {
+ data &= ~SND_DATA_COMP_MODE_ENABLE;
+ REG_WR(pDevice, SndDataComp.Mode, data);
+ for(j = 0; j < MaxWaitCnt; j++)
+ {
+ if(!(REG_RD(pDevice, SndDataComp.Mode) & SND_DATA_COMP_MODE_ENABLE))
+ break;
+ MM_Wait(10);
+ }
+ }
+ else
+ REG_WR(pDevice, SndDataComp.Mode,data | SND_DATA_COMP_MODE_ENABLE);
+ break;
+
+ case T3_BLOCK_MAC_TX_ENGINE:
+ if(cntrl == LM_DISABLE)
+ {
+ pDevice->TxMode &= ~TX_MODE_ENABLE;
+ REG_WR(pDevice, MacCtrl.TxMode, pDevice->TxMode);
+ for(j = 0; j < MaxWaitCnt; j++)
+ {
+ if(!(REG_RD(pDevice, MacCtrl.TxMode) & TX_MODE_ENABLE))
+ break;
+ MM_Wait(10);
+ }
+ }
+ else
+ {
+ pDevice->TxMode |= TX_MODE_ENABLE;
+ REG_WR(pDevice, MacCtrl.TxMode, pDevice->TxMode);
+ }
+ break;
+
+ case T3_BLOCK_MEM_ARBITOR:
+ data = REG_RD(pDevice, MemArbiter.Mode);
+ if (cntrl == LM_DISABLE)
+ {
+ data &= ~T3_MEM_ARBITER_MODE_ENABLE;
+ REG_WR(pDevice, MemArbiter.Mode, data);
+ for(j = 0; j < MaxWaitCnt; j++)
+ {
+ if(!(REG_RD(pDevice, MemArbiter.Mode) & T3_MEM_ARBITER_MODE_ENABLE))
+ break;
+ MM_Wait(10);
+ }
+ }
+ else
+ REG_WR(pDevice, MemArbiter.Mode,data|T3_MEM_ARBITER_MODE_ENABLE);
+ break;
+
+ case T3_BLOCK_MBUF_MANAGER:
+ data = REG_RD(pDevice, BufMgr.Mode);
+ if (cntrl == LM_DISABLE)
+ {
+ data &= ~BUFMGR_MODE_ENABLE;
+ REG_WR(pDevice, BufMgr.Mode,data);
+ for(j = 0; j < MaxWaitCnt; j++)
+ {
+ if(!(REG_RD(pDevice, BufMgr.Mode) & BUFMGR_MODE_ENABLE))
+ break;
+ MM_Wait(10);
+ }
+ }
+ else
+ REG_WR(pDevice, BufMgr.Mode,data | BUFMGR_MODE_ENABLE);
+ break;
+
+ case T3_BLOCK_MAC_GLOBAL:
+ if(cntrl == LM_DISABLE)
+ {
+ pDevice->MacMode &= ~(MAC_MODE_ENABLE_TDE |
+ MAC_MODE_ENABLE_RDE |
+ MAC_MODE_ENABLE_FHDE);
+ }
+ else
+ {
+ pDevice->MacMode |= (MAC_MODE_ENABLE_TDE |
+ MAC_MODE_ENABLE_RDE |
+ MAC_MODE_ENABLE_FHDE);
+ }
+ REG_WR(pDevice, MacCtrl.Mode, pDevice->MacMode);
+ break;
+
+ default:
+ return LM_STATUS_FAILURE;
+ } /* switch */
+
+ if(j >= MaxWaitCnt)
+ {
+ return LM_STATUS_FAILURE;
+ }
+ }
+
+ return LM_STATUS_SUCCESS;
+}
+
+/******************************************************************************/
+/* Description: */
+/* This function reinitializes the adapter. */
+/* */
+/* Return: */
+/* LM_STATUS_SUCCESS */
+/******************************************************************************/
+LM_STATUS
+LM_ResetAdapter(
+PLM_DEVICE_BLOCK pDevice)
+{
+ LM_UINT32 Value32;
+ LM_UINT16 Value16;
+ LM_UINT32 j, k;
+
+ /* Disable interrupt. */
+ LM_DisableInterrupt(pDevice);
+
+ /* May get a spurious interrupt */
+ pDevice->pStatusBlkVirt->Status = STATUS_BLOCK_UPDATED;
+
+ /* Disable transmit and receive DMA engines. Abort all pending requests. */
+ if(pDevice->InitDone)
+ {
+ LM_Abort(pDevice);
+ }
+
+ pDevice->ShuttingDown = FALSE;
+
+ LM_ResetChip(pDevice);
+
+ /* Bug: Athlon fix for B3 silicon only. This bit does not do anything */
+ /* in other chip revisions. */
+ if(pDevice->DelayPciGrant)
+ {
+ Value32 = REG_RD(pDevice, PciCfg.ClockCtrl);
+ REG_WR(pDevice, PciCfg.ClockCtrl, Value32 | BIT_31);
+ }
+
+ if(pDevice->ChipRevId == T3_CHIP_ID_5704_A0)
+ {
+ if (!(pDevice->PciState & T3_PCI_STATE_CONVENTIONAL_PCI_MODE))
+ {
+ Value32 = REG_RD(pDevice, PciCfg.PciState);
+ Value32 |= T3_PCI_STATE_RETRY_SAME_DMA;
+ REG_WR(pDevice, PciCfg.PciState, Value32);
+ }
+ }
+
+ /* Enable TaggedStatus mode. */
+ if(pDevice->UseTaggedStatus)
+ {
+ pDevice->MiscHostCtrl |= MISC_HOST_CTRL_ENABLE_TAGGED_STATUS_MODE;
+ }
+
+ /* Restore PCI configuration registers. */
+ MM_WriteConfig32(pDevice, PCI_CACHE_LINE_SIZE_REG,
+ pDevice->SavedCacheLineReg);
+ MM_WriteConfig32(pDevice, PCI_SUBSYSTEM_VENDOR_ID_REG,
+ (pDevice->SubsystemId << 16) | pDevice->SubsystemVendorId);
+
+ /* Clear the statistics block. */
+ for(j = 0x0300; j < 0x0b00; j++)
+ {
+ MEM_WR_OFFSET(pDevice, j, 0);
+ }
+
+ /* Initialize the statistis Block */
+ pDevice->pStatusBlkVirt->Status = 0;
+ pDevice->pStatusBlkVirt->RcvStdConIdx = 0;
+ pDevice->pStatusBlkVirt->RcvJumboConIdx = 0;
+ pDevice->pStatusBlkVirt->RcvMiniConIdx = 0;
+
+ for(j = 0; j < 16; j++)
+ {
+ pDevice->pStatusBlkVirt->Idx[j].RcvProdIdx = 0;
+ pDevice->pStatusBlkVirt->Idx[j].SendConIdx = 0;
+ }
+
+ for(k = 0; k < T3_STD_RCV_RCB_ENTRY_COUNT ;k++)
+ {
+ pDevice->pRxStdBdVirt[k].HostAddr.High = 0;
+ pDevice->pRxStdBdVirt[k].HostAddr.Low = 0;
+ }
+
+#if T3_JUMBO_RCV_RCB_ENTRY_COUNT
+ /* Receive jumbo BD buffer. */
+ for(k = 0; k < T3_JUMBO_RCV_RCB_ENTRY_COUNT; k++)
+ {
+ pDevice->pRxJumboBdVirt[k].HostAddr.High = 0;
+ pDevice->pRxJumboBdVirt[k].HostAddr.Low = 0;
+ }
+#endif
+
+ REG_WR(pDevice, PciCfg.DmaReadWriteCtrl, pDevice->DmaReadWriteCtrl);
+
+ /* GRC mode control register. */
+#ifdef BIG_ENDIAN_PCI /* Jimmy, this ifdef block deleted in new code! */
+ Value32 =
+ GRC_MODE_WORD_SWAP_DATA |
+ GRC_MODE_WORD_SWAP_NON_FRAME_DATA |
+ GRC_MODE_INT_ON_MAC_ATTN |
+ GRC_MODE_HOST_STACK_UP;
+#else
+ /* No CPU Swap modes for PCI IO */
+ Value32 =
+#ifdef BIG_ENDIAN_HOST
+ GRC_MODE_BYTE_SWAP_NON_FRAME_DATA |
+ GRC_MODE_WORD_SWAP_NON_FRAME_DATA |
+ GRC_MODE_BYTE_SWAP_DATA |
+ GRC_MODE_WORD_SWAP_DATA |
+#else
+ GRC_MODE_WORD_SWAP_NON_FRAME_DATA |
+ GRC_MODE_BYTE_SWAP_DATA |
+ GRC_MODE_WORD_SWAP_DATA |
+#endif
+ GRC_MODE_INT_ON_MAC_ATTN |
+ GRC_MODE_HOST_STACK_UP;
+#endif /* !BIG_ENDIAN_PCI */
+
+ /* Configure send BD mode. */
+ if(pDevice->NicSendBd == FALSE)
+ {
+ Value32 |= GRC_MODE_HOST_SEND_BDS;
+ }
+ else
+ {
+ Value32 |= GRC_MODE_4X_NIC_BASED_SEND_RINGS;
+ }
+
+ /* Configure pseudo checksum mode. */
+ if(pDevice->NoTxPseudoHdrChksum)
+ {
+ Value32 |= GRC_MODE_TX_NO_PSEUDO_HEADER_CHKSUM;
+ }
+
+ if(pDevice->NoRxPseudoHdrChksum)
+ {
+ Value32 |= GRC_MODE_RX_NO_PSEUDO_HEADER_CHKSUM;
+ }
+
+ REG_WR(pDevice, Grc.Mode, Value32);
+
+ /* Setup the timer prescalar register. */
+ REG_WR(pDevice, Grc.MiscCfg, 65 << 1); /* Clock is alwasy 66Mhz. */
+
+ /* Set up the MBUF pool base address and size. */
+ REG_WR(pDevice, BufMgr.MbufPoolAddr, pDevice->MbufBase);
+ REG_WR(pDevice, BufMgr.MbufPoolSize, pDevice->MbufSize);
+
+ /* Set up the DMA descriptor pool base address and size. */
+ REG_WR(pDevice, BufMgr.DmaDescPoolAddr, T3_NIC_DMA_DESC_POOL_ADDR);
+ REG_WR(pDevice, BufMgr.DmaDescPoolSize, T3_NIC_DMA_DESC_POOL_SIZE);
+
+ /* Configure MBUF and Threshold watermarks */
+ /* Configure the DMA read MBUF low water mark. */
+ if(pDevice->DmaMbufLowMark)
+ {
+ REG_WR(pDevice, BufMgr.MbufReadDmaLowWaterMark,
+ pDevice->DmaMbufLowMark);
+ }
+ else
+ {
+ if(pDevice->TxMtu < MAX_ETHERNET_PACKET_BUFFER_SIZE)
+ {
+ REG_WR(pDevice, BufMgr.MbufReadDmaLowWaterMark,
+ T3_DEF_DMA_MBUF_LOW_WMARK);
+ }
+ else
+ {
+ REG_WR(pDevice, BufMgr.MbufReadDmaLowWaterMark,
+ T3_DEF_DMA_MBUF_LOW_WMARK_JUMBO);
+ }
+ }
+
+ /* Configure the MAC Rx MBUF low water mark. */
+ if(pDevice->RxMacMbufLowMark)
+ {
+ REG_WR(pDevice, BufMgr.MbufMacRxLowWaterMark,
+ pDevice->RxMacMbufLowMark);
+ }
+ else
+ {
+ if(pDevice->TxMtu < MAX_ETHERNET_PACKET_BUFFER_SIZE)
+ {
+ REG_WR(pDevice, BufMgr.MbufMacRxLowWaterMark,
+ T3_DEF_RX_MAC_MBUF_LOW_WMARK);
+ }
+ else
+ {
+ REG_WR(pDevice, BufMgr.MbufMacRxLowWaterMark,
+ T3_DEF_RX_MAC_MBUF_LOW_WMARK_JUMBO);
+ }
+ }
+
+ /* Configure the MBUF high water mark. */
+ if(pDevice->MbufHighMark)
+ {
+ REG_WR(pDevice, BufMgr.MbufHighWaterMark, pDevice->MbufHighMark);
+ }
+ else
+ {
+ if(pDevice->TxMtu < MAX_ETHERNET_PACKET_BUFFER_SIZE)
+ {
+ REG_WR(pDevice, BufMgr.MbufHighWaterMark,
+ T3_DEF_MBUF_HIGH_WMARK);
+ }
+ else
+ {
+ REG_WR(pDevice, BufMgr.MbufHighWaterMark,
+ T3_DEF_MBUF_HIGH_WMARK_JUMBO);
+ }
+ }
+
+ REG_WR(pDevice, BufMgr.DmaLowWaterMark, T3_DEF_DMA_DESC_LOW_WMARK);
+ REG_WR(pDevice, BufMgr.DmaHighWaterMark, T3_DEF_DMA_DESC_HIGH_WMARK);
+
+ /* Enable buffer manager. */
+ REG_WR(pDevice, BufMgr.Mode, BUFMGR_MODE_ENABLE | BUFMGR_MODE_ATTN_ENABLE);
+
+ for(j = 0 ;j < 2000; j++)
+ {
+ if(REG_RD(pDevice, BufMgr.Mode) & BUFMGR_MODE_ENABLE)
+ break;
+ MM_Wait(10);
+ }
+
+ if(j >= 2000)
+ {
+ return LM_STATUS_FAILURE;
+ }
+
+ /* Enable the FTQs. */
+ REG_WR(pDevice, Ftq.Reset, 0xffffffff);
+ REG_WR(pDevice, Ftq.Reset, 0);
+
+ /* Wait until FTQ is ready */
+ for(j = 0; j < 2000; j++)
+ {
+ if(REG_RD(pDevice, Ftq.Reset) == 0)
+ break;
+ MM_Wait(10);
+ }
+
+ if(j >= 2000)
+ {
+ return LM_STATUS_FAILURE;
+ }
+
+ /* Initialize the Standard Receive RCB. */
+ REG_WR(pDevice, RcvDataBdIn.StdRcvRcb.HostRingAddr.High,
+ pDevice->RxStdBdPhy.High);
+ REG_WR(pDevice, RcvDataBdIn.StdRcvRcb.HostRingAddr.Low,
+ pDevice->RxStdBdPhy.Low);
+ REG_WR(pDevice, RcvDataBdIn.StdRcvRcb.u.MaxLen_Flags,
+ MAX_STD_RCV_BUFFER_SIZE << 16);
+
+ /* Initialize the Jumbo Receive RCB. */
+ REG_WR(pDevice, RcvDataBdIn.JumboRcvRcb.u.MaxLen_Flags,
+ T3_RCB_FLAG_RING_DISABLED);
+#if T3_JUMBO_RCV_RCB_ENTRY_COUNT
+ REG_WR(pDevice, RcvDataBdIn.JumboRcvRcb.HostRingAddr.High,
+ pDevice->RxJumboBdPhy.High);
+ REG_WR(pDevice, RcvDataBdIn.JumboRcvRcb.HostRingAddr.Low,
+ pDevice->RxJumboBdPhy.Low);
+
+ REG_WR(pDevice, RcvDataBdIn.JumboRcvRcb.u.MaxLen_Flags, 0);
+
+#endif /* T3_JUMBO_RCV_RCB_ENTRY_COUNT */
+
+ /* Initialize the Mini Receive RCB. */
+ REG_WR(pDevice, RcvDataBdIn.MiniRcvRcb.u.MaxLen_Flags,
+ T3_RCB_FLAG_RING_DISABLED);
+
+ {
+ REG_WR(pDevice, RcvDataBdIn.StdRcvRcb.NicRingAddr,
+ (LM_UINT32) T3_NIC_STD_RCV_BUFFER_DESC_ADDR);
+ REG_WR(pDevice, RcvDataBdIn.JumboRcvRcb.NicRingAddr,
+ (LM_UINT32) T3_NIC_JUMBO_RCV_BUFFER_DESC_ADDR);
+ }
+
+ /* Receive BD Ring replenish threshold. */
+ REG_WR(pDevice, RcvBdIn.StdRcvThreshold, pDevice->RxStdDescCnt/8);
+#if T3_JUMBO_RCV_RCB_ENTRY_COUNT
+ REG_WR(pDevice, RcvBdIn.JumboRcvThreshold, pDevice->RxJumboDescCnt/8);
+#endif /* T3_JUMBO_RCV_RCB_ENTRY_COUNT */
+
+ /* Disable all the unused rings. */
+ for(j = 0; j < T3_MAX_SEND_RCB_COUNT; j++) {
+ MEM_WR(pDevice, SendRcb[j].u.MaxLen_Flags, T3_RCB_FLAG_RING_DISABLED);
+ } /* for */
+
+ /* Initialize the indices. */
+ pDevice->SendProdIdx = 0;
+ pDevice->SendConIdx = 0;
+
+ MB_REG_WR(pDevice, Mailbox.SendHostProdIdx[0].Low, 0);
+ MB_REG_WR(pDevice, Mailbox.SendNicProdIdx[0].Low, 0);
+
+ /* Set up host or NIC based send RCB. */
+ if(pDevice->NicSendBd == FALSE)
+ {
+ MEM_WR(pDevice, SendRcb[0].HostRingAddr.High,
+ pDevice->SendBdPhy.High);
+ MEM_WR(pDevice, SendRcb[0].HostRingAddr.Low,
+ pDevice->SendBdPhy.Low);
+
+ /* Set up the NIC ring address in the RCB. */
+ MEM_WR(pDevice, SendRcb[0].NicRingAddr,T3_NIC_SND_BUFFER_DESC_ADDR);
+
+ /* Setup the RCB. */
+ MEM_WR(pDevice, SendRcb[0].u.MaxLen_Flags,
+ T3_SEND_RCB_ENTRY_COUNT << 16);
+
+ for(k = 0; k < T3_SEND_RCB_ENTRY_COUNT; k++)
+ {
+ pDevice->pSendBdVirt[k].HostAddr.High = 0;
+ pDevice->pSendBdVirt[k].HostAddr.Low = 0;
+ }
+ }
+ else
+ {
+ MEM_WR(pDevice, SendRcb[0].HostRingAddr.High, 0);
+ MEM_WR(pDevice, SendRcb[0].HostRingAddr.Low, 0);
+ MEM_WR(pDevice, SendRcb[0].NicRingAddr,
+ pDevice->SendBdPhy.Low);
+
+ for(k = 0; k < T3_SEND_RCB_ENTRY_COUNT; k++)
+ {
+ __raw_writel(0, &(pDevice->pSendBdVirt[k].HostAddr.High));
+ __raw_writel(0, &(pDevice->pSendBdVirt[k].HostAddr.Low));
+ __raw_writel(0, &(pDevice->pSendBdVirt[k].u1.Len_Flags));
+ pDevice->ShadowSendBd[k].HostAddr.High = 0;
+ pDevice->ShadowSendBd[k].u1.Len_Flags = 0;
+ }
+ }
+ atomic_set(&pDevice->SendBdLeft, T3_SEND_RCB_ENTRY_COUNT-1);
+
+ /* Configure the receive return rings. */
+ for(j = 0; j < T3_MAX_RCV_RETURN_RCB_COUNT; j++)
+ {
+ MEM_WR(pDevice, RcvRetRcb[j].u.MaxLen_Flags, T3_RCB_FLAG_RING_DISABLED);
+ }
+
+ pDevice->RcvRetConIdx = 0;
+
+ MEM_WR(pDevice, RcvRetRcb[0].HostRingAddr.High,
+ pDevice->RcvRetBdPhy.High);
+ MEM_WR(pDevice, RcvRetRcb[0].HostRingAddr.Low,
+ pDevice->RcvRetBdPhy.Low);
+
+ /* Set up the NIC ring address in the RCB. */
+ /* Not very clear from the spec. I am guessing that for Receive */
+ /* Return Ring, NicRingAddr is not used. */
+ MEM_WR(pDevice, RcvRetRcb[0].NicRingAddr, 0);
+
+ /* Setup the RCB. */
+ MEM_WR(pDevice, RcvRetRcb[0].u.MaxLen_Flags,
+ T3_RCV_RETURN_RCB_ENTRY_COUNT << 16);
+
+ /* Reinitialize RX ring producer index */
+ MB_REG_WR(pDevice, Mailbox.RcvStdProdIdx.Low, 0);
+ MB_REG_WR(pDevice, Mailbox.RcvJumboProdIdx.Low, 0);
+ MB_REG_WR(pDevice, Mailbox.RcvMiniProdIdx.Low, 0);
+
+#if T3_JUMBO_RCV_RCB_ENTRY_COUNT
+ pDevice->RxJumboProdIdx = 0;
+ pDevice->RxJumboQueuedCnt = 0;
+#endif
+
+ /* Reinitialize our copy of the indices. */
+ pDevice->RxStdProdIdx = 0;
+ pDevice->RxStdQueuedCnt = 0;
+
+#if T3_JUMBO_RCV_ENTRY_COUNT
+ pDevice->RxJumboProdIdx = 0;
+#endif /* T3_JUMBO_RCV_ENTRY_COUNT */
+
+ /* Configure the MAC address. */
+ LM_SetMacAddress(pDevice, pDevice->NodeAddress);
+
+ /* Initialize the transmit random backoff seed. */
+ Value32 = (pDevice->NodeAddress[0] + pDevice->NodeAddress[1] +
+ pDevice->NodeAddress[2] + pDevice->NodeAddress[3] +
+ pDevice->NodeAddress[4] + pDevice->NodeAddress[5]) &
+ MAC_TX_BACKOFF_SEED_MASK;
+ REG_WR(pDevice, MacCtrl.TxBackoffSeed, Value32);
+
+ /* Receive MTU. Frames larger than the MTU is marked as oversized. */
+ REG_WR(pDevice, MacCtrl.MtuSize, pDevice->RxMtu + 8); /* CRC + VLAN. */
+
+ /* Configure Time slot/IPG per 802.3 */
+ REG_WR(pDevice, MacCtrl.TxLengths, 0x2620);
+
+ /*
+ * Configure Receive Rules so that packets don't match
+ * Programmble rule will be queued to Return Ring 1
+ */
+ REG_WR(pDevice, MacCtrl.RcvRuleCfg, RX_RULE_DEFAULT_CLASS);
+
+ /*
+ * Configure to have 16 Classes of Services (COS) and one
+ * queue per class. Bad frames are queued to RRR#1.
+ * And frames don't match rules are also queued to COS#1.
+ */
+ REG_WR(pDevice, RcvListPlmt.Config, 0x181);
+
+ /* Enable Receive Placement Statistics */
+ REG_WR(pDevice, RcvListPlmt.StatsEnableMask,0xffffff);
+ REG_WR(pDevice, RcvListPlmt.StatsCtrl, RCV_LIST_STATS_ENABLE);
+
+ /* Enable Send Data Initator Statistics */
+ REG_WR(pDevice, SndDataIn.StatsEnableMask,0xffffff);
+ REG_WR(pDevice, SndDataIn.StatsCtrl,
+ T3_SND_DATA_IN_STATS_CTRL_ENABLE | \
+ T3_SND_DATA_IN_STATS_CTRL_FASTER_UPDATE);
+
+ /* Disable the host coalescing state machine before configuring it's */
+ /* parameters. */
+ REG_WR(pDevice, HostCoalesce.Mode, 0);
+ for(j = 0; j < 2000; j++)
+ {
+ Value32 = REG_RD(pDevice, HostCoalesce.Mode);
+ if(!(Value32 & HOST_COALESCE_ENABLE))
+ {
+ break;
+ }
+ MM_Wait(10);
+ }
+
+ /* Host coalescing configurations. */
+ REG_WR(pDevice, HostCoalesce.RxCoalescingTicks, pDevice->RxCoalescingTicks);
+ REG_WR(pDevice, HostCoalesce.TxCoalescingTicks, pDevice->TxCoalescingTicks);
+ REG_WR(pDevice, HostCoalesce.RxMaxCoalescedFrames,
+ pDevice->RxMaxCoalescedFrames);
+ REG_WR(pDevice, HostCoalesce.TxMaxCoalescedFrames,
+ pDevice->TxMaxCoalescedFrames);
+ REG_WR(pDevice, HostCoalesce.RxCoalescedTickDuringInt,
+ pDevice->RxCoalescingTicksDuringInt);
+ REG_WR(pDevice, HostCoalesce.TxCoalescedTickDuringInt,
+ pDevice->TxCoalescingTicksDuringInt);
+ REG_WR(pDevice, HostCoalesce.RxMaxCoalescedFramesDuringInt,
+ pDevice->RxMaxCoalescedFramesDuringInt);
+ REG_WR(pDevice, HostCoalesce.TxMaxCoalescedFramesDuringInt,
+ pDevice->TxMaxCoalescedFramesDuringInt);
+
+ /* Initialize the address of the status block. The NIC will DMA */
+ /* the status block to this memory which resides on the host. */
+ REG_WR(pDevice, HostCoalesce.StatusBlkHostAddr.High,
+ pDevice->StatusBlkPhy.High);
+ REG_WR(pDevice, HostCoalesce.StatusBlkHostAddr.Low,
+ pDevice->StatusBlkPhy.Low);
+
+ /* Initialize the address of the statistics block. The NIC will DMA */
+ /* the statistics to this block of memory. */
+ REG_WR(pDevice, HostCoalesce.StatsBlkHostAddr.High,
+ pDevice->StatsBlkPhy.High);
+ REG_WR(pDevice, HostCoalesce.StatsBlkHostAddr.Low,
+ pDevice->StatsBlkPhy.Low);
+
+ REG_WR(pDevice, HostCoalesce.StatsCoalescingTicks,
+ pDevice->StatsCoalescingTicks);
+
+ REG_WR(pDevice, HostCoalesce.StatsBlkNicAddr, 0x300);
+ REG_WR(pDevice, HostCoalesce.StatusBlkNicAddr,0xb00);
+
+ /* Enable Host Coalesing state machine */
+ REG_WR(pDevice, HostCoalesce.Mode, HOST_COALESCE_ENABLE |
+ pDevice->CoalesceMode);
+
+ /* Enable the Receive BD Completion state machine. */
+ REG_WR(pDevice, RcvBdComp.Mode, RCV_BD_COMP_MODE_ENABLE |
+ RCV_BD_COMP_MODE_ATTN_ENABLE);
+
+ /* Enable the Receive List Placement state machine. */
+ REG_WR(pDevice, RcvListPlmt.Mode, RCV_LIST_PLMT_MODE_ENABLE);
+
+ /* Enable the Receive List Selector state machine. */
+ REG_WR(pDevice, RcvListSel.Mode, RCV_LIST_SEL_MODE_ENABLE |
+ RCV_LIST_SEL_MODE_ATTN_ENABLE);
+
+ /* Enable transmit DMA, clear statistics. */
+ pDevice->MacMode = MAC_MODE_ENABLE_TX_STATISTICS |
+ MAC_MODE_ENABLE_RX_STATISTICS | MAC_MODE_ENABLE_TDE |
+ MAC_MODE_ENABLE_RDE | MAC_MODE_ENABLE_FHDE;
+ REG_WR(pDevice, MacCtrl.Mode, pDevice->MacMode |
+ MAC_MODE_CLEAR_RX_STATISTICS | MAC_MODE_CLEAR_TX_STATISTICS);
+
+ /* GRC miscellaneous local control register. */
+ pDevice->GrcLocalCtrl = GRC_MISC_LOCAL_CTRL_INT_ON_ATTN |
+ GRC_MISC_LOCAL_CTRL_AUTO_SEEPROM;
+
+ if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700)
+ {
+ pDevice->GrcLocalCtrl |= GRC_MISC_LOCAL_CTRL_GPIO_OE1 |
+ GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT1;
+ }
+
+ REG_WR(pDevice, Grc.LocalCtrl, pDevice->GrcLocalCtrl);
+ MM_Wait(40);
+
+ /* Reset RX counters. */
+ for(j = 0; j < sizeof(LM_RX_COUNTERS); j++)
+ {
+ ((PLM_UINT8) &pDevice->RxCounters)[j] = 0;
+ }
+
+ /* Reset TX counters. */
+ for(j = 0; j < sizeof(LM_TX_COUNTERS); j++)
+ {
+ ((PLM_UINT8) &pDevice->TxCounters)[j] = 0;
+ }
+
+ MB_REG_WR(pDevice, Mailbox.Interrupt[0].Low, 0);
+
+ /* Enable the DMA Completion state machine. */
+ REG_WR(pDevice, DmaComp.Mode, DMA_COMP_MODE_ENABLE);
+
+ /* Enable the DMA Write state machine. */
+ Value32 = DMA_WRITE_MODE_ENABLE |
+ DMA_WRITE_MODE_TARGET_ABORT_ATTN_ENABLE |
+ DMA_WRITE_MODE_MASTER_ABORT_ATTN_ENABLE |
+ DMA_WRITE_MODE_PARITY_ERROR_ATTN_ENABLE |
+ DMA_WRITE_MODE_ADDR_OVERFLOW_ATTN_ENABLE |
+ DMA_WRITE_MODE_FIFO_OVERRUN_ATTN_ENABLE |
+ DMA_WRITE_MODE_FIFO_UNDERRUN_ATTN_ENABLE |
+ DMA_WRITE_MODE_FIFO_OVERREAD_ATTN_ENABLE |
+ DMA_WRITE_MODE_LONG_READ_ATTN_ENABLE;
+ REG_WR(pDevice, DmaWrite.Mode, Value32);
+
+ if (!(pDevice->PciState & T3_PCI_STATE_CONVENTIONAL_PCI_MODE))
+ {
+ if (pDevice->ChipRevId == T3_CHIP_ID_5704_A0)
+ {
+ Value16 = REG_RD(pDevice, PciCfg.PciXCommand);
+ Value16 &= ~(PCIX_CMD_MAX_SPLIT_MASK | PCIX_CMD_MAX_BURST_MASK);
+ Value16 |= ((PCIX_CMD_MAX_BURST_CPIOB << PCIX_CMD_MAX_BURST_SHL) &
+ PCIX_CMD_MAX_BURST_MASK);
+ if (pDevice->SplitModeEnable == SPLIT_MODE_ENABLE)
+ {
+ Value16 |= (pDevice->SplitModeMaxReq << PCIX_CMD_MAX_SPLIT_SHL)
+ & PCIX_CMD_MAX_SPLIT_MASK;
+ }
+ REG_WR(pDevice, PciCfg.PciXCommand, Value16);
+ }
+ }
+
+ /* Enable the Read DMA state machine. */
+ Value32 = DMA_READ_MODE_ENABLE |
+ DMA_READ_MODE_TARGET_ABORT_ATTN_ENABLE |
+ DMA_READ_MODE_MASTER_ABORT_ATTN_ENABLE |
+ DMA_READ_MODE_PARITY_ERROR_ATTN_ENABLE |
+ DMA_READ_MODE_ADDR_OVERFLOW_ATTN_ENABLE |
+ DMA_READ_MODE_FIFO_OVERRUN_ATTN_ENABLE |
+ DMA_READ_MODE_FIFO_UNDERRUN_ATTN_ENABLE |
+ DMA_READ_MODE_FIFO_OVERREAD_ATTN_ENABLE |
+ DMA_READ_MODE_LONG_READ_ATTN_ENABLE;
+
+ if (pDevice->SplitModeEnable == SPLIT_MODE_ENABLE)
+ {
+ Value32 |= DMA_READ_MODE_SPLIT_ENABLE;
+ }
+ REG_WR(pDevice, DmaRead.Mode, Value32);
+
+ /* Enable the Receive Data Completion state machine. */
+ REG_WR(pDevice, RcvDataComp.Mode, RCV_DATA_COMP_MODE_ENABLE |
+ RCV_DATA_COMP_MODE_ATTN_ENABLE);
+
+ /* Enable the Mbuf Cluster Free state machine. */
+ REG_WR(pDevice, MbufClusterFree.Mode, MBUF_CLUSTER_FREE_MODE_ENABLE);
+
+ /* Enable the Send Data Completion state machine. */
+ REG_WR(pDevice, SndDataComp.Mode, SND_DATA_COMP_MODE_ENABLE);
+
+ /* Enable the Send BD Completion state machine. */
+ REG_WR(pDevice, SndBdComp.Mode, SND_BD_COMP_MODE_ENABLE |
+ SND_BD_COMP_MODE_ATTN_ENABLE);
+
+ /* Enable the Receive BD Initiator state machine. */
+ REG_WR(pDevice, RcvBdIn.Mode, RCV_BD_IN_MODE_ENABLE |
+ RCV_BD_IN_MODE_BD_IN_DIABLED_RCB_ATTN_ENABLE);
+
+ /* Enable the Receive Data and Receive BD Initiator state machine. */
+ REG_WR(pDevice, RcvDataBdIn.Mode, RCV_DATA_BD_IN_MODE_ENABLE |
+ RCV_DATA_BD_IN_MODE_INVALID_RING_SIZE);
+
+ /* Enable the Send Data Initiator state machine. */
+ REG_WR(pDevice, SndDataIn.Mode, T3_SND_DATA_IN_MODE_ENABLE);
+
+ /* Enable the Send BD Initiator state machine. */
+ REG_WR(pDevice, SndBdIn.Mode, SND_BD_IN_MODE_ENABLE |
+ SND_BD_IN_MODE_ATTN_ENABLE);
+
+ /* Enable the Send BD Selector state machine. */
+ REG_WR(pDevice, SndBdSel.Mode, SND_BD_SEL_MODE_ENABLE |
+ SND_BD_SEL_MODE_ATTN_ENABLE);
+
+#if INCLUDE_5701_AX_FIX
+ /* Load the firmware for the 5701_A0 workaround. */
+ if(pDevice->ChipRevId == T3_CHIP_ID_5701_A0)
+ {
+ LM_LoadRlsFirmware(pDevice);
+ }
+#endif
+
+ /* Enable the transmitter. */
+ pDevice->TxMode = TX_MODE_ENABLE;
+ REG_WR(pDevice, MacCtrl.TxMode, pDevice->TxMode);
+
+ /* Enable the receiver. */
+ pDevice->RxMode = RX_MODE_ENABLE;
+ REG_WR(pDevice, MacCtrl.RxMode, pDevice->RxMode);
+
+ if (pDevice->RestoreOnWakeUp)
+ {
+ pDevice->RestoreOnWakeUp = FALSE;
+ pDevice->DisableAutoNeg = pDevice->WakeUpDisableAutoNeg;
+ pDevice->RequestedMediaType = pDevice->WakeUpRequestedMediaType;
+ }
+
+ /* Disable auto polling. */
+ pDevice->MiMode = 0xc0000;
+ REG_WR(pDevice, MacCtrl.MiMode, pDevice->MiMode);
+
+ if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700 ||
+ T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5701)
+ {
+ Value32 = LED_CTRL_PHY_MODE_1;
+ }
+ else
+ {
+ if(pDevice->LedMode == LED_MODE_OUTPUT)
+ {
+ Value32 = LED_CTRL_PHY_MODE_2;
+ }
+ else
+ {
+ Value32 = LED_CTRL_PHY_MODE_1;
+ }
+ }
+ REG_WR(pDevice, MacCtrl.LedCtrl, Value32);
+
+ /* Activate Link to enable MAC state machine */
+ REG_WR(pDevice, MacCtrl.MiStatus, MI_STATUS_ENABLE_LINK_STATUS_ATTN);
+
+ if (pDevice->EnableTbi)
+ {
+ REG_WR(pDevice, MacCtrl.RxMode, RX_MODE_RESET);
+ MM_Wait(10);
+ REG_WR(pDevice, MacCtrl.RxMode, pDevice->RxMode);
+ if (pDevice->ChipRevId == T3_CHIP_ID_5703_A1)
+ {
+ REG_WR(pDevice, MacCtrl.SerdesCfg, 0x616000);
+ }
+ }
+ /* Setup the phy chip. */
+ LM_SetupPhy(pDevice);
+
+ if (!pDevice->EnableTbi) {
+ /* Clear CRC stats */
+ LM_ReadPhy(pDevice, 0x1e, &Value32);
+ LM_WritePhy(pDevice, 0x1e, Value32 | 0x8000);
+ LM_ReadPhy(pDevice, 0x14, &Value32);
+ }
+
+ /* Set up the receive mask. */
+ LM_SetReceiveMask(pDevice, pDevice->ReceiveMask);
+
+ /* Queue Rx packet buffers. */
+ if(pDevice->QueueRxPackets)
+ {
+ LM_QueueRxPackets(pDevice);
+ }
+
+ /* Enable interrupt to the host. */
+ if(pDevice->InitDone)
+ {
+ LM_EnableInterrupt(pDevice);
+ }
+
+ return LM_STATUS_SUCCESS;
+} /* LM_ResetAdapter */
+
+
+/******************************************************************************/
+/* Description: */
+/* This routine disables the adapter from generating interrupts. */
+/* */
+/* Return: */
+/* LM_STATUS_SUCCESS */
+/******************************************************************************/
+LM_STATUS
+LM_DisableInterrupt(
+ PLM_DEVICE_BLOCK pDevice)
+{
+ REG_WR(pDevice, PciCfg.MiscHostCtrl, pDevice->MiscHostCtrl |
+ MISC_HOST_CTRL_MASK_PCI_INT);
+ MB_REG_WR(pDevice, Mailbox.Interrupt[0].Low, 1);
+
+ return LM_STATUS_SUCCESS;
+}
+
+
+
+/******************************************************************************/
+/* Description: */
+/* This routine enables the adapter to generate interrupts. */
+/* */
+/* Return: */
+/* LM_STATUS_SUCCESS */
+/******************************************************************************/
+LM_STATUS
+LM_EnableInterrupt(
+ PLM_DEVICE_BLOCK pDevice)
+{
+ REG_WR(pDevice, PciCfg.MiscHostCtrl, pDevice->MiscHostCtrl &
+ ~MISC_HOST_CTRL_MASK_PCI_INT);
+ MB_REG_WR(pDevice, Mailbox.Interrupt[0].Low, 0);
+
+ if(pDevice->pStatusBlkVirt->Status & STATUS_BLOCK_UPDATED)
+ {
+ REG_WR(pDevice, Grc.LocalCtrl, pDevice->GrcLocalCtrl |
+ GRC_MISC_LOCAL_CTRL_SET_INT);
+ }
+
+ return LM_STATUS_SUCCESS;
+}
+
+
+
+/******************************************************************************/
+/* Description: */
+/* This routine puts a packet on the wire if there is a transmit DMA */
+/* descriptor available; otherwise the packet is queued for later */
+/* transmission. If the second argue is NULL, this routine will put */
+/* the queued packet on the wire if possible. */
+/* */
+/* Return: */
+/* LM_STATUS_SUCCESS */
+/******************************************************************************/
+#if 0
+LM_STATUS
+LM_SendPacket(PLM_DEVICE_BLOCK pDevice, PLM_PACKET pPacket)
+{
+ LM_UINT32 FragCount;
+ PT3_SND_BD pSendBd;
+ PT3_SND_BD pShadowSendBd;
+ LM_UINT32 Value32, Len;
+ LM_UINT32 Idx;
+
+ if (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700) {
+ return LM_5700SendPacket(pDevice, pPacket);
+ }
+
+ /* Update the SendBdLeft count. */
+ atomic_sub(pPacket->u.Tx.FragCount, &pDevice->SendBdLeft);
+
+ /* Initalize the send buffer descriptors. */
+ Idx = pDevice->SendProdIdx;
+
+ pSendBd = &pDevice->pSendBdVirt[Idx];
+
+ /* Next producer index. */
+ if (pDevice->NicSendBd == TRUE)
+ {
+ T3_64BIT_HOST_ADDR paddr;
+
+ pShadowSendBd = &pDevice->ShadowSendBd[Idx];
+ for(FragCount = 0; ; )
+ {
+ MM_MapTxDma(pDevice, pPacket, &paddr, &Len, FragCount);
+ /* Initialize the pointer to the send buffer fragment. */
+ if (paddr.High != pShadowSendBd->HostAddr.High)
+ {
+ __raw_writel(paddr.High, &(pSendBd->HostAddr.High));
+ pShadowSendBd->HostAddr.High = paddr.High;
+ }
+ __raw_writel(paddr.Low, &(pSendBd->HostAddr.Low));
+
+ /* Setup the control flags and send buffer size. */
+ Value32 = (Len << 16) | pPacket->Flags;
+
+ Idx = (Idx + 1) & T3_SEND_RCB_ENTRY_COUNT_MASK;
+
+ FragCount++;
+ if (FragCount >= pPacket->u.Tx.FragCount)
+ {
+ Value32 |= SND_BD_FLAG_END;
+ if (Value32 != pShadowSendBd->u1.Len_Flags)
+ {
+ __raw_writel(Value32, &(pSendBd->u1.Len_Flags));
+ pShadowSendBd->u1.Len_Flags = Value32;
+ }
+ if (pPacket->Flags & SND_BD_FLAG_VLAN_TAG) {
+ __raw_writel(pPacket->VlanTag, &(pSendBd->u2.VlanTag));
+ }
+ break;
+ }
+ else
+ {
+ if (Value32 != pShadowSendBd->u1.Len_Flags)
+ {
+ __raw_writel(Value32, &(pSendBd->u1.Len_Flags));
+ pShadowSendBd->u1.Len_Flags = Value32;
+ }
+ if (pPacket->Flags & SND_BD_FLAG_VLAN_TAG) {
+ __raw_writel(pPacket->VlanTag, &(pSendBd->u2.VlanTag));
+ }
+ }
+
+ pSendBd++;
+ pShadowSendBd++;
+ if (Idx == 0)
+ {
+ pSendBd = &pDevice->pSendBdVirt[0];
+ pShadowSendBd = &pDevice->ShadowSendBd[0];
+ }
+ } /* for */
+
+ /* Put the packet descriptor in the ActiveQ. */
+ QQ_PushTail(&pDevice->TxPacketActiveQ.Container, pPacket);
+
+ wmb();
+ MB_REG_WR(pDevice, Mailbox.SendNicProdIdx[0].Low, Idx);
+
+ }
+ else
+ {
+ for(FragCount = 0; ; )
+ {
+ /* Initialize the pointer to the send buffer fragment. */
+ MM_MapTxDma(pDevice, pPacket, &pSendBd->HostAddr, &Len, FragCount);
+
+ pSendBd->u2.VlanTag = pPacket->VlanTag;
+
+ /* Setup the control flags and send buffer size. */
+ Value32 = (Len << 16) | pPacket->Flags;
+
+ Idx = (Idx + 1) & T3_SEND_RCB_ENTRY_COUNT_MASK;
+
+ FragCount++;
+ if (FragCount >= pPacket->u.Tx.FragCount)
+ {
+ pSendBd->u1.Len_Flags = Value32 | SND_BD_FLAG_END;
+ break;
+ }
+ else
+ {
+ pSendBd->u1.Len_Flags = Value32;
+ }
+ pSendBd++;
+ if (Idx == 0)
+ {
+ pSendBd = &pDevice->pSendBdVirt[0];
+ }
+ } /* for */
+
+ /* Put the packet descriptor in the ActiveQ. */
+ QQ_PushTail(&pDevice->TxPacketActiveQ.Container, pPacket);
+
+ wmb();
+ MB_REG_WR(pDevice, Mailbox.SendHostProdIdx[0].Low, Idx);
+
+ }
+
+ /* Update the producer index. */
+ pDevice->SendProdIdx = Idx;
+
+ return LM_STATUS_SUCCESS;
+}
+#endif
+
+LM_STATUS
+LM_SendPacket(PLM_DEVICE_BLOCK pDevice, PLM_PACKET pPacket)
+{
+ LM_UINT32 FragCount;
+ PT3_SND_BD pSendBd, pTmpSendBd, pShadowSendBd;
+ T3_SND_BD NicSendBdArr[MAX_FRAGMENT_COUNT];
+ LM_UINT32 StartIdx, Idx;
+
+ while (1)
+ {
+ /* Initalize the send buffer descriptors. */
+ StartIdx = Idx = pDevice->SendProdIdx;
+
+ if (pDevice->NicSendBd)
+ {
+ pTmpSendBd = pSendBd = &NicSendBdArr[0];
+ }
+ else
+ {
+ pTmpSendBd = pSendBd = &pDevice->pSendBdVirt[Idx];
+ }
+
+ /* Next producer index. */
+ for(FragCount = 0; ; )
+ {
+ LM_UINT32 Value32, Len;
+
+ /* Initialize the pointer to the send buffer fragment. */
+ MM_MapTxDma(pDevice, pPacket, &pSendBd->HostAddr, &Len, FragCount);
+
+ pSendBd->u2.VlanTag = pPacket->VlanTag;
+
+ /* Setup the control flags and send buffer size. */
+ Value32 = (Len << 16) | pPacket->Flags;
+
+ Idx = (Idx + 1) & T3_SEND_RCB_ENTRY_COUNT_MASK;
+
+ FragCount++;
+ if (FragCount >= pPacket->u.Tx.FragCount)
+ {
+ pSendBd->u1.Len_Flags = Value32 | SND_BD_FLAG_END;
+ break;
+ }
+ else
+ {
+ pSendBd->u1.Len_Flags = Value32;
+ }
+ pSendBd++;
+ if ((Idx == 0) && !pDevice->NicSendBd)
+ {
+ pSendBd = &pDevice->pSendBdVirt[0];
+ }
+ } /* for */
+ if (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700)
+ {
+ if (LM_Test4GBoundary(pDevice, pPacket, pTmpSendBd) ==
+ LM_STATUS_SUCCESS)
+ {
+ if (MM_CoalesceTxBuffer(pDevice, pPacket) != LM_STATUS_SUCCESS)
+ {
+ QQ_PushHead(&pDevice->TxPacketFreeQ.Container, pPacket);
+ return LM_STATUS_FAILURE;
+ }
+ continue;
+ }
+ }
+ break;
+ }
+ /* Put the packet descriptor in the ActiveQ. */
+ QQ_PushTail(&pDevice->TxPacketActiveQ.Container, pPacket);
+
+ if (pDevice->NicSendBd)
+ {
+ pSendBd = &pDevice->pSendBdVirt[StartIdx];
+ pShadowSendBd = &pDevice->ShadowSendBd[StartIdx];
+
+ while (StartIdx != Idx)
+ {
+ LM_UINT32 Value32;
+
+ if ((Value32 = pTmpSendBd->HostAddr.High) !=
+ pShadowSendBd->HostAddr.High)
+ {
+ __raw_writel(Value32, &(pSendBd->HostAddr.High));
+ pShadowSendBd->HostAddr.High = Value32;
+ }
+
+ __raw_writel(pTmpSendBd->HostAddr.Low, &(pSendBd->HostAddr.Low));
+
+ if ((Value32 = pTmpSendBd->u1.Len_Flags) !=
+ pShadowSendBd->u1.Len_Flags)
+ {
+ __raw_writel(Value32, &(pSendBd->u1.Len_Flags));
+ pShadowSendBd->u1.Len_Flags = Value32;
+ }
+
+ if (pPacket->Flags & SND_BD_FLAG_VLAN_TAG)
+ {
+ __raw_writel(pTmpSendBd->u2.VlanTag, &(pSendBd->u2.VlanTag));
+ }
+
+ StartIdx = (StartIdx + 1) & T3_SEND_RCB_ENTRY_COUNT_MASK;
+ if (StartIdx == 0)
+ pSendBd = &pDevice->pSendBdVirt[0];
+ else
+ pSendBd++;
+ pTmpSendBd++;
+ }
+ wmb();
+ MB_REG_WR(pDevice, Mailbox.SendNicProdIdx[0].Low, Idx);
+
+ if(T3_CHIP_REV(pDevice->ChipRevId) == T3_CHIP_REV_5700_BX)
+ {
+ MB_REG_WR(pDevice, Mailbox.SendNicProdIdx[0].Low, Idx);
+ }
+ }
+ else
+ {
+ wmb();
+ MB_REG_WR(pDevice, Mailbox.SendHostProdIdx[0].Low, Idx);
+
+ if(T3_CHIP_REV(pDevice->ChipRevId) == T3_CHIP_REV_5700_BX)
+ {
+ MB_REG_WR(pDevice, Mailbox.SendHostProdIdx[0].Low, Idx);
+ }
+ }
+
+ /* Update the SendBdLeft count. */
+ atomic_sub(pPacket->u.Tx.FragCount, &pDevice->SendBdLeft);
+
+ /* Update the producer index. */
+ pDevice->SendProdIdx = Idx;
+
+ return LM_STATUS_SUCCESS;
+}
+
+STATIC LM_STATUS
+LM_Test4GBoundary(PLM_DEVICE_BLOCK pDevice, PLM_PACKET pPacket,
+ PT3_SND_BD pSendBd)
+{
+ int FragCount;
+ LM_UINT32 Idx, Base, Len;
+
+ Idx = pDevice->SendProdIdx;
+ for(FragCount = 0; ; )
+ {
+ Len = pSendBd->u1.Len_Flags >> 16;
+ if (((Base = pSendBd->HostAddr.Low) > 0xffffdcc0) &&
+ (pSendBd->HostAddr.High == 0) &&
+ ((Base + 8 + Len) < Base))
+ {
+ return LM_STATUS_SUCCESS;
+ }
+ FragCount++;
+ if (FragCount >= pPacket->u.Tx.FragCount)
+ {
+ break;
+ }
+ pSendBd++;
+ if (!pDevice->NicSendBd)
+ {
+ Idx = (Idx + 1) & T3_SEND_RCB_ENTRY_COUNT_MASK;
+ if (Idx == 0)
+ {
+ pSendBd = &pDevice->pSendBdVirt[0];
+ }
+ }
+ }
+ return LM_STATUS_FAILURE;
+}
+
+/******************************************************************************/
+/* Description: */
+/* */
+/* Return: */
+/******************************************************************************/
+__inline static unsigned long
+ComputeCrc32(
+unsigned char *pBuffer,
+unsigned long BufferSize) {
+ unsigned long Reg;
+ unsigned long Tmp;
+ unsigned long j, k;
+
+ Reg = 0xffffffff;
+
+ for(j = 0; j < BufferSize; j++)
+ {
+ Reg ^= pBuffer[j];
+
+ for(k = 0; k < 8; k++)
+ {
+ Tmp = Reg & 0x01;
+
+ Reg >>= 1;
+
+ if(Tmp)
+ {
+ Reg ^= 0xedb88320;
+ }
+ }
+ }
+
+ return ~Reg;
+} /* ComputeCrc32 */
+
+
+
+/******************************************************************************/
+/* Description: */
+/* This routine sets the receive control register according to ReceiveMask */
+/* */
+/* Return: */
+/* LM_STATUS_SUCCESS */
+/******************************************************************************/
+LM_STATUS
+LM_SetReceiveMask(
+PLM_DEVICE_BLOCK pDevice,
+LM_UINT32 Mask) {
+ LM_UINT32 ReceiveMask;
+ LM_UINT32 RxMode;
+ LM_UINT32 j, k;
+
+ ReceiveMask = Mask;
+
+ RxMode = pDevice->RxMode;
+
+ if(Mask & LM_ACCEPT_UNICAST)
+ {
+ Mask &= ~LM_ACCEPT_UNICAST;
+ }
+
+ if(Mask & LM_ACCEPT_MULTICAST)
+ {
+ Mask &= ~LM_ACCEPT_MULTICAST;
+ }
+
+ if(Mask & LM_ACCEPT_ALL_MULTICAST)
+ {
+ Mask &= ~LM_ACCEPT_ALL_MULTICAST;
+ }
+
+ if(Mask & LM_ACCEPT_BROADCAST)
+ {
+ Mask &= ~LM_ACCEPT_BROADCAST;
+ }
+
+ RxMode &= ~RX_MODE_PROMISCUOUS_MODE;
+ if(Mask & LM_PROMISCUOUS_MODE)
+ {
+ RxMode |= RX_MODE_PROMISCUOUS_MODE;
+ Mask &= ~LM_PROMISCUOUS_MODE;
+ }
+
+ RxMode &= ~(RX_MODE_ACCEPT_RUNTS | RX_MODE_ACCEPT_OVERSIZED);
+ if(Mask & LM_ACCEPT_ERROR_PACKET)
+ {
+ RxMode |= RX_MODE_ACCEPT_RUNTS | RX_MODE_ACCEPT_OVERSIZED;
+ Mask &= ~LM_ACCEPT_ERROR_PACKET;
+ }
+
+ /* Make sure all the bits are valid before committing changes. */
+ if(Mask)
+ {
+ return LM_STATUS_FAILURE;
+ }
+
+ /* Commit the new filter. */
+ pDevice->RxMode = RxMode;
+ REG_WR(pDevice, MacCtrl.RxMode, RxMode);
+
+ pDevice->ReceiveMask = ReceiveMask;
+
+ /* Set up the MC hash table. */
+ if(ReceiveMask & LM_ACCEPT_ALL_MULTICAST)
+ {
+ for(k = 0; k < 4; k++)
+ {
+ REG_WR(pDevice, MacCtrl.HashReg[k], 0xffffffff);
+ }
+ }
+ else if(ReceiveMask & LM_ACCEPT_MULTICAST)
+ {
+ LM_UINT32 HashReg[4];
+
+ HashReg[0] = 0; HashReg[1] = 0; HashReg[2] = 0; HashReg[3] = 0;
+ for(j = 0; j < pDevice->McEntryCount; j++)
+ {
+ LM_UINT32 RegIndex;
+ LM_UINT32 Bitpos;
+ LM_UINT32 Crc32;
+
+ Crc32 = ComputeCrc32(pDevice->McTable[j], ETHERNET_ADDRESS_SIZE);
+
+ /* The most significant 7 bits of the CRC32 (no inversion), */
+ /* are used to index into one of the possible 128 bit positions. */
+ Bitpos = ~Crc32 & 0x7f;
+
+ /* Hash register index. */
+ RegIndex = (Bitpos & 0x60) >> 5;
+
+ /* Bit to turn on within a hash register. */
+ Bitpos &= 0x1f;
+
+ /* Enable the multicast bit. */
+ HashReg[RegIndex] |= (1 << Bitpos);
+ }
+
+ /* REV_AX has problem with multicast filtering where it uses both */
+ /* DA and SA to perform hashing. */
+ for(k = 0; k < 4; k++)
+ {
+ REG_WR(pDevice, MacCtrl.HashReg[k], HashReg[k]);
+ }
+ }
+ else
+ {
+ /* Reject all multicast frames. */
+ for(j = 0; j < 4; j++)
+ {
+ REG_WR(pDevice, MacCtrl.HashReg[j], 0);
+ }
+ }
+
+ /* By default, Tigon3 will accept broadcast frames. We need to setup */
+ if(ReceiveMask & LM_ACCEPT_BROADCAST)
+ {
+ REG_WR(pDevice, MacCtrl.RcvRules[RCV_RULE1_REJECT_BROADCAST_IDX].Rule,
+ REJECT_BROADCAST_RULE1_RULE & RCV_DISABLE_RULE_MASK);
+ REG_WR(pDevice, MacCtrl.RcvRules[RCV_RULE1_REJECT_BROADCAST_IDX].Value,
+ REJECT_BROADCAST_RULE1_VALUE & RCV_DISABLE_RULE_MASK);
+ REG_WR(pDevice, MacCtrl.RcvRules[RCV_RULE2_REJECT_BROADCAST_IDX].Rule,
+ REJECT_BROADCAST_RULE1_RULE & RCV_DISABLE_RULE_MASK);
+ REG_WR(pDevice, MacCtrl.RcvRules[RCV_RULE2_REJECT_BROADCAST_IDX].Value,
+ REJECT_BROADCAST_RULE1_VALUE & RCV_DISABLE_RULE_MASK);
+ }
+ else
+ {
+ REG_WR(pDevice, MacCtrl.RcvRules[RCV_RULE1_REJECT_BROADCAST_IDX].Rule,
+ REJECT_BROADCAST_RULE1_RULE);
+ REG_WR(pDevice, MacCtrl.RcvRules[RCV_RULE1_REJECT_BROADCAST_IDX].Value,
+ REJECT_BROADCAST_RULE1_VALUE);
+ REG_WR(pDevice, MacCtrl.RcvRules[RCV_RULE2_REJECT_BROADCAST_IDX].Rule,
+ REJECT_BROADCAST_RULE2_RULE);
+ REG_WR(pDevice, MacCtrl.RcvRules[RCV_RULE2_REJECT_BROADCAST_IDX].Value,
+ REJECT_BROADCAST_RULE2_VALUE);
+ }
+
+ /* disable the rest of the rules. */
+ for(j = RCV_LAST_RULE_IDX; j < 16; j++)
+ {
+ REG_WR(pDevice, MacCtrl.RcvRules[j].Rule, 0);
+ REG_WR(pDevice, MacCtrl.RcvRules[j].Value, 0);
+ }
+
+ return LM_STATUS_SUCCESS;
+} /* LM_SetReceiveMask */
+
+
+
+/******************************************************************************/
+/* Description: */
+/* Disable the interrupt and put the transmitter and receiver engines in */
+/* an idle state. Also aborts all pending send requests and receive */
+/* buffers. */
+/* */
+/* Return: */
+/* LM_STATUS_SUCCESS */
+/******************************************************************************/
+LM_STATUS
+LM_Abort(
+PLM_DEVICE_BLOCK pDevice)
+{
+ PLM_PACKET pPacket;
+ LM_UINT Idx;
+
+ LM_DisableInterrupt(pDevice);
+
+ /* Disable all the state machines. */
+ LM_CntrlBlock(pDevice,T3_BLOCK_MAC_RX_ENGINE,LM_DISABLE);
+ LM_CntrlBlock(pDevice,T3_BLOCK_RX_BD_INITIATOR,LM_DISABLE);
+ LM_CntrlBlock(pDevice,T3_BLOCK_RX_LIST_PLMT,LM_DISABLE);
+ LM_CntrlBlock(pDevice,T3_BLOCK_RX_LIST_SELECTOR,LM_DISABLE);
+ LM_CntrlBlock(pDevice,T3_BLOCK_RX_DATA_INITIATOR,LM_DISABLE);
+ LM_CntrlBlock(pDevice,T3_BLOCK_RX_DATA_COMP,LM_DISABLE);
+ LM_CntrlBlock(pDevice,T3_BLOCK_RX_BD_COMP,LM_DISABLE);
+
+ LM_CntrlBlock(pDevice,T3_BLOCK_SEND_BD_SELECTOR,LM_DISABLE);
+ LM_CntrlBlock(pDevice,T3_BLOCK_SEND_BD_INITIATOR,LM_DISABLE);
+ LM_CntrlBlock(pDevice,T3_BLOCK_SEND_DATA_INITIATOR,LM_DISABLE);
+ LM_CntrlBlock(pDevice,T3_BLOCK_DMA_RD,LM_DISABLE);
+ LM_CntrlBlock(pDevice,T3_BLOCK_SEND_DATA_COMP,LM_DISABLE);
+ LM_CntrlBlock(pDevice,T3_BLOCK_DMA_COMP,LM_DISABLE);
+ LM_CntrlBlock(pDevice,T3_BLOCK_SEND_BD_COMP,LM_DISABLE);
+
+ /* Clear TDE bit */
+ pDevice->MacMode &= ~MAC_MODE_ENABLE_TDE;
+ REG_WR(pDevice, MacCtrl.Mode, pDevice->MacMode);
+
+ LM_CntrlBlock(pDevice,T3_BLOCK_MAC_TX_ENGINE,LM_DISABLE);
+ LM_CntrlBlock(pDevice,T3_BLOCK_HOST_COALESING,LM_DISABLE);
+ LM_CntrlBlock(pDevice,T3_BLOCK_DMA_WR,LM_DISABLE);
+ LM_CntrlBlock(pDevice,T3_BLOCK_MBUF_CLUSTER_FREE,LM_DISABLE);
+
+ /* Reset all FTQs */
+ REG_WR(pDevice, Ftq.Reset, 0xffffffff);
+ REG_WR(pDevice, Ftq.Reset, 0x0);
+
+ LM_CntrlBlock(pDevice,T3_BLOCK_MBUF_MANAGER,LM_DISABLE);
+ LM_CntrlBlock(pDevice,T3_BLOCK_MEM_ARBITOR,LM_DISABLE);
+
+ MM_ACQUIRE_INT_LOCK(pDevice);
+
+ /* Abort packets that have already queued to go out. */
+ pPacket = (PLM_PACKET) QQ_PopHead(&pDevice->TxPacketActiveQ.Container);
+ while(pPacket)
+ {
+
+ pPacket->PacketStatus = LM_STATUS_TRANSMIT_ABORTED;
+ pDevice->TxCounters.TxPacketAbortedCnt++;
+
+ atomic_add(pPacket->u.Tx.FragCount, &pDevice->SendBdLeft);
+
+ QQ_PushTail(&pDevice->TxPacketXmittedQ.Container, pPacket);
+
+ pPacket = (PLM_PACKET)
+ QQ_PopHead(&pDevice->TxPacketActiveQ.Container);
+ }
+
+ /* Cleanup the receive return rings. */
+ LM_ServiceRxInterrupt(pDevice);
+
+ /* Don't want to indicate rx packets in Ndis miniport shutdown context. */
+ /* Doing so may cause system crash. */
+ if(!pDevice->ShuttingDown)
+ {
+ /* Indicate packets to the protocol. */
+ MM_IndicateTxPackets(pDevice);
+
+ /* Indicate received packets to the protocols. */
+ MM_IndicateRxPackets(pDevice);
+ }
+ else
+ {
+ /* Move the receive packet descriptors in the ReceivedQ to the */
+ /* free queue. */
+ for(; ;)
+ {
+ pPacket = (PLM_PACKET) QQ_PopHead(
+ &pDevice->RxPacketReceivedQ.Container);
+ if(pPacket == NULL)
+ {
+ break;
+ }
+ QQ_PushTail(&pDevice->RxPacketFreeQ.Container, pPacket);
+ }
+ }
+
+ /* Clean up the Std Receive Producer ring. */
+ Idx = pDevice->pStatusBlkVirt->RcvStdConIdx;
+
+ while(Idx != pDevice->RxStdProdIdx) {
+ pPacket = (PLM_PACKET) (MM_UINT_PTR(pDevice->pPacketDescBase) +
+ MM_UINT_PTR(pDevice->pRxStdBdVirt[Idx].Opaque));
+
+ QQ_PushTail(&pDevice->RxPacketFreeQ.Container, pPacket);
+
+ Idx = (Idx + 1) & T3_STD_RCV_RCB_ENTRY_COUNT_MASK;
+ } /* while */
+
+ /* Reinitialize our copy of the indices. */
+ pDevice->RxStdProdIdx = 0;
+
+#if T3_JUMBO_RCV_RCB_ENTRY_COUNT
+ /* Clean up the Jumbo Receive Producer ring. */
+ Idx = pDevice->pStatusBlkVirt->RcvJumboConIdx;
+
+ while(Idx != pDevice->RxJumboProdIdx) {
+ pPacket = (PLM_PACKET) (MM_UINT_PTR(pDevice->pPacketDescBase) +
+ MM_UINT_PTR(pDevice->pRxJumboBdVirt[Idx].Opaque));
+
+ QQ_PushTail(&pDevice->RxPacketFreeQ.Container, pPacket);
+
+ Idx = (Idx + 1) & T3_JUMBO_RCV_RCB_ENTRY_COUNT_MASK;
+ } /* while */
+
+ /* Reinitialize our copy of the indices. */
+ pDevice->RxJumboProdIdx = 0;
+#endif /* T3_JUMBO_RCV_RCB_ENTRY_COUNT */
+
+ MM_RELEASE_INT_LOCK(pDevice);
+
+ /* Initialize the statistis Block */
+ pDevice->pStatusBlkVirt->Status = 0;
+ pDevice->pStatusBlkVirt->RcvStdConIdx = 0;
+ pDevice->pStatusBlkVirt->RcvJumboConIdx = 0;
+ pDevice->pStatusBlkVirt->RcvMiniConIdx = 0;
+
+ return LM_STATUS_SUCCESS;
+} /* LM_Abort */
+
+
+
+/******************************************************************************/
+/* Description: */
+/* Disable the interrupt and put the transmitter and receiver engines in */
+/* an idle state. Aborts all pending send requests and receive buffers. */
+/* Also free all the receive buffers. */
+/* */
+/* Return: */
+/* LM_STATUS_SUCCESS */
+/******************************************************************************/
+LM_STATUS
+LM_Halt(
+PLM_DEVICE_BLOCK pDevice) {
+ PLM_PACKET pPacket;
+ LM_UINT32 EntryCnt;
+
+ LM_Abort(pDevice);
+
+ /* Get the number of entries in the queue. */
+ EntryCnt = QQ_GetEntryCnt(&pDevice->RxPacketFreeQ.Container);
+
+ /* Make sure all the packets have been accounted for. */
+ for(EntryCnt = 0; EntryCnt < pDevice->RxPacketDescCnt; EntryCnt++)
+ {
+ pPacket = (PLM_PACKET) QQ_PopHead(&pDevice->RxPacketFreeQ.Container);
+ if (pPacket == 0)
+ break;
+
+ MM_FreeRxBuffer(pDevice, pPacket);
+
+ QQ_PushTail(&pDevice->RxPacketFreeQ.Container, pPacket);
+ }
+
+ LM_ResetChip(pDevice);
+
+ /* Restore PCI configuration registers. */
+ MM_WriteConfig32(pDevice, PCI_CACHE_LINE_SIZE_REG,
+ pDevice->SavedCacheLineReg);
+ LM_RegWrInd(pDevice, PCI_SUBSYSTEM_VENDOR_ID_REG,
+ (pDevice->SubsystemId << 16) | pDevice->SubsystemVendorId);
+
+ /* Reprogram the MAC address. */
+ LM_SetMacAddress(pDevice, pDevice->NodeAddress);
+
+ return LM_STATUS_SUCCESS;
+} /* LM_Halt */
+
+
+STATIC LM_STATUS
+LM_ResetChip(PLM_DEVICE_BLOCK pDevice)
+{
+ LM_UINT32 Value32;
+ LM_UINT32 j;
+
+ /* Wait for access to the nvram interface before resetting. This is */
+ /* a workaround to prevent EEPROM corruption. */
+ if(T3_ASIC_REV(pDevice->ChipRevId) != T3_ASIC_REV_5700 &&
+ T3_ASIC_REV(pDevice->ChipRevId) != T3_ASIC_REV_5701)
+ {
+ /* Request access to the flash interface. */
+ REG_WR(pDevice, Nvram.SwArb, SW_ARB_REQ_SET1);
+
+ for(j = 0; j < 100000; j++)
+ {
+ Value32 = REG_RD(pDevice, Nvram.SwArb);
+ if(Value32 & SW_ARB_GNT1)
+ {
+ break;
+ }
+ MM_Wait(10);
+ }
+ }
+
+ /* Global reset. */
+ REG_WR(pDevice, Grc.MiscCfg, GRC_MISC_CFG_CORE_CLOCK_RESET);
+ MM_Wait(40); MM_Wait(40); MM_Wait(40);
+
+ /* make sure we re-enable indirect accesses */
+ MM_WriteConfig32(pDevice, T3_PCI_MISC_HOST_CTRL_REG,
+ pDevice->MiscHostCtrl);
+
+ /* Set MAX PCI retry to zero. */
+ Value32 = T3_PCI_STATE_PCI_ROM_ENABLE | T3_PCI_STATE_PCI_ROM_RETRY_ENABLE;
+ if (pDevice->ChipRevId == T3_CHIP_ID_5704_A0)
+ {
+ if (!(pDevice->PciState & T3_PCI_STATE_CONVENTIONAL_PCI_MODE))
+ {
+ Value32 |= T3_PCI_STATE_RETRY_SAME_DMA;
+ }
+ }
+ MM_WriteConfig32(pDevice, T3_PCI_STATE_REG, Value32);
+
+ /* Restore PCI command register. */
+ MM_WriteConfig32(pDevice, PCI_COMMAND_REG,
+ pDevice->PciCommandStatusWords);
+
+ /* Disable PCI-X relaxed ordering bit. */
+ MM_ReadConfig32(pDevice, PCIX_CAP_REG, &Value32);
+ Value32 &= ~PCIX_ENABLE_RELAXED_ORDERING;
+ MM_WriteConfig32(pDevice, PCIX_CAP_REG, Value32);
+
+ /* Enable memory arbiter. */
+ REG_WR(pDevice, MemArbiter.Mode, T3_MEM_ARBITER_MODE_ENABLE);
+
+#ifdef BIG_ENDIAN_PCI /* This from jfd */
+ Value32 = GRC_MODE_WORD_SWAP_DATA|
+ GRC_MODE_WORD_SWAP_NON_FRAME_DATA;
+#else
+#ifdef BIG_ENDIAN_HOST
+ /* Reconfigure the mode register. */
+ Value32 = GRC_MODE_BYTE_SWAP_NON_FRAME_DATA |
+ GRC_MODE_WORD_SWAP_NON_FRAME_DATA |
+ GRC_MODE_BYTE_SWAP_DATA |
+ GRC_MODE_WORD_SWAP_DATA;
+#else
+ /* Reconfigure the mode register. */
+ Value32 = GRC_MODE_BYTE_SWAP_NON_FRAME_DATA | GRC_MODE_BYTE_SWAP_DATA;
+#endif
+#endif
+ REG_WR(pDevice, Grc.Mode, Value32);
+
+ /* Prevent PXE from restarting. */
+ MEM_WR_OFFSET(pDevice, 0x0b50, T3_MAGIC_NUM);
+
+ if(pDevice->EnableTbi) {
+ pDevice->MacMode = MAC_MODE_PORT_MODE_TBI;
+ REG_WR(pDevice, MacCtrl.Mode, MAC_MODE_PORT_MODE_TBI);
+ }
+ else {
+ REG_WR(pDevice, MacCtrl.Mode, 0);
+ }
+
+ /* Wait for the firmware to finish initialization. */
+ for(j = 0; j < 100000; j++)
+ {
+ MM_Wait(10);
+
+ Value32 = MEM_RD_OFFSET(pDevice, 0x0b50);
+ if(Value32 == ~T3_MAGIC_NUM)
+ {
+ break;
+ }
+ }
+ return LM_STATUS_SUCCESS;
+}
+
+/******************************************************************************/
+/* Description: */
+/* */
+/* Return: */
+/******************************************************************************/
+__inline static void
+LM_ServiceTxInterrupt(
+PLM_DEVICE_BLOCK pDevice) {
+ PLM_PACKET pPacket;
+ LM_UINT32 HwConIdx;
+ LM_UINT32 SwConIdx;
+
+ HwConIdx = pDevice->pStatusBlkVirt->Idx[0].SendConIdx;
+
+ /* Get our copy of the consumer index. The buffer descriptors */
+ /* that are in between the consumer indices are freed. */
+ SwConIdx = pDevice->SendConIdx;
+
+ /* Move the packets from the TxPacketActiveQ that are sent out to */
+ /* the TxPacketXmittedQ. Packets that are sent use the */
+ /* descriptors that are between SwConIdx and HwConIdx. */
+ while(SwConIdx != HwConIdx)
+ {
+ /* Get the packet that was sent from the TxPacketActiveQ. */
+ pPacket = (PLM_PACKET) QQ_PopHead(
+ &pDevice->TxPacketActiveQ.Container);
+
+ /* Set the return status. */
+ pPacket->PacketStatus = LM_STATUS_SUCCESS;
+
+ /* Put the packet in the TxPacketXmittedQ for indication later. */
+ QQ_PushTail(&pDevice->TxPacketXmittedQ.Container, pPacket);
+
+ /* Move to the next packet's BD. */
+ SwConIdx = (SwConIdx + pPacket->u.Tx.FragCount) &
+ T3_SEND_RCB_ENTRY_COUNT_MASK;
+
+ /* Update the number of unused BDs. */
+ atomic_add(pPacket->u.Tx.FragCount, &pDevice->SendBdLeft);
+
+ /* Get the new updated HwConIdx. */
+ HwConIdx = pDevice->pStatusBlkVirt->Idx[0].SendConIdx;
+ } /* while */
+
+ /* Save the new SwConIdx. */
+ pDevice->SendConIdx = SwConIdx;
+
+} /* LM_ServiceTxInterrupt */
+
+
+
+/******************************************************************************/
+/* Description: */
+/* */
+/* Return: */
+/******************************************************************************/
+__inline static void
+LM_ServiceRxInterrupt(
+PLM_DEVICE_BLOCK pDevice) {
+ PLM_PACKET pPacket;
+ PT3_RCV_BD pRcvBd;
+ LM_UINT32 HwRcvRetProdIdx;
+ LM_UINT32 SwRcvRetConIdx;
+
+ /* Loop thru the receive return rings for received packets. */
+ HwRcvRetProdIdx = pDevice->pStatusBlkVirt->Idx[0].RcvProdIdx;
+
+ SwRcvRetConIdx = pDevice->RcvRetConIdx;
+ while(SwRcvRetConIdx != HwRcvRetProdIdx)
+ {
+ pRcvBd = &pDevice->pRcvRetBdVirt[SwRcvRetConIdx];
+
+ /* Get the received packet descriptor. */
+ pPacket = (PLM_PACKET) (MM_UINT_PTR(pDevice->pPacketDescBase) +
+ MM_UINT_PTR(pRcvBd->Opaque));
+
+ /* Check the error flag. */
+ if(pRcvBd->ErrorFlag &&
+ pRcvBd->ErrorFlag != RCV_BD_ERR_ODD_NIBBLED_RCVD_MII)
+ {
+ pPacket->PacketStatus = LM_STATUS_FAILURE;
+
+ pDevice->RxCounters.RxPacketErrCnt++;
+
+ if(pRcvBd->ErrorFlag & RCV_BD_ERR_BAD_CRC)
+ {
+ pDevice->RxCounters.RxErrCrcCnt++;
+ }
+
+ if(pRcvBd->ErrorFlag & RCV_BD_ERR_COLL_DETECT)
+ {
+ pDevice->RxCounters.RxErrCollCnt++;
+ }
+
+ if(pRcvBd->ErrorFlag & RCV_BD_ERR_LINK_LOST_DURING_PKT)
+ {
+ pDevice->RxCounters.RxErrLinkLostCnt++;
+ }
+
+ if(pRcvBd->ErrorFlag & RCV_BD_ERR_PHY_DECODE_ERR)
+ {
+ pDevice->RxCounters.RxErrPhyDecodeCnt++;
+ }
+
+ if(pRcvBd->ErrorFlag & RCV_BD_ERR_ODD_NIBBLED_RCVD_MII)
+ {
+ pDevice->RxCounters.RxErrOddNibbleCnt++;
+ }
+
+ if(pRcvBd->ErrorFlag & RCV_BD_ERR_MAC_ABORT)
+ {
+ pDevice->RxCounters.RxErrMacAbortCnt++;
+ }
+
+ if(pRcvBd->ErrorFlag & RCV_BD_ERR_LEN_LT_64)
+ {
+ pDevice->RxCounters.RxErrShortPacketCnt++;
+ }
+
+ if(pRcvBd->ErrorFlag & RCV_BD_ERR_TRUNC_NO_RESOURCES)
+ {
+ pDevice->RxCounters.RxErrNoResourceCnt++;
+ }
+
+ if(pRcvBd->ErrorFlag & RCV_BD_ERR_GIANT_FRAME_RCVD)
+ {
+ pDevice->RxCounters.RxErrLargePacketCnt++;
+ }
+ }
+ else
+ {
+ pPacket->PacketStatus = LM_STATUS_SUCCESS;
+ pPacket->PacketSize = pRcvBd->Len - 4;
+
+ pPacket->Flags = pRcvBd->Flags;
+ if(pRcvBd->Flags & RCV_BD_FLAG_VLAN_TAG)
+ {
+ pPacket->VlanTag = pRcvBd->VlanTag;
+ }
+
+ pPacket->u.Rx.TcpUdpChecksum = pRcvBd->TcpUdpCksum;
+ }
+
+ /* Put the packet descriptor containing the received packet */
+ /* buffer in the RxPacketReceivedQ for indication later. */
+ QQ_PushTail(&pDevice->RxPacketReceivedQ.Container, pPacket);
+
+ /* Go to the next buffer descriptor. */
+ SwRcvRetConIdx = (SwRcvRetConIdx + 1) &
+ T3_RCV_RETURN_RCB_ENTRY_COUNT_MASK;
+
+ /* Get the updated HwRcvRetProdIdx. */
+ HwRcvRetProdIdx = pDevice->pStatusBlkVirt->Idx[0].RcvProdIdx;
+ } /* while */
+
+ pDevice->RcvRetConIdx = SwRcvRetConIdx;
+
+ /* Update the receive return ring consumer index. */
+ MB_REG_WR(pDevice, Mailbox.RcvRetConIdx[0].Low, SwRcvRetConIdx);
+} /* LM_ServiceRxInterrupt */
+
+
+
+/******************************************************************************/
+/* Description: */
+/* This is the interrupt event handler routine. It acknowledges all */
+/* pending interrupts and process all pending events. */
+/* */
+/* Return: */
+/* LM_STATUS_SUCCESS */
+/******************************************************************************/
+LM_STATUS
+LM_ServiceInterrupts(
+ PLM_DEVICE_BLOCK pDevice)
+{
+ LM_UINT32 Value32;
+ int ServicePhyInt = FALSE;
+
+ /* Setup the phy chip whenever the link status changes. */
+ if(pDevice->LinkChngMode == T3_LINK_CHNG_MODE_USE_STATUS_REG)
+ {
+ Value32 = REG_RD(pDevice, MacCtrl.Status);
+ if(pDevice->PhyIntMode == T3_PHY_INT_MODE_MI_INTERRUPT)
+ {
+ if (Value32 & MAC_STATUS_MI_INTERRUPT)
+ {
+ ServicePhyInt = TRUE;
+ }
+ }
+ else if(Value32 & MAC_STATUS_LINK_STATE_CHANGED)
+ {
+ ServicePhyInt = TRUE;
+ }
+ }
+ else
+ {
+ if(pDevice->pStatusBlkVirt->Status & STATUS_BLOCK_LINK_CHANGED_STATUS)
+ {
+ pDevice->pStatusBlkVirt->Status = STATUS_BLOCK_UPDATED |
+ (pDevice->pStatusBlkVirt->Status & ~STATUS_BLOCK_LINK_CHANGED_STATUS);
+ ServicePhyInt = TRUE;
+ }
+ }
+#if INCLUDE_TBI_SUPPORT
+ if (pDevice->IgnoreTbiLinkChange == TRUE)
+ {
+ ServicePhyInt = FALSE;
+ }
+#endif
+ if (ServicePhyInt == TRUE)
+ {
+ LM_SetupPhy(pDevice);
+ }
+
+ /* Service receive and transmit interrupts. */
+ LM_ServiceRxInterrupt(pDevice);
+ LM_ServiceTxInterrupt(pDevice);
+
+ /* No spinlock for this queue since this routine is serialized. */
+ if(!QQ_Empty(&pDevice->RxPacketReceivedQ.Container))
+ {
+ /* Indicate receive packets. */
+ MM_IndicateRxPackets(pDevice);
+ /* LM_QueueRxPackets(pDevice); */
+ }
+
+ /* No spinlock for this queue since this routine is serialized. */
+ if(!QQ_Empty(&pDevice->TxPacketXmittedQ.Container))
+ {
+ MM_IndicateTxPackets(pDevice);
+ }
+
+ return LM_STATUS_SUCCESS;
+} /* LM_ServiceInterrupts */
+
+
+
+/******************************************************************************/
+/* Description: */
+/* */
+/* Return: */
+/******************************************************************************/
+LM_STATUS
+LM_MulticastAdd(
+PLM_DEVICE_BLOCK pDevice,
+PLM_UINT8 pMcAddress) {
+ PLM_UINT8 pEntry;
+ LM_UINT32 j;
+
+ pEntry = pDevice->McTable[0];
+ for(j = 0; j < pDevice->McEntryCount; j++)
+ {
+ if(IS_ETH_ADDRESS_EQUAL(pEntry, pMcAddress))
+ {
+ /* Found a match, increment the instance count. */
+ pEntry[LM_MC_INSTANCE_COUNT_INDEX] += 1;
+
+ return LM_STATUS_SUCCESS;
+ }
+
+ pEntry += LM_MC_ENTRY_SIZE;
+ }
+
+ if(pDevice->McEntryCount >= LM_MAX_MC_TABLE_SIZE)
+ {
+ return LM_STATUS_FAILURE;
+ }
+
+ pEntry = pDevice->McTable[pDevice->McEntryCount];
+
+ COPY_ETH_ADDRESS(pMcAddress, pEntry);
+ pEntry[LM_MC_INSTANCE_COUNT_INDEX] = 1;
+
+ pDevice->McEntryCount++;
+
+ LM_SetReceiveMask(pDevice, pDevice->ReceiveMask | LM_ACCEPT_MULTICAST);
+
+ return LM_STATUS_SUCCESS;
+} /* LM_MulticastAdd */
+
+
+
+/******************************************************************************/
+/* Description: */
+/* */
+/* Return: */
+/******************************************************************************/
+LM_STATUS
+LM_MulticastDel(
+PLM_DEVICE_BLOCK pDevice,
+PLM_UINT8 pMcAddress) {
+ PLM_UINT8 pEntry;
+ LM_UINT32 j;
+
+ pEntry = pDevice->McTable[0];
+ for(j = 0; j < pDevice->McEntryCount; j++)
+ {
+ if(IS_ETH_ADDRESS_EQUAL(pEntry, pMcAddress))
+ {
+ /* Found a match, decrement the instance count. */
+ pEntry[LM_MC_INSTANCE_COUNT_INDEX] -= 1;
+
+ /* No more instance left, remove the address from the table. */
+ /* Move the last entry in the table to the delete slot. */
+ if(pEntry[LM_MC_INSTANCE_COUNT_INDEX] == 0 &&
+ pDevice->McEntryCount > 1)
+ {
+
+ COPY_ETH_ADDRESS(
+ pDevice->McTable[pDevice->McEntryCount-1], pEntry);
+ pEntry[LM_MC_INSTANCE_COUNT_INDEX] =
+ pDevice->McTable[pDevice->McEntryCount-1]
+ [LM_MC_INSTANCE_COUNT_INDEX];
+ }
+ pDevice->McEntryCount--;
+
+ /* Update the receive mask if the table is empty. */
+ if(pDevice->McEntryCount == 0)
+ {
+ LM_SetReceiveMask(pDevice,
+ pDevice->ReceiveMask & ~LM_ACCEPT_MULTICAST);
+ }
+
+ return LM_STATUS_SUCCESS;
+ }
+
+ pEntry += LM_MC_ENTRY_SIZE;
+ }
+
+ return LM_STATUS_FAILURE;
+} /* LM_MulticastDel */
+
+
+
+/******************************************************************************/
+/* Description: */
+/* */
+/* Return: */
+/******************************************************************************/
+LM_STATUS
+LM_MulticastClear(
+PLM_DEVICE_BLOCK pDevice) {
+ pDevice->McEntryCount = 0;
+
+ LM_SetReceiveMask(pDevice, pDevice->ReceiveMask & ~LM_ACCEPT_MULTICAST);
+
+ return LM_STATUS_SUCCESS;
+} /* LM_MulticastClear */
+
+
+
+/******************************************************************************/
+/* Description: */
+/* */
+/* Return: */
+/******************************************************************************/
+LM_STATUS
+LM_SetMacAddress(
+ PLM_DEVICE_BLOCK pDevice,
+ PLM_UINT8 pMacAddress)
+{
+ LM_UINT32 j;
+
+ for(j = 0; j < 4; j++)
+ {
+ REG_WR(pDevice, MacCtrl.MacAddr[j].High,
+ (pMacAddress[0] << 8) | pMacAddress[1]);
+ REG_WR(pDevice, MacCtrl.MacAddr[j].Low,
+ (pMacAddress[2] << 24) | (pMacAddress[3] << 16) |
+ (pMacAddress[4] << 8) | pMacAddress[5]);
+ }
+
+ return LM_STATUS_SUCCESS;
+}
+
+
+/******************************************************************************/
+/* Description: */
+/* Sets up the default line speed, and duplex modes based on the requested */
+/* media type. */
+/* */
+/* Return: */
+/* None. */
+/******************************************************************************/
+static LM_STATUS
+LM_TranslateRequestedMediaType(
+LM_REQUESTED_MEDIA_TYPE RequestedMediaType,
+PLM_MEDIA_TYPE pMediaType,
+PLM_LINE_SPEED pLineSpeed,
+PLM_DUPLEX_MODE pDuplexMode) {
+ *pMediaType = LM_MEDIA_TYPE_AUTO;
+ *pLineSpeed = LM_LINE_SPEED_UNKNOWN;
+ *pDuplexMode = LM_DUPLEX_MODE_UNKNOWN;
+
+ /* determine media type */
+ switch(RequestedMediaType) {
+ case LM_REQUESTED_MEDIA_TYPE_BNC:
+ *pMediaType = LM_MEDIA_TYPE_BNC;
+ *pLineSpeed = LM_LINE_SPEED_10MBPS;
+ *pDuplexMode = LM_DUPLEX_MODE_HALF;
+ break;
+
+ case LM_REQUESTED_MEDIA_TYPE_UTP_AUTO:
+ *pMediaType = LM_MEDIA_TYPE_UTP;
+ break;
+
+ case LM_REQUESTED_MEDIA_TYPE_UTP_10MBPS:
+ *pMediaType = LM_MEDIA_TYPE_UTP;
+ *pLineSpeed = LM_LINE_SPEED_10MBPS;
+ *pDuplexMode = LM_DUPLEX_MODE_HALF;
+ break;
+
+ case LM_REQUESTED_MEDIA_TYPE_UTP_10MBPS_FULL_DUPLEX:
+ *pMediaType = LM_MEDIA_TYPE_UTP;
+ *pLineSpeed = LM_LINE_SPEED_10MBPS;
+ *pDuplexMode = LM_DUPLEX_MODE_FULL;
+ break;
+
+ case LM_REQUESTED_MEDIA_TYPE_UTP_100MBPS:
+ *pMediaType = LM_MEDIA_TYPE_UTP;
+ *pLineSpeed = LM_LINE_SPEED_100MBPS;
+ *pDuplexMode = LM_DUPLEX_MODE_HALF;
+ break;
+
+ case LM_REQUESTED_MEDIA_TYPE_UTP_100MBPS_FULL_DUPLEX:
+ *pMediaType = LM_MEDIA_TYPE_UTP;
+ *pLineSpeed = LM_LINE_SPEED_100MBPS;
+ *pDuplexMode = LM_DUPLEX_MODE_FULL;
+ break;
+
+ case LM_REQUESTED_MEDIA_TYPE_UTP_1000MBPS:
+ *pMediaType = LM_MEDIA_TYPE_UTP;
+ *pLineSpeed = LM_LINE_SPEED_1000MBPS;
+ *pDuplexMode = LM_DUPLEX_MODE_HALF;
+ break;
+
+ case LM_REQUESTED_MEDIA_TYPE_UTP_1000MBPS_FULL_DUPLEX:
+ *pMediaType = LM_MEDIA_TYPE_UTP;
+ *pLineSpeed = LM_LINE_SPEED_1000MBPS;
+ *pDuplexMode = LM_DUPLEX_MODE_FULL;
+ break;
+
+ case LM_REQUESTED_MEDIA_TYPE_FIBER_100MBPS:
+ *pMediaType = LM_MEDIA_TYPE_FIBER;
+ *pLineSpeed = LM_LINE_SPEED_100MBPS;
+ *pDuplexMode = LM_DUPLEX_MODE_HALF;
+ break;
+
+ case LM_REQUESTED_MEDIA_TYPE_FIBER_100MBPS_FULL_DUPLEX:
+ *pMediaType = LM_MEDIA_TYPE_FIBER;
+ *pLineSpeed = LM_LINE_SPEED_100MBPS;
+ *pDuplexMode = LM_DUPLEX_MODE_FULL;
+ break;
+
+ case LM_REQUESTED_MEDIA_TYPE_FIBER_1000MBPS:
+ *pMediaType = LM_MEDIA_TYPE_FIBER;
+ *pLineSpeed = LM_LINE_SPEED_1000MBPS;
+ *pDuplexMode = LM_DUPLEX_MODE_HALF;
+ break;
+
+ case LM_REQUESTED_MEDIA_TYPE_FIBER_1000MBPS_FULL_DUPLEX:
+ *pMediaType = LM_MEDIA_TYPE_FIBER;
+ *pLineSpeed = LM_LINE_SPEED_1000MBPS;
+ *pDuplexMode = LM_DUPLEX_MODE_FULL;
+ break;
+
+ default:
+ break;
+ } /* switch */
+
+ return LM_STATUS_SUCCESS;
+} /* LM_TranslateRequestedMediaType */
+
+/******************************************************************************/
+/* Description: */
+/* */
+/* Return: */
+/* LM_STATUS_LINK_ACTIVE */
+/* LM_STATUS_LINK_DOWN */
+/******************************************************************************/
+static LM_STATUS
+LM_InitBcm540xPhy(
+PLM_DEVICE_BLOCK pDevice)
+{
+ LM_LINE_SPEED CurrentLineSpeed;
+ LM_DUPLEX_MODE CurrentDuplexMode;
+ LM_STATUS CurrentLinkStatus;
+ LM_UINT32 Value32;
+ LM_UINT32 j;
+
+#if 1 /* jmb: bugfix -- moved here, out of code that sets initial pwr state */
+ LM_WritePhy(pDevice, BCM5401_AUX_CTRL, 0x2);
+#endif
+ if((pDevice->PhyId & PHY_ID_MASK) == PHY_BCM5401_PHY_ID)
+ {
+ LM_ReadPhy(pDevice, PHY_STATUS_REG, &Value32);
+ LM_ReadPhy(pDevice, PHY_STATUS_REG, &Value32);
+
+ if(!pDevice->InitDone)
+ {
+ Value32 = 0;
+ }
+
+ if(!(Value32 & PHY_STATUS_LINK_PASS))
+ {
+ LM_WritePhy(pDevice, BCM5401_AUX_CTRL, 0x0c20);
+
+ LM_WritePhy(pDevice, BCM540X_DSP_ADDRESS_REG, 0x0012);
+ LM_WritePhy(pDevice, BCM540X_DSP_RW_PORT, 0x1804);
+
+ LM_WritePhy(pDevice, BCM540X_DSP_ADDRESS_REG, 0x0013);
+ LM_WritePhy(pDevice, BCM540X_DSP_RW_PORT, 0x1204);
+
+ LM_WritePhy(pDevice, BCM540X_DSP_ADDRESS_REG, 0x8006);
+ LM_WritePhy(pDevice, BCM540X_DSP_RW_PORT, 0x0132);
+
+ LM_WritePhy(pDevice, BCM540X_DSP_ADDRESS_REG, 0x8006);
+ LM_WritePhy(pDevice, BCM540X_DSP_RW_PORT, 0x0232);
+
+ LM_WritePhy(pDevice, BCM540X_DSP_ADDRESS_REG, 0x201f);
+ LM_WritePhy(pDevice, BCM540X_DSP_RW_PORT, 0x0a20);
+
+ LM_ReadPhy(pDevice, PHY_STATUS_REG, &Value32);
+ for(j = 0; j < 1000; j++)
+ {
+ MM_Wait(10);
+
+ LM_ReadPhy(pDevice, PHY_STATUS_REG, &Value32);
+ if(Value32 & PHY_STATUS_LINK_PASS)
+ {
+ MM_Wait(40);
+ break;
+ }
+ }
+
+ if((pDevice->PhyId & PHY_ID_REV_MASK) == PHY_BCM5401_B0_REV)
+ {
+ if(!(Value32 & PHY_STATUS_LINK_PASS) &&
+ (pDevice->OldLineSpeed == LM_LINE_SPEED_1000MBPS))
+ {
+ LM_WritePhy(pDevice, PHY_CTRL_REG, PHY_CTRL_PHY_RESET);
+ for(j = 0; j < 100; j++)
+ {
+ MM_Wait(10);
+
+ LM_ReadPhy(pDevice, PHY_CTRL_REG, &Value32);
+ if(!(Value32 & PHY_CTRL_PHY_RESET))
+ {
+ MM_Wait(40);
+ break;
+ }
+ }
+
+ LM_WritePhy(pDevice, BCM5401_AUX_CTRL, 0x0c20);
+
+ LM_WritePhy(pDevice, BCM540X_DSP_ADDRESS_REG, 0x0012);
+ LM_WritePhy(pDevice, BCM540X_DSP_RW_PORT, 0x1804);
+
+ LM_WritePhy(pDevice, BCM540X_DSP_ADDRESS_REG, 0x0013);
+ LM_WritePhy(pDevice, BCM540X_DSP_RW_PORT, 0x1204);
+
+ LM_WritePhy(pDevice, BCM540X_DSP_ADDRESS_REG, 0x8006);
+ LM_WritePhy(pDevice, BCM540X_DSP_RW_PORT, 0x0132);
+
+ LM_WritePhy(pDevice, BCM540X_DSP_ADDRESS_REG, 0x8006);
+ LM_WritePhy(pDevice, BCM540X_DSP_RW_PORT, 0x0232);
+
+ LM_WritePhy(pDevice, BCM540X_DSP_ADDRESS_REG, 0x201f);
+ LM_WritePhy(pDevice, BCM540X_DSP_RW_PORT, 0x0a20);
+ }
+ }
+ }
+ }
+ else if(pDevice->ChipRevId == T3_CHIP_ID_5701_A0 ||
+ pDevice->ChipRevId == T3_CHIP_ID_5701_B0)
+ {
+ /* Bug: 5701 A0, B0 TX CRC workaround. */
+ LM_WritePhy(pDevice, 0x15, 0x0a75);
+ LM_WritePhy(pDevice, 0x1c, 0x8c68);
+ LM_WritePhy(pDevice, 0x1c, 0x8d68);
+ LM_WritePhy(pDevice, 0x1c, 0x8c68);
+ }
+
+ /* Acknowledge interrupts. */
+ LM_ReadPhy(pDevice, BCM540X_INT_STATUS_REG, &Value32);
+ LM_ReadPhy(pDevice, BCM540X_INT_STATUS_REG, &Value32);
+
+ /* Configure the interrupt mask. */
+ if(pDevice->PhyIntMode == T3_PHY_INT_MODE_MI_INTERRUPT)
+ {
+ LM_WritePhy(pDevice, BCM540X_INT_MASK_REG, ~BCM540X_INT_LINK_CHANGE);
+ }
+
+ /* Configure PHY led mode. */
+ if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5701 ||
+ (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700))
+ {
+ if(pDevice->LedMode == LED_MODE_THREE_LINK)
+ {
+ LM_WritePhy(pDevice, BCM540X_EXT_CTRL_REG,
+ BCM540X_EXT_CTRL_LINK3_LED_MODE);
+ }
+ else
+ {
+ LM_WritePhy(pDevice, BCM540X_EXT_CTRL_REG, 0);
+ }
+ }
+
+ CurrentLinkStatus = LM_STATUS_LINK_DOWN;
+
+ /* Get current link and duplex mode. */
+ for(j = 0; j < 100; j++)
+ {
+ LM_ReadPhy(pDevice, PHY_STATUS_REG, &Value32);
+ LM_ReadPhy(pDevice, PHY_STATUS_REG, &Value32);
+
+ if(Value32 & PHY_STATUS_LINK_PASS)
+ {
+ break;
+ }
+ MM_Wait(40);
+ }
+
+ if(Value32 & PHY_STATUS_LINK_PASS)
+ {
+
+ /* Determine the current line and duplex settings. */
+ LM_ReadPhy(pDevice, BCM540X_AUX_STATUS_REG, &Value32);
+ for(j = 0; j < 2000; j++)
+ {
+ MM_Wait(10);
+
+ LM_ReadPhy(pDevice, BCM540X_AUX_STATUS_REG, &Value32);
+ if(Value32)
+ {
+ break;
+ }
+ }
+
+ switch(Value32 & BCM540X_AUX_SPEED_MASK)
+ {
+ case BCM540X_AUX_10BASET_HD:
+ CurrentLineSpeed = LM_LINE_SPEED_10MBPS;
+ CurrentDuplexMode = LM_DUPLEX_MODE_HALF;
+ break;
+
+ case BCM540X_AUX_10BASET_FD:
+ CurrentLineSpeed = LM_LINE_SPEED_10MBPS;
+ CurrentDuplexMode = LM_DUPLEX_MODE_FULL;
+ break;
+
+ case BCM540X_AUX_100BASETX_HD:
+ CurrentLineSpeed = LM_LINE_SPEED_100MBPS;
+ CurrentDuplexMode = LM_DUPLEX_MODE_HALF;
+ break;
+
+ case BCM540X_AUX_100BASETX_FD:
+ CurrentLineSpeed = LM_LINE_SPEED_100MBPS;
+ CurrentDuplexMode = LM_DUPLEX_MODE_FULL;
+ break;
+
+ case BCM540X_AUX_100BASET_HD:
+ CurrentLineSpeed = LM_LINE_SPEED_1000MBPS;
+ CurrentDuplexMode = LM_DUPLEX_MODE_HALF;
+ break;
+
+ case BCM540X_AUX_100BASET_FD:
+ CurrentLineSpeed = LM_LINE_SPEED_1000MBPS;
+ CurrentDuplexMode = LM_DUPLEX_MODE_FULL;
+ break;
+
+ default:
+
+ CurrentLineSpeed = LM_LINE_SPEED_UNKNOWN;
+ CurrentDuplexMode = LM_DUPLEX_MODE_UNKNOWN;
+ break;
+ }
+
+ /* Make sure we are in auto-neg mode. */
+ for (j = 0; j < 200; j++)
+ {
+ LM_ReadPhy(pDevice, PHY_CTRL_REG, &Value32);
+ if(Value32 && Value32 != 0x7fff)
+ {
+ break;
+ }
+
+ if(Value32 == 0 && pDevice->RequestedMediaType ==
+ LM_REQUESTED_MEDIA_TYPE_UTP_10MBPS)
+ {
+ break;
+ }
+
+ MM_Wait(10);
+ }
+
+ /* Use the current line settings for "auto" mode. */
+ if(pDevice->RequestedMediaType == LM_REQUESTED_MEDIA_TYPE_AUTO ||
+ pDevice->RequestedMediaType == LM_REQUESTED_MEDIA_TYPE_UTP_AUTO)
+ {
+ if(Value32 & PHY_CTRL_AUTO_NEG_ENABLE)
+ {
+ CurrentLinkStatus = LM_STATUS_LINK_ACTIVE;
+
+ /* We may be exiting low power mode and the link is in */
+ /* 10mb. In this case, we need to restart autoneg. */
+ LM_ReadPhy(pDevice, BCM540X_1000BASET_CTRL_REG, &Value32);
+ pDevice->advertising1000 = Value32;
+ /* 5702FE supports 10/100Mb only. */
+ if(T3_ASIC_REV(pDevice->ChipRevId) != T3_ASIC_REV_5703 ||
+ pDevice->BondId != GRC_MISC_BD_ID_5702FE)
+ {
+ if(!(Value32 & (BCM540X_AN_AD_1000BASET_HALF |
+ BCM540X_AN_AD_1000BASET_FULL)))
+ {
+ CurrentLinkStatus = LM_STATUS_LINK_SETTING_MISMATCH;
+ }
+ }
+ }
+ else
+ {
+ CurrentLinkStatus = LM_STATUS_LINK_SETTING_MISMATCH;
+ }
+ }
+ else
+ {
+ /* Force line settings. */
+ /* Use the current setting if it matches the user's requested */
+ /* setting. */
+ LM_ReadPhy(pDevice, PHY_CTRL_REG, &Value32);
+ if((pDevice->LineSpeed == CurrentLineSpeed) &&
+ (pDevice->DuplexMode == CurrentDuplexMode))
+ {
+ if ((pDevice->DisableAutoNeg &&
+ !(Value32 & PHY_CTRL_AUTO_NEG_ENABLE)) ||
+ (!pDevice->DisableAutoNeg &&
+ (Value32 & PHY_CTRL_AUTO_NEG_ENABLE)))
+ {
+ CurrentLinkStatus = LM_STATUS_LINK_ACTIVE;
+ }
+ else
+ {
+ CurrentLinkStatus = LM_STATUS_LINK_SETTING_MISMATCH;
+ }
+ }
+ else
+ {
+ CurrentLinkStatus = LM_STATUS_LINK_SETTING_MISMATCH;
+ }
+ }
+
+ /* Save line settings. */
+ pDevice->LineSpeed = CurrentLineSpeed;
+ pDevice->DuplexMode = CurrentDuplexMode;
+ pDevice->MediaType = LM_MEDIA_TYPE_UTP;
+ }
+
+ return CurrentLinkStatus;
+} /* LM_InitBcm540xPhy */
+
+/******************************************************************************/
+/* Description: */
+/* */
+/* Return: */
+/******************************************************************************/
+LM_STATUS
+LM_SetFlowControl(
+ PLM_DEVICE_BLOCK pDevice,
+ LM_UINT32 LocalPhyAd,
+ LM_UINT32 RemotePhyAd)
+{
+ LM_FLOW_CONTROL FlowCap;
+
+ /* Resolve flow control. */
+ FlowCap = LM_FLOW_CONTROL_NONE;
+
+ /* See Table 28B-3 of 802.3ab-1999 spec. */
+ if(pDevice->FlowControlCap & LM_FLOW_CONTROL_AUTO_PAUSE)
+ {
+ if(LocalPhyAd & PHY_AN_AD_PAUSE_CAPABLE)
+ {
+ if(LocalPhyAd & PHY_AN_AD_ASYM_PAUSE)
+ {
+ if(RemotePhyAd & PHY_LINK_PARTNER_PAUSE_CAPABLE)
+ {
+ FlowCap = LM_FLOW_CONTROL_TRANSMIT_PAUSE |
+ LM_FLOW_CONTROL_RECEIVE_PAUSE;
+ }
+ else if(RemotePhyAd & PHY_LINK_PARTNER_ASYM_PAUSE)
+ {
+ FlowCap = LM_FLOW_CONTROL_RECEIVE_PAUSE;
+ }
+ }
+ else
+ {
+ if(RemotePhyAd & PHY_LINK_PARTNER_PAUSE_CAPABLE)
+ {
+ FlowCap = LM_FLOW_CONTROL_TRANSMIT_PAUSE |
+ LM_FLOW_CONTROL_RECEIVE_PAUSE;
+ }
+ }
+ }
+ else if(LocalPhyAd & PHY_AN_AD_ASYM_PAUSE)
+ {
+ if((RemotePhyAd & PHY_LINK_PARTNER_PAUSE_CAPABLE) &&
+ (RemotePhyAd & PHY_LINK_PARTNER_ASYM_PAUSE))
+ {
+ FlowCap = LM_FLOW_CONTROL_TRANSMIT_PAUSE;
+ }
+ }
+ }
+ else
+ {
+ FlowCap = pDevice->FlowControlCap;
+ }
+
+ /* Enable/disable rx PAUSE. */
+ pDevice->RxMode &= ~RX_MODE_ENABLE_FLOW_CONTROL;
+ if(FlowCap & LM_FLOW_CONTROL_RECEIVE_PAUSE &&
+ (pDevice->FlowControlCap == LM_FLOW_CONTROL_AUTO_PAUSE ||
+ pDevice->FlowControlCap & LM_FLOW_CONTROL_RECEIVE_PAUSE))
+ {
+ pDevice->FlowControl |= LM_FLOW_CONTROL_RECEIVE_PAUSE;
+ pDevice->RxMode |= RX_MODE_ENABLE_FLOW_CONTROL;
+
+ }
+ REG_WR(pDevice, MacCtrl.RxMode, pDevice->RxMode);
+
+ /* Enable/disable tx PAUSE. */
+ pDevice->TxMode &= ~TX_MODE_ENABLE_FLOW_CONTROL;
+ if(FlowCap & LM_FLOW_CONTROL_TRANSMIT_PAUSE &&
+ (pDevice->FlowControlCap == LM_FLOW_CONTROL_AUTO_PAUSE ||
+ pDevice->FlowControlCap & LM_FLOW_CONTROL_TRANSMIT_PAUSE))
+ {
+ pDevice->FlowControl |= LM_FLOW_CONTROL_TRANSMIT_PAUSE;
+ pDevice->TxMode |= TX_MODE_ENABLE_FLOW_CONTROL;
+
+ }
+ REG_WR(pDevice, MacCtrl.TxMode, pDevice->TxMode);
+
+ return LM_STATUS_SUCCESS;
+}
+
+
+#if INCLUDE_TBI_SUPPORT
+/******************************************************************************/
+/* Description: */
+/* */
+/* Return: */
+/******************************************************************************/
+STATIC LM_STATUS
+LM_InitBcm800xPhy(
+ PLM_DEVICE_BLOCK pDevice)
+{
+ LM_UINT32 Value32;
+ LM_UINT32 j;
+
+ Value32 = REG_RD(pDevice, MacCtrl.Status);
+
+ /* Reset the SERDES during init and when we have link. */
+ if(!pDevice->InitDone || Value32 & MAC_STATUS_PCS_SYNCED)
+ {
+ /* Set PLL lock range. */
+ LM_WritePhy(pDevice, 0x16, 0x8007);
+
+ /* Software reset. */
+ LM_WritePhy(pDevice, 0x00, 0x8000);
+
+ /* Wait for reset to complete. */
+ for(j = 0; j < 500; j++)
+ {
+ MM_Wait(10);
+ }
+
+ /* Config mode; seletct PMA/Ch 1 regs. */
+ LM_WritePhy(pDevice, 0x10, 0x8411);
+
+ /* Enable auto-lock and comdet, select txclk for tx. */
+ LM_WritePhy(pDevice, 0x11, 0x0a10);
+
+ LM_WritePhy(pDevice, 0x18, 0x00a0);
+ LM_WritePhy(pDevice, 0x16, 0x41ff);
+
+ /* Assert and deassert POR. */
+ LM_WritePhy(pDevice, 0x13, 0x0400);
+ MM_Wait(40);
+ LM_WritePhy(pDevice, 0x13, 0x0000);
+
+ LM_WritePhy(pDevice, 0x11, 0x0a50);
+ MM_Wait(40);
+ LM_WritePhy(pDevice, 0x11, 0x0a10);
+
+ /* Delay for signal to stabilize. */
+ for(j = 0; j < 15000; j++)
+ {
+ MM_Wait(10);
+ }
+
+ /* Deselect the channel register so we can read the PHY id later. */
+ LM_WritePhy(pDevice, 0x10, 0x8011);
+ }
+
+ return LM_STATUS_SUCCESS;
+}
+
+
+
+/******************************************************************************/
+/* Description: */
+/* */
+/* Return: */
+/******************************************************************************/
+STATIC LM_STATUS
+LM_SetupFiberPhy(
+ PLM_DEVICE_BLOCK pDevice)
+{
+ LM_STATUS CurrentLinkStatus;
+ AUTONEG_STATUS AnStatus = 0;
+ LM_UINT32 Value32;
+ LM_UINT32 Cnt;
+ LM_UINT32 j, k;
+
+ pDevice->MacMode &= ~(MAC_MODE_HALF_DUPLEX | MAC_MODE_PORT_MODE_MASK);
+
+ /* Initialize the send_config register. */
+ REG_WR(pDevice, MacCtrl.TxAutoNeg, 0);
+
+ /* Enable TBI and full duplex mode. */
+ pDevice->MacMode |= MAC_MODE_PORT_MODE_TBI;
+ REG_WR(pDevice, MacCtrl.Mode, pDevice->MacMode);
+
+ /* Initialize the BCM8002 SERDES PHY. */
+ switch(pDevice->PhyId & PHY_ID_MASK)
+ {
+ case PHY_BCM8002_PHY_ID:
+ LM_InitBcm800xPhy(pDevice);
+ break;
+
+ default:
+ break;
+ }
+
+ /* Enable link change interrupt. */
+ REG_WR(pDevice, MacCtrl.MacEvent, MAC_EVENT_ENABLE_LINK_STATE_CHANGED_ATTN);
+
+ /* Default to link down. */
+ CurrentLinkStatus = LM_STATUS_LINK_DOWN;
+
+ /* Get the link status. */
+ Value32 = REG_RD(pDevice, MacCtrl.Status);
+ if(Value32 & MAC_STATUS_PCS_SYNCED)
+ {
+ if((pDevice->RequestedMediaType == LM_REQUESTED_MEDIA_TYPE_AUTO) ||
+ (pDevice->DisableAutoNeg == FALSE))
+ {
+ /* auto-negotiation mode. */
+ /* Initialize the autoneg default capaiblities. */
+ AutonegInit(&pDevice->AnInfo);
+
+ /* Set the context pointer to point to the main device structure. */
+ pDevice->AnInfo.pContext = pDevice;
+
+ /* Setup flow control advertisement register. */
+ Value32 = GetPhyAdFlowCntrlSettings(pDevice);
+ if(Value32 & PHY_AN_AD_PAUSE_CAPABLE)
+ {
+ pDevice->AnInfo.mr_adv_sym_pause = 1;
+ }
+ else
+ {
+ pDevice->AnInfo.mr_adv_sym_pause = 0;
+ }
+
+ if(Value32 & PHY_AN_AD_ASYM_PAUSE)
+ {
+ pDevice->AnInfo.mr_adv_asym_pause = 1;
+ }
+ else
+ {
+ pDevice->AnInfo.mr_adv_asym_pause = 0;
+ }
+
+ /* Try to autoneg up to six times. */
+ if (pDevice->IgnoreTbiLinkChange)
+ {
+ Cnt = 1;
+ }
+ else
+ {
+ Cnt = 6;
+ }
+ for (j = 0; j < Cnt; j++)
+ {
+ REG_WR(pDevice, MacCtrl.TxAutoNeg, 0);
+
+ Value32 = pDevice->MacMode & ~MAC_MODE_PORT_MODE_MASK;
+ REG_WR(pDevice, MacCtrl.Mode, Value32);
+ MM_Wait(20);
+
+ REG_WR(pDevice, MacCtrl.Mode, pDevice->MacMode |
+ MAC_MODE_SEND_CONFIGS);
+
+ MM_Wait(20);
+
+ pDevice->AnInfo.State = AN_STATE_UNKNOWN;
+ pDevice->AnInfo.CurrentTime_us = 0;
+
+ REG_WR(pDevice, Grc.Timer, 0);
+ for(k = 0; (pDevice->AnInfo.CurrentTime_us < 75000) &&
+ (k < 75000); k++)
+ {
+ AnStatus = Autoneg8023z(&pDevice->AnInfo);
+
+ if((AnStatus == AUTONEG_STATUS_DONE) ||
+ (AnStatus == AUTONEG_STATUS_FAILED))
+ {
+ break;
+ }
+
+ pDevice->AnInfo.CurrentTime_us = REG_RD(pDevice, Grc.Timer);
+
+ }
+ if((AnStatus == AUTONEG_STATUS_DONE) ||
+ (AnStatus == AUTONEG_STATUS_FAILED))
+ {
+ break;
+ }
+ if (j >= 1)
+ {
+ if (!(REG_RD(pDevice, MacCtrl.Status) &
+ MAC_STATUS_PCS_SYNCED)) {
+ break;
+ }
+ }
+ }
+
+ /* Stop sending configs. */
+ MM_AnTxIdle(&pDevice->AnInfo);
+
+ /* Resolve flow control settings. */
+ if((AnStatus == AUTONEG_STATUS_DONE) &&
+ pDevice->AnInfo.mr_an_complete && pDevice->AnInfo.mr_link_ok &&
+ pDevice->AnInfo.mr_lp_adv_full_duplex)
+ {
+ LM_UINT32 RemotePhyAd;
+ LM_UINT32 LocalPhyAd;
+
+ LocalPhyAd = 0;
+ if(pDevice->AnInfo.mr_adv_sym_pause)
+ {
+ LocalPhyAd |= PHY_AN_AD_PAUSE_CAPABLE;
+ }
+
+ if(pDevice->AnInfo.mr_adv_asym_pause)
+ {
+ LocalPhyAd |= PHY_AN_AD_ASYM_PAUSE;
+ }
+
+ RemotePhyAd = 0;
+ if(pDevice->AnInfo.mr_lp_adv_sym_pause)
+ {
+ RemotePhyAd |= PHY_LINK_PARTNER_PAUSE_CAPABLE;
+ }
+
+ if(pDevice->AnInfo.mr_lp_adv_asym_pause)
+ {
+ RemotePhyAd |= PHY_LINK_PARTNER_ASYM_PAUSE;
+ }
+
+ LM_SetFlowControl(pDevice, LocalPhyAd, RemotePhyAd);
+
+ CurrentLinkStatus = LM_STATUS_LINK_ACTIVE;
+ }
+ for (j = 0; j < 30; j++)
+ {
+ MM_Wait(20);
+ REG_WR(pDevice, MacCtrl.Status, MAC_STATUS_SYNC_CHANGED |
+ MAC_STATUS_CFG_CHANGED);
+ MM_Wait(20);
+ if ((REG_RD(pDevice, MacCtrl.Status) &
+ (MAC_STATUS_SYNC_CHANGED | MAC_STATUS_CFG_CHANGED)) == 0)
+ break;
+ }
+ if (pDevice->PollTbiLink)
+ {
+ Value32 = REG_RD(pDevice, MacCtrl.Status);
+ if (Value32 & MAC_STATUS_RECEIVING_CFG)
+ {
+ pDevice->IgnoreTbiLinkChange = TRUE;
+ }
+ else
+ {
+ pDevice->IgnoreTbiLinkChange = FALSE;
+ }
+ }
+ Value32 = REG_RD(pDevice, MacCtrl.Status);
+ if (CurrentLinkStatus == LM_STATUS_LINK_DOWN &&
+ (Value32 & MAC_STATUS_PCS_SYNCED) &&
+ ((Value32 & MAC_STATUS_RECEIVING_CFG) == 0))
+ {
+ CurrentLinkStatus = LM_STATUS_LINK_ACTIVE;
+ }
+ }
+ else
+ {
+ /* We are forcing line speed. */
+ pDevice->FlowControlCap &= ~LM_FLOW_CONTROL_AUTO_PAUSE;
+ LM_SetFlowControl(pDevice, 0, 0);
+
+ CurrentLinkStatus = LM_STATUS_LINK_ACTIVE;
+ REG_WR(pDevice, MacCtrl.Mode, pDevice->MacMode |
+ MAC_MODE_SEND_CONFIGS);
+ }
+ }
+ /* Set the link polarity bit. */
+ pDevice->MacMode &= ~MAC_MODE_LINK_POLARITY;
+ REG_WR(pDevice, MacCtrl.Mode, pDevice->MacMode);
+
+ pDevice->pStatusBlkVirt->Status = STATUS_BLOCK_UPDATED |
+ (pDevice->pStatusBlkVirt->Status & ~STATUS_BLOCK_LINK_CHANGED_STATUS);
+
+ for (j = 0; j < 100; j++)
+ {
+ REG_WR(pDevice, MacCtrl.Status, MAC_STATUS_SYNC_CHANGED |
+ MAC_STATUS_CFG_CHANGED);
+ MM_Wait(5);
+ if ((REG_RD(pDevice, MacCtrl.Status) &
+ (MAC_STATUS_SYNC_CHANGED | MAC_STATUS_CFG_CHANGED)) == 0)
+ break;
+ }
+
+ Value32 = REG_RD(pDevice, MacCtrl.Status);
+ if((Value32 & MAC_STATUS_PCS_SYNCED) == 0)
+ {
+ CurrentLinkStatus = LM_STATUS_LINK_DOWN;
+ if (pDevice->DisableAutoNeg == FALSE)
+ {
+ REG_WR(pDevice, MacCtrl.Mode, pDevice->MacMode |
+ MAC_MODE_SEND_CONFIGS);
+ MM_Wait(1);
+ REG_WR(pDevice, MacCtrl.Mode, pDevice->MacMode);
+ }
+ }
+
+ /* Initialize the current link status. */
+ if(CurrentLinkStatus == LM_STATUS_LINK_ACTIVE)
+ {
+ pDevice->LineSpeed = LM_LINE_SPEED_1000MBPS;
+ pDevice->DuplexMode = LM_DUPLEX_MODE_FULL;
+ REG_WR(pDevice, MacCtrl.LedCtrl, LED_CTRL_OVERRIDE_LINK_LED |
+ LED_CTRL_1000MBPS_LED_ON);
+ }
+ else
+ {
+ pDevice->LineSpeed = LM_LINE_SPEED_UNKNOWN;
+ pDevice->DuplexMode = LM_DUPLEX_MODE_UNKNOWN;
+ REG_WR(pDevice, MacCtrl.LedCtrl, LED_CTRL_OVERRIDE_LINK_LED |
+ LED_CTRL_OVERRIDE_TRAFFIC_LED);
+ }
+
+ /* Indicate link status. */
+ if (pDevice->LinkStatus != CurrentLinkStatus) {
+ pDevice->LinkStatus = CurrentLinkStatus;
+ MM_IndicateStatus(pDevice, CurrentLinkStatus);
+ }
+
+ return LM_STATUS_SUCCESS;
+}
+#endif /* INCLUDE_TBI_SUPPORT */
+
+
+/******************************************************************************/
+/* Description: */
+/* */
+/* Return: */
+/******************************************************************************/
+LM_STATUS
+LM_SetupCopperPhy(
+ PLM_DEVICE_BLOCK pDevice)
+{
+ LM_STATUS CurrentLinkStatus;
+ LM_UINT32 Value32;
+
+ /* Assume there is not link first. */
+ CurrentLinkStatus = LM_STATUS_LINK_DOWN;
+
+ /* Disable phy link change attention. */
+ REG_WR(pDevice, MacCtrl.MacEvent, 0);
+
+ /* Clear link change attention. */
+ REG_WR(pDevice, MacCtrl.Status, MAC_STATUS_SYNC_CHANGED |
+ MAC_STATUS_CFG_CHANGED);
+
+ /* Disable auto-polling for the moment. */
+ pDevice->MiMode = 0xc0000;
+ REG_WR(pDevice, MacCtrl.MiMode, pDevice->MiMode);
+ MM_Wait(40);
+
+ /* Determine the requested line speed and duplex. */
+ pDevice->OldLineSpeed = pDevice->LineSpeed;
+ LM_TranslateRequestedMediaType(pDevice->RequestedMediaType,
+ &pDevice->MediaType, &pDevice->LineSpeed, &pDevice->DuplexMode);
+
+ /* Initialize the phy chip. */
+ switch(pDevice->PhyId & PHY_ID_MASK)
+ {
+ case PHY_BCM5400_PHY_ID:
+ case PHY_BCM5401_PHY_ID:
+ case PHY_BCM5411_PHY_ID:
+ case PHY_BCM5701_PHY_ID:
+ case PHY_BCM5703_PHY_ID:
+ case PHY_BCM5704_PHY_ID:
+ CurrentLinkStatus = LM_InitBcm540xPhy(pDevice);
+ break;
+
+ default:
+ break;
+ }
+
+ if(CurrentLinkStatus == LM_STATUS_LINK_SETTING_MISMATCH)
+ {
+ CurrentLinkStatus = LM_STATUS_LINK_DOWN;
+ }
+
+ /* Setup flow control. */
+ pDevice->FlowControl = LM_FLOW_CONTROL_NONE;
+ if(CurrentLinkStatus == LM_STATUS_LINK_ACTIVE)
+ {
+ LM_FLOW_CONTROL FlowCap; /* Flow control capability. */
+
+ FlowCap = LM_FLOW_CONTROL_NONE;
+
+ if(pDevice->DuplexMode == LM_DUPLEX_MODE_FULL)
+ {
+ if(pDevice->DisableAutoNeg == FALSE ||
+ pDevice->RequestedMediaType == LM_REQUESTED_MEDIA_TYPE_AUTO ||
+ pDevice->RequestedMediaType == LM_REQUESTED_MEDIA_TYPE_UTP_AUTO)
+ {
+ LM_UINT32 ExpectedPhyAd;
+ LM_UINT32 LocalPhyAd;
+ LM_UINT32 RemotePhyAd;
+
+ LM_ReadPhy(pDevice, PHY_AN_AD_REG, &LocalPhyAd);
+ pDevice->advertising = LocalPhyAd;
+ LocalPhyAd &= (PHY_AN_AD_ASYM_PAUSE | PHY_AN_AD_PAUSE_CAPABLE);
+
+ ExpectedPhyAd = GetPhyAdFlowCntrlSettings(pDevice);
+
+ if(LocalPhyAd != ExpectedPhyAd)
+ {
+ CurrentLinkStatus = LM_STATUS_LINK_DOWN;
+ }
+ else
+ {
+ LM_ReadPhy(pDevice, PHY_LINK_PARTNER_ABILITY_REG,
+ &RemotePhyAd);
+
+ LM_SetFlowControl(pDevice, LocalPhyAd, RemotePhyAd);
+ }
+ }
+ else
+ {
+ pDevice->FlowControlCap &= ~LM_FLOW_CONTROL_AUTO_PAUSE;
+ LM_SetFlowControl(pDevice, 0, 0);
+ }
+ }
+ }
+
+ if(CurrentLinkStatus == LM_STATUS_LINK_DOWN)
+ {
+ LM_ForceAutoNeg(pDevice, pDevice->RequestedMediaType);
+
+ /* If we force line speed, we make get link right away. */
+ LM_ReadPhy(pDevice, PHY_STATUS_REG, &Value32);
+ LM_ReadPhy(pDevice, PHY_STATUS_REG, &Value32);
+ if(Value32 & PHY_STATUS_LINK_PASS)
+ {
+ CurrentLinkStatus = LM_STATUS_LINK_ACTIVE;
+ }
+ }
+
+ /* GMII interface. */
+ pDevice->MacMode &= ~MAC_MODE_PORT_MODE_MASK;
+ if(CurrentLinkStatus == LM_STATUS_LINK_ACTIVE)
+ {
+ if(pDevice->LineSpeed == LM_LINE_SPEED_100MBPS ||
+ pDevice->LineSpeed == LM_LINE_SPEED_10MBPS)
+ {
+ pDevice->MacMode |= MAC_MODE_PORT_MODE_MII;
+ }
+ else
+ {
+ pDevice->MacMode |= MAC_MODE_PORT_MODE_GMII;
+ }
+ }
+ else {
+ pDevice->MacMode |= MAC_MODE_PORT_MODE_GMII;
+ }
+
+ /* Set the MAC to operate in the appropriate duplex mode. */
+ pDevice->MacMode &= ~MAC_MODE_HALF_DUPLEX;
+ if(pDevice->DuplexMode == LM_DUPLEX_MODE_HALF)
+ {
+ pDevice->MacMode |= MAC_MODE_HALF_DUPLEX;
+ }
+
+ /* Set the link polarity bit. */
+ pDevice->MacMode &= ~MAC_MODE_LINK_POLARITY;
+ if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700)
+ {
+ if((pDevice->LedMode == LED_MODE_LINK10) ||
+ (CurrentLinkStatus == LM_STATUS_LINK_ACTIVE &&
+ pDevice->LineSpeed == LM_LINE_SPEED_10MBPS))
+ {
+ pDevice->MacMode |= MAC_MODE_LINK_POLARITY;
+ }
+ }
+ else
+ {
+ if (CurrentLinkStatus == LM_STATUS_LINK_ACTIVE)
+ {
+ pDevice->MacMode |= MAC_MODE_LINK_POLARITY;
+ }
+
+ /* Set LED mode. */
+ if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700 ||
+ T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5701)
+ {
+ Value32 = LED_CTRL_PHY_MODE_1;
+ }
+ else
+ {
+ if(pDevice->LedMode == LED_MODE_OUTPUT)
+ {
+ Value32 = LED_CTRL_PHY_MODE_2;
+ }
+ else
+ {
+ Value32 = LED_CTRL_PHY_MODE_1;
+ }
+ }
+ REG_WR(pDevice, MacCtrl.LedCtrl, Value32);
+ }
+
+ REG_WR(pDevice, MacCtrl.Mode, pDevice->MacMode);
+
+ /* Enable auto polling. */
+ if(pDevice->PhyIntMode == T3_PHY_INT_MODE_AUTO_POLLING)
+ {
+ pDevice->MiMode |= MI_MODE_AUTO_POLLING_ENABLE;
+ REG_WR(pDevice, MacCtrl.MiMode, pDevice->MiMode);
+ }
+
+ /* Enable phy link change attention. */
+ if(pDevice->PhyIntMode == T3_PHY_INT_MODE_MI_INTERRUPT)
+ {
+ REG_WR(pDevice, MacCtrl.MacEvent, MAC_EVENT_ENABLE_MI_INTERRUPT);
+ }
+ else
+ {
+ REG_WR(pDevice, MacCtrl.MacEvent,
+ MAC_EVENT_ENABLE_LINK_STATE_CHANGED_ATTN);
+ }
+ if ((T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700) &&
+ (CurrentLinkStatus == LM_STATUS_LINK_ACTIVE) &&
+ (pDevice->LineSpeed == LM_LINE_SPEED_1000MBPS) &&
+ (((pDevice->PciState & T3_PCI_STATE_CONVENTIONAL_PCI_MODE) &&
+ (pDevice->PciState & T3_PCI_STATE_BUS_SPEED_HIGH)) ||
+ !(pDevice->PciState & T3_PCI_STATE_CONVENTIONAL_PCI_MODE)))
+ {
+ MM_Wait(120);
+ REG_WR(pDevice, MacCtrl.Status, MAC_STATUS_SYNC_CHANGED |
+ MAC_STATUS_CFG_CHANGED);
+ MEM_WR_OFFSET(pDevice, T3_FIRMWARE_MAILBOX,
+ T3_MAGIC_NUM_DISABLE_DMAW_ON_LINK_CHANGE);
+ }
+
+ /* Indicate link status. */
+ if (pDevice->LinkStatus != CurrentLinkStatus) {
+ pDevice->LinkStatus = CurrentLinkStatus;
+ MM_IndicateStatus(pDevice, CurrentLinkStatus);
+ }
+
+ return LM_STATUS_SUCCESS;
+} /* LM_SetupCopperPhy */
+
+/******************************************************************************/
+/* Description: */
+/* */
+/* Return: */
+/******************************************************************************/
+LM_STATUS
+LM_SetupPhy(
+ PLM_DEVICE_BLOCK pDevice)
+{
+ LM_STATUS LmStatus;
+ LM_UINT32 Value32;
+
+#if INCLUDE_TBI_SUPPORT
+ if(pDevice->EnableTbi)
+ {
+ LmStatus = LM_SetupFiberPhy(pDevice);
+ }
+ else
+#endif /* INCLUDE_TBI_SUPPORT */
+ {
+ LmStatus = LM_SetupCopperPhy(pDevice);
+ }
+ if (pDevice->ChipRevId == T3_CHIP_ID_5704_A0)
+ {
+ if (!(pDevice->PciState & T3_PCI_STATE_CONVENTIONAL_PCI_MODE))
+ {
+ Value32 = REG_RD(pDevice, PciCfg.PciState);
+ REG_WR(pDevice, PciCfg.PciState,
+ Value32 | T3_PCI_STATE_RETRY_SAME_DMA);
+ }
+ }
+ if ((pDevice->LineSpeed == LM_LINE_SPEED_1000MBPS) &&
+ (pDevice->DuplexMode == LM_DUPLEX_MODE_HALF))
+ {
+ REG_WR(pDevice, MacCtrl.TxLengths, 0x26ff);
+ }
+ else
+ {
+ REG_WR(pDevice, MacCtrl.TxLengths, 0x2620);
+ }
+
+ return LmStatus;
+}
+
+/******************************************************************************/
+/* Description: */
+/* */
+/* Return: */
+/******************************************************************************/
+LM_VOID
+LM_ReadPhy(
+PLM_DEVICE_BLOCK pDevice,
+LM_UINT32 PhyReg,
+PLM_UINT32 pData32) {
+ LM_UINT32 Value32;
+ LM_UINT32 j;
+
+ if(pDevice->PhyIntMode == T3_PHY_INT_MODE_AUTO_POLLING)
+ {
+ REG_WR(pDevice, MacCtrl.MiMode, pDevice->MiMode &
+ ~MI_MODE_AUTO_POLLING_ENABLE);
+ MM_Wait(40);
+ }
+
+ Value32 = (pDevice->PhyAddr << MI_COM_FIRST_PHY_ADDR_BIT) |
+ ((PhyReg & MI_COM_PHY_REG_ADDR_MASK) << MI_COM_FIRST_PHY_REG_ADDR_BIT) |
+ MI_COM_CMD_READ | MI_COM_START;
+
+ REG_WR(pDevice, MacCtrl.MiCom, Value32);
+
+ for(j = 0; j < 20; j++)
+ {
+ MM_Wait(25);
+
+ Value32 = REG_RD(pDevice, MacCtrl.MiCom);
+
+ if(!(Value32 & MI_COM_BUSY))
+ {
+ MM_Wait(5);
+ Value32 = REG_RD(pDevice, MacCtrl.MiCom);
+ Value32 &= MI_COM_PHY_DATA_MASK;
+ break;
+ }
+ }
+
+ if(Value32 & MI_COM_BUSY)
+ {
+ Value32 = 0;
+ }
+
+ *pData32 = Value32;
+
+ if(pDevice->PhyIntMode == T3_PHY_INT_MODE_AUTO_POLLING)
+ {
+ REG_WR(pDevice, MacCtrl.MiMode, pDevice->MiMode);
+ MM_Wait(40);
+ }
+} /* LM_ReadPhy */
+
+
+
+/******************************************************************************/
+/* Description: */
+/* */
+/* Return: */
+/******************************************************************************/
+LM_VOID
+LM_WritePhy(
+PLM_DEVICE_BLOCK pDevice,
+LM_UINT32 PhyReg,
+LM_UINT32 Data32) {
+ LM_UINT32 Value32;
+ LM_UINT32 j;
+
+ if(pDevice->PhyIntMode == T3_PHY_INT_MODE_AUTO_POLLING)
+ {
+ REG_WR(pDevice, MacCtrl.MiMode, pDevice->MiMode &
+ ~MI_MODE_AUTO_POLLING_ENABLE);
+ MM_Wait(40);
+ }
+
+ Value32 = (pDevice->PhyAddr << MI_COM_FIRST_PHY_ADDR_BIT) |
+ ((PhyReg & MI_COM_PHY_REG_ADDR_MASK) << MI_COM_FIRST_PHY_REG_ADDR_BIT) |
+ (Data32 & MI_COM_PHY_DATA_MASK) | MI_COM_CMD_WRITE | MI_COM_START;
+
+ REG_WR(pDevice, MacCtrl.MiCom, Value32);
+
+ for(j = 0; j < 20; j++)
+ {
+ MM_Wait(25);
+
+ Value32 = REG_RD(pDevice, MacCtrl.MiCom);
+
+ if(!(Value32 & MI_COM_BUSY))
+ {
+ MM_Wait(5);
+ break;
+ }
+ }
+
+ if(pDevice->PhyIntMode == T3_PHY_INT_MODE_AUTO_POLLING)
+ {
+ REG_WR(pDevice, MacCtrl.MiMode, pDevice->MiMode);
+ MM_Wait(40);
+ }
+} /* LM_WritePhy */
+
+
+/******************************************************************************/
+/* Description: */
+/* */
+/* Return: */
+/******************************************************************************/
+LM_STATUS
+LM_SetPowerState(
+PLM_DEVICE_BLOCK pDevice,
+LM_POWER_STATE PowerLevel) {
+ LM_UINT32 PmeSupport;
+ LM_UINT32 Value32;
+ LM_UINT32 PmCtrl;
+
+ /* make sureindirect accesses are enabled*/
+ MM_WriteConfig32(pDevice, T3_PCI_MISC_HOST_CTRL_REG, pDevice->MiscHostCtrl);
+
+ /* Clear the PME_ASSERT bit and the power state bits. Also enable */
+ /* the PME bit. */
+ MM_ReadConfig32(pDevice, T3_PCI_PM_STATUS_CTRL_REG, &PmCtrl);
+
+ PmCtrl |= T3_PM_PME_ASSERTED;
+ PmCtrl &= ~T3_PM_POWER_STATE_MASK;
+
+ /* Set the appropriate power state. */
+ if(PowerLevel == LM_POWER_STATE_D0)
+ {
+
+ /* Bring the card out of low power mode. */
+ PmCtrl |= T3_PM_POWER_STATE_D0;
+ MM_WriteConfig32(pDevice, T3_PCI_PM_STATUS_CTRL_REG, PmCtrl);
+
+ REG_WR(pDevice, Grc.LocalCtrl, pDevice->GrcLocalCtrl);
+ MM_Wait (40);
+#if 0 /* Bugfix by jmb...can't call WritePhy here because pDevice not fully initialized */
+ LM_WritePhy(pDevice, BCM5401_AUX_CTRL, 0x02);
+#endif
+
+ return LM_STATUS_SUCCESS;
+ }
+ else if(PowerLevel == LM_POWER_STATE_D1)
+ {
+ PmCtrl |= T3_PM_POWER_STATE_D1;
+ }
+ else if(PowerLevel == LM_POWER_STATE_D2)
+ {
+ PmCtrl |= T3_PM_POWER_STATE_D2;
+ }
+ else if(PowerLevel == LM_POWER_STATE_D3)
+ {
+ PmCtrl |= T3_PM_POWER_STATE_D3;
+ }
+ else
+ {
+ return LM_STATUS_FAILURE;
+ }
+ PmCtrl |= T3_PM_PME_ENABLE;
+
+ /* Mask out all interrupts so LM_SetupPhy won't be called while we are */
+ /* setting new line speed. */
+ Value32 = REG_RD(pDevice, PciCfg.MiscHostCtrl);
+ REG_WR(pDevice, PciCfg.MiscHostCtrl, Value32 | MISC_HOST_CTRL_MASK_PCI_INT);
+
+ if(!pDevice->RestoreOnWakeUp)
+ {
+ pDevice->RestoreOnWakeUp = TRUE;
+ pDevice->WakeUpDisableAutoNeg = pDevice->DisableAutoNeg;
+ pDevice->WakeUpRequestedMediaType = pDevice->RequestedMediaType;
+ }
+
+ /* Force auto-negotiation to 10 line speed. */
+ pDevice->DisableAutoNeg = FALSE;
+ pDevice->RequestedMediaType = LM_REQUESTED_MEDIA_TYPE_UTP_10MBPS;
+ LM_SetupPhy(pDevice);
+
+ /* Put the driver in the initial state, and go through the power down */
+ /* sequence. */
+ LM_Halt(pDevice);
+
+ MM_ReadConfig32(pDevice, T3_PCI_PM_CAP_REG, &PmeSupport);
+
+ if (pDevice->WakeUpModeCap != LM_WAKE_UP_MODE_NONE)
+ {
+
+ /* Enable WOL. */
+ LM_WritePhy(pDevice, BCM5401_AUX_CTRL, 0x5a);
+ MM_Wait(40);
+
+ /* Set LED mode. */
+ if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700 ||
+ T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5701)
+ {
+ Value32 = LED_CTRL_PHY_MODE_1;
+ }
+ else
+ {
+ if(pDevice->LedMode == LED_MODE_OUTPUT)
+ {
+ Value32 = LED_CTRL_PHY_MODE_2;
+ }
+ else
+ {
+ Value32 = LED_CTRL_PHY_MODE_1;
+ }
+ }
+
+ Value32 = MAC_MODE_PORT_MODE_MII;
+ if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700)
+ {
+ if(pDevice->LedMode == LED_MODE_LINK10 ||
+ pDevice->WolSpeed == WOL_SPEED_10MB)
+ {
+ Value32 |= MAC_MODE_LINK_POLARITY;
+ }
+ }
+ else
+ {
+ Value32 |= MAC_MODE_LINK_POLARITY;
+ }
+ REG_WR(pDevice, MacCtrl.Mode, Value32);
+ MM_Wait(40); MM_Wait(40); MM_Wait(40);
+
+ /* Always enable magic packet wake-up if we have vaux. */
+ if((PmeSupport & T3_PCI_PM_CAP_PME_D3COLD) &&
+ (pDevice->WakeUpModeCap & LM_WAKE_UP_MODE_MAGIC_PACKET))
+ {
+ Value32 |= MAC_MODE_DETECT_MAGIC_PACKET_ENABLE;
+ }
+
+ REG_WR(pDevice, MacCtrl.Mode, Value32);
+
+ /* Enable the receiver. */
+ REG_WR(pDevice, MacCtrl.RxMode, RX_MODE_ENABLE);
+ }
+
+ /* Disable tx/rx clocks, and seletect an alternate clock. */
+ if(pDevice->WolSpeed == WOL_SPEED_100MB)
+ {
+ if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700 ||
+ T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5701)
+ {
+ Value32 = T3_PCI_DISABLE_RX_CLOCK | T3_PCI_DISABLE_TX_CLOCK |
+ T3_PCI_SELECT_ALTERNATE_CLOCK;
+ }
+ else
+ {
+ Value32 = T3_PCI_SELECT_ALTERNATE_CLOCK;
+ }
+ REG_WR(pDevice, PciCfg.ClockCtrl, Value32);
+
+ MM_Wait(40);
+
+ if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700 ||
+ T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5701)
+ {
+ Value32 = T3_PCI_DISABLE_RX_CLOCK | T3_PCI_DISABLE_TX_CLOCK |
+ T3_PCI_SELECT_ALTERNATE_CLOCK | T3_PCI_44MHZ_CORE_CLOCK;
+ }
+ else
+ {
+ Value32 = T3_PCI_SELECT_ALTERNATE_CLOCK |
+ T3_PCI_44MHZ_CORE_CLOCK;
+ }
+
+ REG_WR(pDevice, PciCfg.ClockCtrl, Value32);
+
+ MM_Wait(40);
+
+ if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700 ||
+ T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5701)
+ {
+ Value32 = T3_PCI_DISABLE_RX_CLOCK | T3_PCI_DISABLE_TX_CLOCK |
+ T3_PCI_44MHZ_CORE_CLOCK;
+ }
+ else
+ {
+ Value32 = T3_PCI_44MHZ_CORE_CLOCK;
+ }
+
+ REG_WR(pDevice, PciCfg.ClockCtrl, Value32);
+ }
+ else
+ {
+ if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700 ||
+ T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5701)
+ {
+ Value32 = T3_PCI_DISABLE_RX_CLOCK | T3_PCI_DISABLE_TX_CLOCK |
+ T3_PCI_SELECT_ALTERNATE_CLOCK |
+ T3_PCI_POWER_DOWN_PCI_PLL133;
+ }
+ else
+ {
+ Value32 = T3_PCI_SELECT_ALTERNATE_CLOCK |
+ T3_PCI_POWER_DOWN_PCI_PLL133;
+ }
+
+ REG_WR(pDevice, PciCfg.ClockCtrl, Value32);
+ }
+
+ MM_Wait(40);
+
+ if(!pDevice->EepromWp && (pDevice->WakeUpModeCap != LM_WAKE_UP_MODE_NONE))
+ {
+ /* Switch adapter to auxilliary power. */
+ if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700 ||
+ T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5701)
+ {
+ /* GPIO0 = 1, GPIO1 = 1, GPIO2 = 0. */
+ REG_WR(pDevice, Grc.LocalCtrl, pDevice->GrcLocalCtrl |
+ GRC_MISC_LOCAL_CTRL_GPIO_OE0 |
+ GRC_MISC_LOCAL_CTRL_GPIO_OE1 |
+ GRC_MISC_LOCAL_CTRL_GPIO_OE2 |
+ GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT0 |
+ GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT1);
+ MM_Wait(40);
+ }
+ else
+ {
+ /* GPIO0 = 0, GPIO1 = 1, GPIO2 = 1. */
+ REG_WR(pDevice, Grc.LocalCtrl, pDevice->GrcLocalCtrl |
+ GRC_MISC_LOCAL_CTRL_GPIO_OE0 |
+ GRC_MISC_LOCAL_CTRL_GPIO_OE1 |
+ GRC_MISC_LOCAL_CTRL_GPIO_OE2 |
+ GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT1 |
+ GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT2);
+ MM_Wait(40);
+
+ /* GPIO0 = 1, GPIO1 = 1, GPIO2 = 1. */
+ REG_WR(pDevice, Grc.LocalCtrl, pDevice->GrcLocalCtrl |
+ GRC_MISC_LOCAL_CTRL_GPIO_OE0 |
+ GRC_MISC_LOCAL_CTRL_GPIO_OE1 |
+ GRC_MISC_LOCAL_CTRL_GPIO_OE2 |
+ GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT0 |
+ GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT1 |
+ GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT2);
+ MM_Wait(40);
+
+ /* GPIO0 = 1, GPIO1 = 1, GPIO2 = 0. */
+ REG_WR(pDevice, Grc.LocalCtrl, pDevice->GrcLocalCtrl |
+ GRC_MISC_LOCAL_CTRL_GPIO_OE0 |
+ GRC_MISC_LOCAL_CTRL_GPIO_OE1 |
+ GRC_MISC_LOCAL_CTRL_GPIO_OE2 |
+ GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT0 |
+ GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT1);
+ MM_Wait(40);
+ }
+ }
+
+ /* Set the phy to low power mode. */
+ /* Put the the hardware in low power mode. */
+ MM_WriteConfig32(pDevice, T3_PCI_PM_STATUS_CTRL_REG, PmCtrl);
+
+ return LM_STATUS_SUCCESS;
+} /* LM_SetPowerState */
+
+
+
+/******************************************************************************/
+/* Description: */
+/* */
+/* Return: */
+/******************************************************************************/
+static LM_UINT32
+GetPhyAdFlowCntrlSettings(
+ PLM_DEVICE_BLOCK pDevice)
+{
+ LM_UINT32 Value32;
+
+ Value32 = 0;
+
+ /* Auto negotiation flow control only when autonegotiation is enabled. */
+ if(pDevice->DisableAutoNeg == FALSE ||
+ pDevice->RequestedMediaType == LM_REQUESTED_MEDIA_TYPE_AUTO ||
+ pDevice->RequestedMediaType == LM_REQUESTED_MEDIA_TYPE_UTP_AUTO)
+ {
+ /* Please refer to Table 28B-3 of the 802.3ab-1999 spec. */
+ if((pDevice->FlowControlCap == LM_FLOW_CONTROL_AUTO_PAUSE) ||
+ ((pDevice->FlowControlCap & LM_FLOW_CONTROL_RECEIVE_PAUSE) &&
+ (pDevice->FlowControlCap & LM_FLOW_CONTROL_TRANSMIT_PAUSE)))
+ {
+ Value32 |= PHY_AN_AD_PAUSE_CAPABLE;
+ }
+ else if(pDevice->FlowControlCap & LM_FLOW_CONTROL_TRANSMIT_PAUSE)
+ {
+ Value32 |= PHY_AN_AD_ASYM_PAUSE;
+ }
+ else if(pDevice->FlowControlCap & LM_FLOW_CONTROL_RECEIVE_PAUSE)
+ {
+ Value32 |= PHY_AN_AD_PAUSE_CAPABLE | PHY_AN_AD_ASYM_PAUSE;
+ }
+ }
+
+ return Value32;
+}
+
+
+
+/******************************************************************************/
+/* Description: */
+/* */
+/* Return: */
+/* LM_STATUS_FAILURE */
+/* LM_STATUS_SUCCESS */
+/* */
+/******************************************************************************/
+static LM_STATUS
+LM_ForceAutoNegBcm540xPhy(
+PLM_DEVICE_BLOCK pDevice,
+LM_REQUESTED_MEDIA_TYPE RequestedMediaType)
+{
+ LM_MEDIA_TYPE MediaType;
+ LM_LINE_SPEED LineSpeed;
+ LM_DUPLEX_MODE DuplexMode;
+ LM_UINT32 NewPhyCtrl;
+ LM_UINT32 Value32;
+ LM_UINT32 Cnt;
+
+ /* Get the interface type, line speed, and duplex mode. */
+ LM_TranslateRequestedMediaType(RequestedMediaType, &MediaType, &LineSpeed,
+ &DuplexMode);
+
+ if (pDevice->RestoreOnWakeUp)
+ {
+ LM_WritePhy(pDevice, BCM540X_1000BASET_CTRL_REG, 0);
+ pDevice->advertising1000 = 0;
+ Value32 = PHY_AN_AD_10BASET_FULL | PHY_AN_AD_10BASET_HALF;
+ if (pDevice->WolSpeed == WOL_SPEED_100MB)
+ {
+ Value32 |= PHY_AN_AD_100BASETX_FULL | PHY_AN_AD_100BASETX_HALF;
+ }
+ Value32 |= PHY_AN_AD_PROTOCOL_802_3_CSMA_CD;
+ Value32 |= GetPhyAdFlowCntrlSettings(pDevice);
+ LM_WritePhy(pDevice, PHY_AN_AD_REG, Value32);
+ pDevice->advertising = Value32;
+ }
+ /* Setup the auto-negotiation advertisement register. */
+ else if(LineSpeed == LM_LINE_SPEED_UNKNOWN)
+ {
+ /* Setup the 10/100 Mbps auto-negotiation advertisement register. */
+ Value32 = PHY_AN_AD_PROTOCOL_802_3_CSMA_CD |
+ PHY_AN_AD_10BASET_HALF | PHY_AN_AD_10BASET_FULL |
+ PHY_AN_AD_100BASETX_FULL | PHY_AN_AD_100BASETX_HALF;
+ Value32 |= GetPhyAdFlowCntrlSettings(pDevice);
+
+ LM_WritePhy(pDevice, PHY_AN_AD_REG, Value32);
+ pDevice->advertising = Value32;
+
+ /* Advertise 1000Mbps */
+ Value32 = BCM540X_AN_AD_1000BASET_HALF | BCM540X_AN_AD_1000BASET_FULL;
+
+#if INCLUDE_5701_AX_FIX
+ /* Bug: workaround for CRC error in gigabit mode when we are in */
+ /* slave mode. This will force the PHY to operate in */
+ /* master mode. */
+ if(pDevice->ChipRevId == T3_CHIP_ID_5701_A0 ||
+ pDevice->ChipRevId == T3_CHIP_ID_5701_B0)
+ {
+ Value32 |= BCM540X_CONFIG_AS_MASTER |
+ BCM540X_ENABLE_CONFIG_AS_MASTER;
+ }
+#endif
+
+ LM_WritePhy(pDevice, BCM540X_1000BASET_CTRL_REG, Value32);
+ pDevice->advertising1000 = Value32;
+ }
+ else
+ {
+ if(LineSpeed == LM_LINE_SPEED_1000MBPS)
+ {
+ Value32 = PHY_AN_AD_PROTOCOL_802_3_CSMA_CD;
+ Value32 |= GetPhyAdFlowCntrlSettings(pDevice);
+
+ LM_WritePhy(pDevice, PHY_AN_AD_REG, Value32);
+ pDevice->advertising = Value32;
+
+ if(DuplexMode != LM_DUPLEX_MODE_FULL)
+ {
+ Value32 = BCM540X_AN_AD_1000BASET_HALF;
+ }
+ else
+ {
+ Value32 = BCM540X_AN_AD_1000BASET_FULL;
+ }
+
+ LM_WritePhy(pDevice, BCM540X_1000BASET_CTRL_REG, Value32);
+ pDevice->advertising1000 = Value32;
+ }
+ else if(LineSpeed == LM_LINE_SPEED_100MBPS)
+ {
+ LM_WritePhy(pDevice, BCM540X_1000BASET_CTRL_REG, 0);
+ pDevice->advertising1000 = 0;
+
+ if(DuplexMode != LM_DUPLEX_MODE_FULL)
+ {
+ Value32 = PHY_AN_AD_100BASETX_HALF;
+ }
+ else
+ {
+ Value32 = PHY_AN_AD_100BASETX_FULL;
+ }
+
+ Value32 |= PHY_AN_AD_PROTOCOL_802_3_CSMA_CD;
+ Value32 |= GetPhyAdFlowCntrlSettings(pDevice);
+
+ LM_WritePhy(pDevice, PHY_AN_AD_REG, Value32);
+ pDevice->advertising = Value32;
+ }
+ else if(LineSpeed == LM_LINE_SPEED_10MBPS)
+ {
+ LM_WritePhy(pDevice, BCM540X_1000BASET_CTRL_REG, 0);
+ pDevice->advertising1000 = 0;
+
+ if(DuplexMode != LM_DUPLEX_MODE_FULL)
+ {
+ Value32 = PHY_AN_AD_10BASET_HALF;
+ }
+ else
+ {
+ Value32 = PHY_AN_AD_10BASET_FULL;
+ }
+
+ Value32 |= PHY_AN_AD_PROTOCOL_802_3_CSMA_CD;
+ Value32 |= GetPhyAdFlowCntrlSettings(pDevice);
+
+ LM_WritePhy(pDevice, PHY_AN_AD_REG, Value32);
+ pDevice->advertising = Value32;
+ }
+ }
+
+ /* Force line speed if auto-negotiation is disabled. */
+ if(pDevice->DisableAutoNeg && LineSpeed != LM_LINE_SPEED_UNKNOWN)
+ {
+ /* This code path is executed only when there is link. */
+ pDevice->MediaType = MediaType;
+ pDevice->LineSpeed = LineSpeed;
+ pDevice->DuplexMode = DuplexMode;
+
+ /* Force line seepd. */
+ NewPhyCtrl = 0;
+ switch(LineSpeed)
+ {
+ case LM_LINE_SPEED_10MBPS:
+ NewPhyCtrl |= PHY_CTRL_SPEED_SELECT_10MBPS;
+ break;
+ case LM_LINE_SPEED_100MBPS:
+ NewPhyCtrl |= PHY_CTRL_SPEED_SELECT_100MBPS;
+ break;
+ case LM_LINE_SPEED_1000MBPS:
+ NewPhyCtrl |= PHY_CTRL_SPEED_SELECT_1000MBPS;
+ break;
+ default:
+ NewPhyCtrl |= PHY_CTRL_SPEED_SELECT_1000MBPS;
+ break;
+ }
+
+ if(DuplexMode == LM_DUPLEX_MODE_FULL)
+ {
+ NewPhyCtrl |= PHY_CTRL_FULL_DUPLEX_MODE;
+ }
+
+ /* Don't do anything if the PHY_CTRL is already what we wanted. */
+ LM_ReadPhy(pDevice, PHY_CTRL_REG, &Value32);
+ if(Value32 != NewPhyCtrl)
+ {
+ /* Temporary bring the link down before forcing line speed. */
+ LM_WritePhy(pDevice, PHY_CTRL_REG, PHY_CTRL_LOOPBACK_MODE);
+
+ /* Wait for link to go down. */
+ for(Cnt = 0; Cnt < 15000; Cnt++)
+ {
+ MM_Wait(10);
+
+ LM_ReadPhy(pDevice, PHY_STATUS_REG, &Value32);
+ LM_ReadPhy(pDevice, PHY_STATUS_REG, &Value32);
+
+ if(!(Value32 & PHY_STATUS_LINK_PASS))
+ {
+ MM_Wait(40);
+ break;
+ }
+ }
+
+ LM_WritePhy(pDevice, PHY_CTRL_REG, NewPhyCtrl);
+ MM_Wait(40);
+ }
+ }
+ else
+ {
+ LM_WritePhy(pDevice, PHY_CTRL_REG, PHY_CTRL_AUTO_NEG_ENABLE |
+ PHY_CTRL_RESTART_AUTO_NEG);
+ }
+
+ return LM_STATUS_SUCCESS;
+} /* LM_ForceAutoNegBcm540xPhy */
+
+
+
+/******************************************************************************/
+/* Description: */
+/* */
+/* Return: */
+/******************************************************************************/
+static LM_STATUS
+LM_ForceAutoNeg(
+PLM_DEVICE_BLOCK pDevice,
+LM_REQUESTED_MEDIA_TYPE RequestedMediaType)
+{
+ LM_STATUS LmStatus;
+
+ /* Initialize the phy chip. */
+ switch(pDevice->PhyId & PHY_ID_MASK)
+ {
+ case PHY_BCM5400_PHY_ID:
+ case PHY_BCM5401_PHY_ID:
+ case PHY_BCM5411_PHY_ID:
+ case PHY_BCM5701_PHY_ID:
+ case PHY_BCM5703_PHY_ID:
+ case PHY_BCM5704_PHY_ID:
+ LmStatus = LM_ForceAutoNegBcm540xPhy(pDevice, RequestedMediaType);
+ break;
+
+ default:
+ LmStatus = LM_STATUS_FAILURE;
+ break;
+ }
+
+ return LmStatus;
+} /* LM_ForceAutoNeg */
+
+/******************************************************************************/
+/* Description: */
+/* */
+/* Return: */
+/******************************************************************************/
+LM_STATUS LM_LoadFirmware(PLM_DEVICE_BLOCK pDevice,
+ PT3_FWIMG_INFO pFwImg,
+ LM_UINT32 LoadCpu,
+ LM_UINT32 StartCpu)
+{
+ LM_UINT32 i;
+ LM_UINT32 address;
+
+ if (LoadCpu & T3_RX_CPU_ID)
+ {
+ if (LM_HaltCpu(pDevice,T3_RX_CPU_ID) != LM_STATUS_SUCCESS)
+ {
+ return LM_STATUS_FAILURE;
+ }
+
+ /* First of all clear scrach pad memory */
+ for (i = 0; i < T3_RX_CPU_SPAD_SIZE; i+=4)
+ {
+ LM_RegWrInd(pDevice,T3_RX_CPU_SPAD_ADDR+i,0);
+ }
+
+ /* Copy code first */
+ address = T3_RX_CPU_SPAD_ADDR + (pFwImg->Text.Offset & 0xffff);
+ for (i = 0; i <= pFwImg->Text.Length; i+=4)
+ {
+ LM_RegWrInd(pDevice,address+i,
+ ((LM_UINT32 *)pFwImg->Text.Buffer)[i/4]);
+ }
+
+ address = T3_RX_CPU_SPAD_ADDR + (pFwImg->ROnlyData.Offset & 0xffff);
+ for (i = 0; i <= pFwImg->ROnlyData.Length; i+=4)
+ {
+ LM_RegWrInd(pDevice,address+i,
+ ((LM_UINT32 *)pFwImg->ROnlyData.Buffer)[i/4]);
+ }
+
+ address = T3_RX_CPU_SPAD_ADDR + (pFwImg->Data.Offset & 0xffff);
+ for (i= 0; i <= pFwImg->Data.Length; i+=4)
+ {
+ LM_RegWrInd(pDevice,address+i,
+ ((LM_UINT32 *)pFwImg->Data.Buffer)[i/4]);
+ }
+ }
+
+ if (LoadCpu & T3_TX_CPU_ID)
+ {
+ if (LM_HaltCpu(pDevice,T3_TX_CPU_ID) != LM_STATUS_SUCCESS)
+ {
+ return LM_STATUS_FAILURE;
+ }
+
+ /* First of all clear scrach pad memory */
+ for (i = 0; i < T3_TX_CPU_SPAD_SIZE; i+=4)
+ {
+ LM_RegWrInd(pDevice,T3_TX_CPU_SPAD_ADDR+i,0);
+ }
+
+ /* Copy code first */
+ address = T3_TX_CPU_SPAD_ADDR + (pFwImg->Text.Offset & 0xffff);
+ for (i= 0; i <= pFwImg->Text.Length; i+=4)
+ {
+ LM_RegWrInd(pDevice,address+i,
+ ((LM_UINT32 *)pFwImg->Text.Buffer)[i/4]);
+ }
+
+ address = T3_TX_CPU_SPAD_ADDR + (pFwImg->ROnlyData.Offset & 0xffff);
+ for (i= 0; i <= pFwImg->ROnlyData.Length; i+=4)
+ {
+ LM_RegWrInd(pDevice,address+i,
+ ((LM_UINT32 *)pFwImg->ROnlyData.Buffer)[i/4]);
+ }
+
+ address = T3_TX_CPU_SPAD_ADDR + (pFwImg->Data.Offset & 0xffff);
+ for (i= 0; i <= pFwImg->Data.Length; i+=4)
+ {
+ LM_RegWrInd(pDevice,address+i,
+ ((LM_UINT32 *)pFwImg->Data.Buffer)[i/4]);
+ }
+ }
+
+ if (StartCpu & T3_RX_CPU_ID)
+ {
+ /* Start Rx CPU */
+ REG_WR(pDevice,rxCpu.reg.state, 0xffffffff);
+ REG_WR(pDevice,rxCpu.reg.PC,pFwImg->StartAddress);
+ for (i = 0 ; i < 5; i++)
+ {
+ if (pFwImg->StartAddress == REG_RD(pDevice,rxCpu.reg.PC))
+ break;
+
+ REG_WR(pDevice,rxCpu.reg.state, 0xffffffff);
+ REG_WR(pDevice,rxCpu.reg.mode,CPU_MODE_HALT);
+ REG_WR(pDevice,rxCpu.reg.PC,pFwImg->StartAddress);
+ MM_Wait(1000);
+ }
+
+ REG_WR(pDevice,rxCpu.reg.state, 0xffffffff);
+ REG_WR(pDevice,rxCpu.reg.mode, 0);
+ }
+
+ if (StartCpu & T3_TX_CPU_ID)
+ {
+ /* Start Tx CPU */
+ REG_WR(pDevice,txCpu.reg.state, 0xffffffff);
+ REG_WR(pDevice,txCpu.reg.PC,pFwImg->StartAddress);
+ for (i = 0 ; i < 5; i++)
+ {
+ if (pFwImg->StartAddress == REG_RD(pDevice,txCpu.reg.PC))
+ break;
+
+ REG_WR(pDevice,txCpu.reg.state, 0xffffffff);
+ REG_WR(pDevice,txCpu.reg.mode,CPU_MODE_HALT);
+ REG_WR(pDevice,txCpu.reg.PC,pFwImg->StartAddress);
+ MM_Wait(1000);
+ }
+
+ REG_WR(pDevice,txCpu.reg.state, 0xffffffff);
+ REG_WR(pDevice,txCpu.reg.mode, 0);
+ }
+
+ return LM_STATUS_SUCCESS;
+}
+
+STATIC LM_STATUS LM_HaltCpu(PLM_DEVICE_BLOCK pDevice,LM_UINT32 cpu_number)
+{
+ LM_UINT32 i;
+
+ if (cpu_number == T3_RX_CPU_ID)
+ {
+ for (i = 0 ; i < 10000; i++)
+ {
+ REG_WR(pDevice,rxCpu.reg.state, 0xffffffff);
+ REG_WR(pDevice,rxCpu.reg.mode,CPU_MODE_HALT);
+
+ if (REG_RD(pDevice,rxCpu.reg.mode) & CPU_MODE_HALT)
+ break;
+ }
+
+ REG_WR(pDevice,rxCpu.reg.state, 0xffffffff);
+ REG_WR(pDevice,rxCpu.reg.mode,CPU_MODE_HALT);
+ MM_Wait(10);
+ }
+ else
+ {
+ for (i = 0 ; i < 10000; i++)
+ {
+ REG_WR(pDevice,txCpu.reg.state, 0xffffffff);
+ REG_WR(pDevice,txCpu.reg.mode,CPU_MODE_HALT);
+
+ if (REG_RD(pDevice,txCpu.reg.mode) & CPU_MODE_HALT)
+ break;
+ }
+ }
+
+ return (( i == 10000) ? LM_STATUS_FAILURE : LM_STATUS_SUCCESS);
+}
+
+
+int
+LM_BlinkLED(PLM_DEVICE_BLOCK pDevice, LM_UINT32 BlinkDurationSec)
+{
+ LM_UINT32 Oldcfg;
+ int j;
+ int ret = 0;
+
+ if(BlinkDurationSec == 0)
+ {
+ return 0;
+ }
+ if(BlinkDurationSec > 120)
+ {
+ BlinkDurationSec = 120;
+ }
+
+ Oldcfg = REG_RD(pDevice, MacCtrl.LedCtrl);
+ for(j = 0; j < BlinkDurationSec * 2; j++)
+ {
+ if(j % 2)
+ {
+ /* Turn on the LEDs. */
+ REG_WR(pDevice, MacCtrl.LedCtrl,
+ LED_CTRL_OVERRIDE_LINK_LED |
+ LED_CTRL_1000MBPS_LED_ON |
+ LED_CTRL_100MBPS_LED_ON |
+ LED_CTRL_10MBPS_LED_ON |
+ LED_CTRL_OVERRIDE_TRAFFIC_LED |
+ LED_CTRL_BLINK_TRAFFIC_LED |
+ LED_CTRL_TRAFFIC_LED);
+ }
+ else
+ {
+ /* Turn off the LEDs. */
+ REG_WR(pDevice, MacCtrl.LedCtrl,
+ LED_CTRL_OVERRIDE_LINK_LED |
+ LED_CTRL_OVERRIDE_TRAFFIC_LED);
+ }
+
+#ifndef EMBEDDED
+ current->state = TASK_INTERRUPTIBLE;
+ if (schedule_timeout(HZ/2) != 0) {
+ ret = -EINTR;
+ break;
+ }
+#else
+ udelay(100000); /* 1s sleep */
+#endif
+ }
+ REG_WR(pDevice, MacCtrl.LedCtrl, Oldcfg);
+ return ret;
+}
+
+int t3_do_dma(PLM_DEVICE_BLOCK pDevice,
+ LM_PHYSICAL_ADDRESS host_addr_phy, int length,
+ int dma_read)
+{
+ T3_DMA_DESC dma_desc;
+ int i;
+ LM_UINT32 dma_desc_addr;
+ LM_UINT32 value32;
+
+ REG_WR(pDevice, BufMgr.Mode, 0);
+ REG_WR(pDevice, Ftq.Reset, 0);
+
+ dma_desc.host_addr.High = host_addr_phy.High;
+ dma_desc.host_addr.Low = host_addr_phy.Low;
+ dma_desc.nic_mbuf = 0x2100;
+ dma_desc.len = length;
+ dma_desc.flags = 0x00000004; /* Generate Rx-CPU event */
+
+ if (dma_read)
+ {
+ dma_desc.cqid_sqid = (T3_QID_RX_BD_COMP << 8) |
+ T3_QID_DMA_HIGH_PRI_READ;
+ REG_WR(pDevice, DmaRead.Mode, DMA_READ_MODE_ENABLE);
+ }
+ else
+ {
+ dma_desc.cqid_sqid = (T3_QID_RX_DATA_COMP << 8) |
+ T3_QID_DMA_HIGH_PRI_WRITE;
+ REG_WR(pDevice, DmaWrite.Mode, DMA_WRITE_MODE_ENABLE);
+ }
+
+ dma_desc_addr = T3_NIC_DMA_DESC_POOL_ADDR;
+
+ /* Writing this DMA descriptor to DMA memory */
+ for (i = 0; i < sizeof(T3_DMA_DESC); i += 4)
+ {
+ value32 = *((PLM_UINT32) (((PLM_UINT8) &dma_desc) + i));
+ MM_WriteConfig32(pDevice, T3_PCI_MEM_WIN_ADDR_REG, dma_desc_addr+i);
+ MM_WriteConfig32(pDevice, T3_PCI_MEM_WIN_DATA_REG, cpu_to_le32(value32));
+ }
+ MM_WriteConfig32(pDevice, T3_PCI_MEM_WIN_ADDR_REG, 0);
+
+ if (dma_read)
+ REG_WR(pDevice, Ftq.DmaHighReadFtqFifoEnqueueDequeue, dma_desc_addr);
+ else
+ REG_WR(pDevice, Ftq.DmaHighWriteFtqFifoEnqueueDequeue, dma_desc_addr);
+
+ for (i = 0; i < 40; i++)
+ {
+ if (dma_read)
+ value32 = REG_RD(pDevice, Ftq.RcvBdCompFtqFifoEnqueueDequeue);
+ else
+ value32 = REG_RD(pDevice, Ftq.RcvDataCompFtqFifoEnqueueDequeue);
+
+ if ((value32 & 0xffff) == dma_desc_addr)
+ break;
+
+ MM_Wait(10);
+ }
+
+ return LM_STATUS_SUCCESS;
+}
+
+STATIC LM_STATUS
+LM_DmaTest(PLM_DEVICE_BLOCK pDevice, PLM_UINT8 pBufferVirt,
+ LM_PHYSICAL_ADDRESS BufferPhy, LM_UINT32 BufferSize)
+{
+ int j;
+ LM_UINT32 *ptr;
+ int dma_success = 0;
+
+ if(T3_ASIC_REV(pDevice->ChipRevId) != T3_ASIC_REV_5700 &&
+ T3_ASIC_REV(pDevice->ChipRevId) != T3_ASIC_REV_5701)
+ {
+ return LM_STATUS_SUCCESS;
+ }
+ while (!dma_success)
+ {
+ /* Fill data with incremental patterns */
+ ptr = (LM_UINT32 *)pBufferVirt;
+ for (j = 0; j < BufferSize/4; j++)
+ *ptr++ = j;
+
+ if (t3_do_dma(pDevice,BufferPhy,BufferSize, 1) == LM_STATUS_FAILURE)
+ {
+ return LM_STATUS_FAILURE;
+ }
+
+ MM_Wait(40);
+ ptr = (LM_UINT32 *)pBufferVirt;
+ /* Fill data with zero */
+ for (j = 0; j < BufferSize/4; j++)
+ *ptr++ = 0;
+
+ if (t3_do_dma(pDevice,BufferPhy,BufferSize, 0) == LM_STATUS_FAILURE)
+ {
+ return LM_STATUS_FAILURE;
+ }
+
+ MM_Wait(40);
+ /* Check for data */
+ ptr = (LM_UINT32 *)pBufferVirt;
+ for (j = 0; j < BufferSize/4; j++)
+ {
+ if (*ptr++ != j)
+ {
+ if ((pDevice->DmaReadWriteCtrl & DMA_CTRL_WRITE_BOUNDARY_MASK)
+ == DMA_CTRL_WRITE_BOUNDARY_DISABLE)
+ {
+ pDevice->DmaReadWriteCtrl = (pDevice->DmaReadWriteCtrl &
+ ~DMA_CTRL_WRITE_BOUNDARY_MASK) |
+ DMA_CTRL_WRITE_BOUNDARY_16;
+ REG_WR(pDevice, PciCfg.DmaReadWriteCtrl,
+ pDevice->DmaReadWriteCtrl);
+ break;
+ }
+ else
+ {
+ return LM_STATUS_FAILURE;
+ }
+ }
+ }
+ if (j == (BufferSize/4))
+ dma_success = 1;
+ }
+ return LM_STATUS_SUCCESS;
+}
+#endif /* CFG_CMD_NET, !CONFIG_NET_MULTI, CONFIG_TIGON3 */
--- /dev/null
+
+/******************************************************************************/
+/* */
+/* Broadcom BCM5700 Linux Network Driver, Copyright (c) 2000 Broadcom */
+/* Corporation. */
+/* All rights reserved. */
+/* */
+/* 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, located in the file LICENSE. */
+/* */
+/* History: */
+/* */
+/******************************************************************************/
+
+#ifndef TIGON3_H
+#define TIGON3_H
+
+#include "bcm570x_lm.h"
+#if INCLUDE_TBI_SUPPORT
+#include "bcm570x_autoneg.h"
+#endif
+
+
+/* io defines */
+#if !defined(BIG_ENDIAN_HOST)
+#define readl(addr) \
+ (LONGSWAP((*(volatile unsigned int *)(addr))))
+#define writel(b,addr) \
+ ((*(volatile unsigned int *)(addr)) = (LONGSWAP(b)))
+#else
+#if 0 /* !defined(PPC603) */
+#define readl(addr) (*(volatile unsigned int*)(0xa0000000 + (unsigned long)(addr)))
+#define writel(b,addr) ((*(volatile unsigned int *) ((unsigned long)(addr) + 0xa0000000)) = (b))
+#else
+#if 1
+#define readl(addr) (*(volatile unsigned int*)(addr))
+#define writel(b,addr) ((*(volatile unsigned int *) (addr)) = (b))
+#else
+extern int sprintf(char* buf, const char* f, ...);
+static __inline unsigned int readl(void* addr){
+ char buf[128];
+ unsigned int tmp = (*(volatile unsigned int*)(addr));
+ sprintf(buf,"%s:%s: read 0x%x from 0x%x\n",__FILE__,__LINE__,tmp,addr,0,0);
+ sysSerialPrintString(buf);
+ return tmp;
+}
+static __inline void writel(unsigned int b, unsigned int addr){
+ char buf[128];
+ ((*(volatile unsigned int *) (addr)) = (b));
+ sprintf(buf,"%s:%s: write 0x%x to 0x%x\n",__FILE__,__LINE__,b,addr,0,0);
+ sysSerialPrintString(buf);
+}
+#endif
+#endif /* PPC603 */
+#endif
+
+
+
+
+/******************************************************************************/
+/* Constants. */
+/******************************************************************************/
+
+/* Maxim number of packet descriptors used for sending packets. */
+#define MAX_TX_PACKET_DESC_COUNT 600
+#define DEFAULT_TX_PACKET_DESC_COUNT 2
+
+/* Maximum number of packet descriptors used for receiving packets. */
+#if T3_JUMBO_RCB_ENTRY_COUNT
+#define MAX_RX_PACKET_DESC_COUNT \
+ (T3_STD_RCV_RCB_ENTRY_COUNT + T3_JUMBO_RCV_RCB_ENTRY_COUNT)
+#else
+#define MAX_RX_PACKET_DESC_COUNT 800
+#endif
+#define DEFAULT_RX_PACKET_DESC_COUNT 2
+
+/* Threshhold for double copying small tx packets. 0 will disable double */
+/* copying of small Tx packets. */
+#define DEFAULT_TX_COPY_BUFFER_SIZE 0
+#define MIN_TX_COPY_BUFFER_SIZE 64
+#define MAX_TX_COPY_BUFFER_SIZE 512
+
+/* Cache line. */
+#define COMMON_CACHE_LINE_SIZE 0x20
+#define COMMON_CACHE_LINE_MASK (COMMON_CACHE_LINE_SIZE-1)
+
+/* Maximum number of fragment we can handle. */
+#ifndef MAX_FRAGMENT_COUNT
+#define MAX_FRAGMENT_COUNT 32
+#endif
+
+/* B0 bug. */
+#define BCM5700_BX_MIN_FRAG_SIZE 10
+#define BCM5700_BX_MIN_FRAG_BUF_SIZE 16 /* nice aligned size. */
+#define BCM5700_BX_MIN_FRAG_BUF_SIZE_MASK (BCM5700_BX_MIN_FRAG_BUF_SIZE-1)
+#define BCM5700_BX_TX_COPY_BUF_SIZE (BCM5700_BX_MIN_FRAG_BUF_SIZE * \
+ MAX_FRAGMENT_COUNT)
+
+/* MAGIC number. */
+/* #define T3_MAGIC_NUM 'KevT' */
+#define T3_FIRMWARE_MAILBOX 0x0b50
+#define T3_MAGIC_NUM 0x4B657654
+#define T3_MAGIC_NUM_DISABLE_DMAW_ON_LINK_CHANGE 0x4861764b
+
+#define T3_NIC_DATA_SIG_ADDR 0x0b54
+#define T3_NIC_DATA_SIG 0x4b657654
+
+#define T3_NIC_DATA_NIC_CFG_ADDR 0x0b58
+#define T3_NIC_CFG_LED_MODE_UNKNOWN BIT_NONE
+#define T3_NIC_CFG_LED_MODE_TRIPLE_SPEED BIT_2
+#define T3_NIC_CFG_LED_MODE_LINK_SPEED BIT_3
+#define T3_NIC_CFG_LED_MODE_OPEN_DRAIN BIT_2
+#define T3_NIC_CFG_LED_MODE_OUTPUT BIT_3
+#define T3_NIC_CFG_LED_MODE_MASK (BIT_2 | BIT_3)
+#define T3_NIC_CFG_PHY_TYPE_UNKNOWN BIT_NONE
+#define T3_NIC_CFG_PHY_TYPE_COPPER BIT_4
+#define T3_NIC_CFG_PHY_TYPE_FIBER BIT_5
+#define T3_NIC_CFG_PHY_TYPE_MASK (BIT_4 | BIT_5)
+#define T3_NIC_CFG_ENABLE_WOL BIT_6
+#define T3_NIC_CFG_ENABLE_ASF BIT_7
+#define T3_NIC_EEPROM_WP BIT_8
+
+#define T3_NIC_DATA_PHY_ID_ADDR 0x0b74
+#define T3_NIC_PHY_ID1_MASK 0xffff0000
+#define T3_NIC_PHY_ID2_MASK 0x0000ffff
+
+#define T3_CMD_MAILBOX 0x0b78
+#define T3_CMD_NICDRV_ALIVE 0x01
+#define T3_CMD_NICDRV_PAUSE_FW 0x02
+#define T3_CMD_NICDRV_IPV4ADDR_CHANGE 0x03
+#define T3_CMD_NICDRV_IPV6ADDR_CHANGE 0x04
+#define T3_CMD_5703A0_FIX_DMAFW_DMAR 0x05
+#define T3_CMD_5703A0_FIX_DMAFW_DMAW 0x06
+
+#define T3_CMD_LENGTH_MAILBOX 0x0b7c
+#define T3_CMD_DATA_MAILBOX 0x0b80
+
+#define T3_ASF_FW_STATUS_MAILBOX 0x0c00
+
+#define T3_DRV_STATE_MAILBOX 0x0c04
+#define T3_DRV_STATE_START 0x01
+#define T3_DRV_STATE_UNLOAD 0x02
+#define T3_DRV_STATE_WOL 0x03
+#define T3_DRV_STATE_SUSPEND 0x04
+
+#define T3_FW_RESET_TYPE_MAILBOX 0x0c08
+
+#define T3_MAC_ADDR_HIGH_MAILBOX 0x0c14
+#define T3_MAC_ADDR_LOW_MAILBOX 0x0c18
+
+/******************************************************************************/
+/* Hardware constants. */
+/******************************************************************************/
+
+/* Number of entries in the send ring: must be 512. */
+#define T3_SEND_RCB_ENTRY_COUNT 512
+#define T3_SEND_RCB_ENTRY_COUNT_MASK (T3_SEND_RCB_ENTRY_COUNT-1)
+
+/* Number of send RCBs. May be 1-16 but for now, only support one. */
+#define T3_MAX_SEND_RCB_COUNT 16
+
+/* Number of entries in the Standard Receive RCB. Must be 512 entries. */
+#define T3_STD_RCV_RCB_ENTRY_COUNT 512
+#define T3_STD_RCV_RCB_ENTRY_COUNT_MASK (T3_STD_RCV_RCB_ENTRY_COUNT-1)
+#define DEFAULT_STD_RCV_DESC_COUNT 200 /* Must be < 512. */
+#define MAX_STD_RCV_BUFFER_SIZE 0x600
+
+/* Number of entries in the Mini Receive RCB. This value can either be */
+/* 0, 1024. Currently Mini Receive RCB is disabled. */
+#ifndef T3_MINI_RCV_RCB_ENTRY_COUNT
+#define T3_MINI_RCV_RCB_ENTRY_COUNT 0
+#endif /* T3_MINI_RCV_RCB_ENTRY_COUNT */
+#define T3_MINI_RCV_RCB_ENTRY_COUNT_MASK (T3_MINI_RCV_RCB_ENTRY_COUNT-1)
+#define MAX_MINI_RCV_BUFFER_SIZE 512
+#define DEFAULT_MINI_RCV_BUFFER_SIZE 64
+#define DEFAULT_MINI_RCV_DESC_COUNT 100 /* Must be < 1024. */
+
+/* Number of entries in the Jumbo Receive RCB. This value must 256 or 0. */
+/* Currently, Jumbo Receive RCB is disabled. */
+#ifndef T3_JUMBO_RCV_RCB_ENTRY_COUNT
+#define T3_JUMBO_RCV_RCB_ENTRY_COUNT 0
+#endif /* T3_JUMBO_RCV_RCB_ENTRY_COUNT */
+#define T3_JUMBO_RCV_RCB_ENTRY_COUNT_MASK (T3_JUMBO_RCV_RCB_ENTRY_COUNT-1)
+
+#define MAX_JUMBO_RCV_BUFFER_SIZE (10 * 1024) /* > 1514 */
+#define DEFAULT_JUMBO_RCV_BUFFER_SIZE (4 * 1024) /* > 1514 */
+#define DEFAULT_JUMBO_RCV_DESC_COUNT 128 /* Must be < 256. */
+
+#define MAX_JUMBO_TX_BUFFER_SIZE (8 * 1024) /* > 1514 */
+#define DEFAULT_JUMBO_TX_BUFFER_SIZE (4 * 1024) /* > 1514 */
+
+/* Number of receive return RCBs. Maybe 1-16 but for now, only support one. */
+#define T3_MAX_RCV_RETURN_RCB_COUNT 16
+
+/* Number of entries in a Receive Return ring. This value is either 1024 */
+/* or 2048. */
+#ifndef T3_RCV_RETURN_RCB_ENTRY_COUNT
+#define T3_RCV_RETURN_RCB_ENTRY_COUNT 1024
+#endif /* T3_RCV_RETURN_RCB_ENTRY_COUNT */
+#define T3_RCV_RETURN_RCB_ENTRY_COUNT_MASK (T3_RCV_RETURN_RCB_ENTRY_COUNT-1)
+
+
+/* Default coalescing parameters. */
+#define DEFAULT_RX_COALESCING_TICKS 100
+#define MAX_RX_COALESCING_TICKS 500
+#define DEFAULT_TX_COALESCING_TICKS 400
+#define MAX_TX_COALESCING_TICKS 500
+#define DEFAULT_RX_MAX_COALESCED_FRAMES 10
+#define MAX_RX_MAX_COALESCED_FRAMES 100
+#define ADAPTIVE_LO_RX_MAX_COALESCED_FRAMES 5
+#define ADAPTIVE_HI_RX_MAX_COALESCED_FRAMES 42
+#define ADAPTIVE_LO_RX_COALESCING_TICKS 50
+#define ADAPTIVE_HI_RX_COALESCING_TICKS 300
+#define ADAPTIVE_LO_PKT_THRESH 30000
+#define ADAPTIVE_HI_PKT_THRESH 74000
+#define DEFAULT_TX_MAX_COALESCED_FRAMES 40
+#define ADAPTIVE_LO_TX_MAX_COALESCED_FRAMES 25
+#define ADAPTIVE_HI_TX_MAX_COALESCED_FRAMES 75
+#define MAX_TX_MAX_COALESCED_FRAMES 100
+
+#define DEFAULT_RX_COALESCING_TICKS_DURING_INT 25
+#define DEFAULT_TX_COALESCING_TICKS_DURING_INT 25
+#define DEFAULT_RX_MAX_COALESCED_FRAMES_DURING_INT 5
+#define DEFAULT_TX_MAX_COALESCED_FRAMES_DURING_INT 5
+
+#define BAD_DEFAULT_VALUE 0xffffffff
+
+#define DEFAULT_STATS_COALESCING_TICKS 1000000
+#define MAX_STATS_COALESCING_TICKS 3600000000U
+
+
+/* Receive BD Replenish thresholds. */
+#define DEFAULT_RCV_STD_BD_REPLENISH_THRESHOLD 4
+#define DEFAULT_RCV_JUMBO_BD_REPLENISH_THRESHOLD 4
+
+#define SPLIT_MODE_DISABLE 0
+#define SPLIT_MODE_ENABLE 1
+
+#define SPLIT_MODE_5704_MAX_REQ 3
+
+/* Maximum physical fragment size. */
+#define MAX_FRAGMENT_SIZE (64 * 1024)
+
+
+/* Standard view. */
+#define T3_STD_VIEW_SIZE (64 * 1024)
+#define T3_FLAT_VIEW_SIZE (32 * 1024 * 1024)
+
+
+/* Buffer descriptor base address on the NIC's memory. */
+
+#define T3_NIC_SND_BUFFER_DESC_ADDR 0x4000
+#define T3_NIC_STD_RCV_BUFFER_DESC_ADDR 0x6000
+#define T3_NIC_JUMBO_RCV_BUFFER_DESC_ADDR 0x7000
+
+#define T3_NIC_STD_RCV_BUFFER_DESC_ADDR_EXT_MEM 0xc000
+#define T3_NIC_JUMBO_RCV_BUFFER_DESC_ADDR_EXT_MEM 0xd000
+#define T3_NIC_MINI_RCV_BUFFER_DESC_ADDR_EXT_MEM 0xe000
+
+#define T3_NIC_SND_BUFFER_DESC_SIZE (T3_SEND_RCB_ENTRY_COUNT * \
+ sizeof(T3_SND_BD) / 4)
+
+#define T3_NIC_STD_RCV_BUFFER_DESC_SIZE (T3_STD_RCV_RCB_ENTRY_COUNT * \
+ sizeof(T3_RCV_BD) / 4)
+
+#define T3_NIC_JUMBO_RCV_BUFFER_DESC_SIZE (T3_JUMBO_RCV_RCB_ENTRY_COUNT * \
+ sizeof(T3_EXT_RCV_BD) / 4)
+
+
+/* MBUF pool. */
+#define T3_NIC_MBUF_POOL_ADDR 0x8000
+/* #define T3_NIC_MBUF_POOL_SIZE 0x18000 */
+#define T3_NIC_MBUF_POOL_SIZE96 0x18000
+#define T3_NIC_MBUF_POOL_SIZE64 0x10000
+
+
+#define T3_NIC_MBUF_POOL_ADDR_EXT_MEM 0x20000
+
+/* DMA descriptor pool */
+#define T3_NIC_DMA_DESC_POOL_ADDR 0x2000
+#define T3_NIC_DMA_DESC_POOL_SIZE 0x2000 /* 8KB. */
+
+#define T3_DEF_DMA_MBUF_LOW_WMARK 0x40
+#define T3_DEF_RX_MAC_MBUF_LOW_WMARK 0x20
+#define T3_DEF_MBUF_HIGH_WMARK 0x60
+
+#define T3_DEF_DMA_MBUF_LOW_WMARK_JUMBO 304
+#define T3_DEF_RX_MAC_MBUF_LOW_WMARK_JUMBO 152
+#define T3_DEF_MBUF_HIGH_WMARK_JUMBO 380
+
+#define T3_DEF_DMA_DESC_LOW_WMARK 5
+#define T3_DEF_DMA_DESC_HIGH_WMARK 10
+
+/* Maximum size of giant TCP packet can be sent */
+#define T3_TCP_SEG_MAX_OFFLOAD_SIZE 64*1000
+#define T3_TCP_SEG_MIN_NUM_SEG 20
+
+#define T3_RX_CPU_ID 0x1
+#define T3_TX_CPU_ID 0x2
+#define T3_RX_CPU_SPAD_ADDR 0x30000
+#define T3_RX_CPU_SPAD_SIZE 0x4000
+#define T3_TX_CPU_SPAD_ADDR 0x34000
+#define T3_TX_CPU_SPAD_SIZE 0x4000
+
+typedef struct T3_DIR_ENTRY
+{
+ PLM_UINT8 Buffer;
+ LM_UINT32 Offset;
+ LM_UINT32 Length;
+} T3_DIR_ENTRY,*PT3_DIR_ENTRY;
+
+typedef struct T3_FWIMG_INFO
+{
+ LM_UINT32 StartAddress;
+ T3_DIR_ENTRY Text;
+ T3_DIR_ENTRY ROnlyData;
+ T3_DIR_ENTRY Data;
+ T3_DIR_ENTRY Sbss;
+ T3_DIR_ENTRY Bss;
+} T3_FWIMG_INFO, *PT3_FWIMG_INFO;
+
+
+
+/******************************************************************************/
+/* Tigon3 PCI Registers. */
+/******************************************************************************/
+#define T3_PCI_ID_BCM5700 0x164414e4
+#define T3_PCI_ID_BCM5701 0x164514e4
+#define T3_PCI_ID_BCM5702 0x164614e4
+#define T3_PCI_ID_BCM5702x 0x16A614e4
+#define T3_PCI_ID_BCM5703 0x164714e4
+#define T3_PCI_ID_BCM5703x 0x16A714e4
+#define T3_PCI_ID_BCM5702FE 0x164D14e4
+#define T3_PCI_ID_BCM5704 0x164814e4
+
+#define T3_PCI_VENDOR_ID (T3_PCI_ID & 0xffff)
+#define T3_PCI_DEVICE_ID (T3_PCI_ID >> 16)
+
+#define T3_PCI_MISC_HOST_CTRL_REG 0x68
+
+/* The most significant 16bit of register 0x68. */
+/* ChipId:4, ChipRev:4, MetalRev:8 */
+#define T3_CHIP_ID_5700_A0 0x7000
+#define T3_CHIP_ID_5700_A1 0x7001
+#define T3_CHIP_ID_5700_B0 0x7100
+#define T3_CHIP_ID_5700_B1 0x7101
+#define T3_CHIP_ID_5700_C0 0x7200
+
+#define T3_CHIP_ID_5701_A0 0x0000
+#define T3_CHIP_ID_5701_B0 0x0100
+#define T3_CHIP_ID_5701_B2 0x0102
+#define T3_CHIP_ID_5701_B5 0x0105
+
+#define T3_CHIP_ID_5703_A0 0x1000
+#define T3_CHIP_ID_5703_A1 0x1001
+#define T3_CHIP_ID_5703_A2 0x1002
+
+#define T3_CHIP_ID_5704_A0 0x2000
+
+/* Chip Id. */
+#define T3_ASIC_REV(_ChipRevId) ((_ChipRevId) >> 12)
+#define T3_ASIC_REV_5700 0x07
+#define T3_ASIC_REV_5701 0x00
+#define T3_ASIC_REV_5703 0x01
+#define T3_ASIC_REV_5704 0x02
+
+
+/* Chip id and revision. */
+#define T3_CHIP_REV(_ChipRevId) ((_ChipRevId) >> 8)
+#define T3_CHIP_REV_5700_AX 0x70
+#define T3_CHIP_REV_5700_BX 0x71
+#define T3_CHIP_REV_5700_CX 0x72
+#define T3_CHIP_REV_5701_AX 0x00
+
+/* Metal revision. */
+#define T3_METAL_REV(_ChipRevId) ((_ChipRevId) & 0xff)
+#define T3_METAL_REV_A0 0x00
+#define T3_METAL_REV_A1 0x01
+#define T3_METAL_REV_B0 0x00
+#define T3_METAL_REV_B1 0x01
+#define T3_METAL_REV_B2 0x02
+
+#define T3_PCI_REG_CLOCK_CTRL 0x74
+
+#define T3_PCI_DISABLE_RX_CLOCK BIT_10
+#define T3_PCI_DISABLE_TX_CLOCK BIT_11
+#define T3_PCI_SELECT_ALTERNATE_CLOCK BIT_12
+#define T3_PCI_POWER_DOWN_PCI_PLL133 BIT_15
+#define T3_PCI_44MHZ_CORE_CLOCK BIT_18
+
+
+#define T3_PCI_REG_ADDR_REG 0x78
+#define T3_PCI_REG_DATA_REG 0x80
+
+#define T3_PCI_MEM_WIN_ADDR_REG 0x7c
+#define T3_PCI_MEM_WIN_DATA_REG 0x84
+
+#define T3_PCI_PM_CAP_REG 0x48
+
+#define T3_PCI_PM_CAP_PME_D3COLD BIT_31
+#define T3_PCI_PM_CAP_PME_D3HOT BIT_30
+
+#define T3_PCI_PM_STATUS_CTRL_REG 0x4c
+
+#define T3_PM_POWER_STATE_MASK (BIT_0 | BIT_1)
+#define T3_PM_POWER_STATE_D0 BIT_NONE
+#define T3_PM_POWER_STATE_D1 BIT_0
+#define T3_PM_POWER_STATE_D2 BIT_1
+#define T3_PM_POWER_STATE_D3 (BIT_0 | BIT_1)
+
+#define T3_PM_PME_ENABLE BIT_8
+#define T3_PM_PME_ASSERTED BIT_15
+
+
+/* PCI state register. */
+#define T3_PCI_STATE_REG 0x70
+
+#define T3_PCI_STATE_FORCE_RESET BIT_0
+#define T3_PCI_STATE_INT_NOT_ACTIVE BIT_1
+#define T3_PCI_STATE_CONVENTIONAL_PCI_MODE BIT_2
+#define T3_PCI_STATE_BUS_SPEED_HIGH BIT_3
+#define T3_PCI_STATE_32BIT_PCI_BUS BIT_4
+
+
+/* Broadcom subsystem/subvendor IDs. */
+#define T3_SVID_BROADCOM 0x14e4
+
+#define T3_SSID_BROADCOM_BCM95700A6 0x1644
+#define T3_SSID_BROADCOM_BCM95701A5 0x0001
+#define T3_SSID_BROADCOM_BCM95700T6 0x0002 /* BCM8002 */
+#define T3_SSID_BROADCOM_BCM95700A9 0x0003 /* Agilent */
+#define T3_SSID_BROADCOM_BCM95701T1 0x0005
+#define T3_SSID_BROADCOM_BCM95701T8 0x0006
+#define T3_SSID_BROADCOM_BCM95701A7 0x0007 /* Agilent */
+#define T3_SSID_BROADCOM_BCM95701A10 0x0008
+#define T3_SSID_BROADCOM_BCM95701A12 0x8008
+#define T3_SSID_BROADCOM_BCM95703Ax1 0x0009
+#define T3_SSID_BROADCOM_BCM95703Ax2 0x8009
+
+/* 3COM subsystem/subvendor IDs. */
+#define T3_SVID_3COM 0x10b7
+
+#define T3_SSID_3COM_3C996T 0x1000
+#define T3_SSID_3COM_3C996BT 0x1006
+#define T3_SSID_3COM_3C996CT 0x1002
+#define T3_SSID_3COM_3C997T 0x1003
+#define T3_SSID_3COM_3C1000T 0x1007
+#define T3_SSID_3COM_3C940BR01 0x1008
+
+/* Fiber boards. */
+#define T3_SSID_3COM_3C996SX 0x1004
+#define T3_SSID_3COM_3C997SX 0x1005
+
+
+/* Dell subsystem/subvendor IDs. */
+
+#define T3_SVID_DELL 0x1028
+
+#define T3_SSID_DELL_VIPER 0x00d1
+#define T3_SSID_DELL_JAGUAR 0x0106
+#define T3_SSID_DELL_MERLOT 0x0109
+#define T3_SSID_DELL_SLIM_MERLOT 0x010a
+
+/* Compaq subsystem/subvendor IDs */
+
+#define T3_SVID_COMPAQ 0x0e11
+
+#define T3_SSID_COMPAQ_BANSHEE 0x007c
+#define T3_SSID_COMPAQ_BANSHEE_2 0x009a
+#define T3_SSID_COMPAQ_CHANGELING 0x007d
+#define T3_SSID_COMPAQ_NC7780 0x0085
+#define T3_SSID_COMPAQ_NC7780_2 0x0099
+
+
+/******************************************************************************/
+/* MII registers. */
+/******************************************************************************/
+
+/* Control register. */
+#define PHY_CTRL_REG 0x00
+
+#define PHY_CTRL_SPEED_MASK (BIT_6 | BIT_13)
+#define PHY_CTRL_SPEED_SELECT_10MBPS BIT_NONE
+#define PHY_CTRL_SPEED_SELECT_100MBPS BIT_13
+#define PHY_CTRL_SPEED_SELECT_1000MBPS BIT_6
+#define PHY_CTRL_COLLISION_TEST_ENABLE BIT_7
+#define PHY_CTRL_FULL_DUPLEX_MODE BIT_8
+#define PHY_CTRL_RESTART_AUTO_NEG BIT_9
+#define PHY_CTRL_ISOLATE_PHY BIT_10
+#define PHY_CTRL_LOWER_POWER_MODE BIT_11
+#define PHY_CTRL_AUTO_NEG_ENABLE BIT_12
+#define PHY_CTRL_LOOPBACK_MODE BIT_14
+#define PHY_CTRL_PHY_RESET BIT_15
+
+
+/* Status register. */
+#define PHY_STATUS_REG 0x01
+
+#define PHY_STATUS_LINK_PASS BIT_2
+#define PHY_STATUS_AUTO_NEG_COMPLETE BIT_5
+
+
+/* Phy Id registers. */
+#define PHY_ID1_REG 0x02
+#define PHY_ID1_OUI_MASK 0xffff
+
+#define PHY_ID2_REG 0x03
+#define PHY_ID2_REV_MASK 0x000f
+#define PHY_ID2_MODEL_MASK 0x03f0
+#define PHY_ID2_OUI_MASK 0xfc00
+
+
+/* Auto-negotiation advertisement register. */
+#define PHY_AN_AD_REG 0x04
+
+#define PHY_AN_AD_ASYM_PAUSE BIT_11
+#define PHY_AN_AD_PAUSE_CAPABLE BIT_10
+#define PHY_AN_AD_10BASET_HALF BIT_5
+#define PHY_AN_AD_10BASET_FULL BIT_6
+#define PHY_AN_AD_100BASETX_HALF BIT_7
+#define PHY_AN_AD_100BASETX_FULL BIT_8
+#define PHY_AN_AD_PROTOCOL_802_3_CSMA_CD 0x01
+
+
+/* Auto-negotiation Link Partner Ability register. */
+#define PHY_LINK_PARTNER_ABILITY_REG 0x05
+
+#define PHY_LINK_PARTNER_ASYM_PAUSE BIT_11
+#define PHY_LINK_PARTNER_PAUSE_CAPABLE BIT_10
+
+
+/* Auto-negotiation expansion register. */
+#define PHY_AN_EXPANSION_REG 0x06
+
+
+
+/******************************************************************************/
+/* BCM5400 and BCM5401 phy info. */
+/******************************************************************************/
+
+#define PHY_DEVICE_ID 1
+
+/* OUI: bit 31-10; Model#: bit 9-4; Rev# bit 3-0. */
+#define PHY_UNKNOWN_PHY 0x00000000
+#define PHY_BCM5400_PHY_ID 0x60008040
+#define PHY_BCM5401_PHY_ID 0x60008050
+#define PHY_BCM5411_PHY_ID 0x60008070
+#define PHY_BCM5701_PHY_ID 0x60008110
+#define PHY_BCM5703_PHY_ID 0x60008160
+#define PHY_BCM5704_PHY_ID 0x60008190
+#define PHY_BCM8002_PHY_ID 0x60010140
+
+#define PHY_BCM5401_B0_REV 0x1
+#define PHY_BCM5401_B2_REV 0x3
+#define PHY_BCM5401_C0_REV 0x6
+
+#define PHY_ID_OUI_MASK 0xfffffc00
+#define PHY_ID_MODEL_MASK 0x000003f0
+#define PHY_ID_REV_MASK 0x0000000f
+#define PHY_ID_MASK (PHY_ID_OUI_MASK | \
+ PHY_ID_MODEL_MASK)
+
+
+#define UNKNOWN_PHY_ID(x) ((((x) & PHY_ID_MASK) != PHY_BCM5400_PHY_ID) && \
+ (((x) & PHY_ID_MASK) != PHY_BCM5401_PHY_ID) && \
+ (((x) & PHY_ID_MASK) != PHY_BCM5411_PHY_ID) && \
+ (((x) & PHY_ID_MASK) != PHY_BCM5701_PHY_ID) && \
+ (((x) & PHY_ID_MASK) != PHY_BCM5703_PHY_ID) && \
+ (((x) & PHY_ID_MASK) != PHY_BCM5704_PHY_ID) && \
+ (((x) & PHY_ID_MASK) != PHY_BCM8002_PHY_ID))
+
+
+
+/* 1000Base-T control register. */
+#define BCM540X_1000BASET_CTRL_REG 0x09
+
+#define BCM540X_AN_AD_1000BASET_HALF BIT_8
+#define BCM540X_AN_AD_1000BASET_FULL BIT_9
+#define BCM540X_CONFIG_AS_MASTER BIT_11
+#define BCM540X_ENABLE_CONFIG_AS_MASTER BIT_12
+
+
+/* Extended control register. */
+#define BCM540X_EXT_CTRL_REG 0x10
+
+#define BCM540X_EXT_CTRL_LINK3_LED_MODE BIT_1
+#define BCM540X_EXT_CTRL_TBI BIT_15
+
+/* PHY extended status register. */
+#define BCM540X_EXT_STATUS_REG 0x11
+
+#define BCM540X_EXT_STATUS_LINK_PASS BIT_8
+
+
+/* DSP Coefficient Read/Write Port. */
+#define BCM540X_DSP_RW_PORT 0x15
+
+
+/* DSP Coeficient Address Register. */
+#define BCM540X_DSP_ADDRESS_REG 0x17
+
+#define BCM540X_DSP_TAP_NUMBER_MASK 0x00
+#define BCM540X_DSP_AGC_A 0x00
+#define BCM540X_DSP_AGC_B 0x01
+#define BCM540X_DSP_MSE_PAIR_STATUS 0x02
+#define BCM540X_DSP_SOFT_DECISION 0x03
+#define BCM540X_DSP_PHASE_REG 0x04
+#define BCM540X_DSP_SKEW 0x05
+#define BCM540X_DSP_POWER_SAVER_UPPER_BOUND 0x06
+#define BCM540X_DSP_POWER_SAVER_LOWER_BOUND 0x07
+#define BCM540X_DSP_LAST_ECHO 0x08
+#define BCM540X_DSP_FREQUENCY 0x09
+#define BCM540X_DSP_PLL_BANDWIDTH 0x0a
+#define BCM540X_DSP_PLL_PHASE_OFFSET 0x0b
+
+#define BCM540X_DSP_FILTER_DCOFFSET (BIT_10 | BIT_11)
+#define BCM540X_DSP_FILTER_FEXT3 (BIT_8 | BIT_9 | BIT_11)
+#define BCM540X_DSP_FILTER_FEXT2 (BIT_9 | BIT_11)
+#define BCM540X_DSP_FILTER_FEXT1 (BIT_8 | BIT_11)
+#define BCM540X_DSP_FILTER_FEXT0 BIT_11
+#define BCM540X_DSP_FILTER_NEXT3 (BIT_8 | BIT_9 | BIT_10)
+#define BCM540X_DSP_FILTER_NEXT2 (BIT_9 | BIT_10)
+#define BCM540X_DSP_FILTER_NEXT1 (BIT_8 | BIT_10)
+#define BCM540X_DSP_FILTER_NEXT0 BIT_10
+#define BCM540X_DSP_FILTER_ECHO (BIT_8 | BIT_9)
+#define BCM540X_DSP_FILTER_DFE BIT_9
+#define BCM540X_DSP_FILTER_FFE BIT_8
+
+#define BCM540X_DSP_CONTROL_ALL_FILTERS BIT_12
+
+#define BCM540X_DSP_SEL_CH_0 BIT_NONE
+#define BCM540X_DSP_SEL_CH_1 BIT_13
+#define BCM540X_DSP_SEL_CH_2 BIT_14
+#define BCM540X_DSP_SEL_CH_3 (BIT_13 | BIT_14)
+
+#define BCM540X_CONTROL_ALL_CHANNELS BIT_15
+
+
+/* Auxilliary Control Register (Shadow Register) */
+#define BCM5401_AUX_CTRL 0x18
+
+#define BCM5401_SHADOW_SEL_MASK 0x7
+#define BCM5401_SHADOW_SEL_NORMAL 0x00
+#define BCM5401_SHADOW_SEL_10BASET 0x01
+#define BCM5401_SHADOW_SEL_POWER_CONTROL 0x02
+#define BCM5401_SHADOW_SEL_IP_PHONE 0x03
+#define BCM5401_SHADOW_SEL_MISC_TEST1 0x04
+#define BCM5401_SHADOW_SEL_MISC_TEST2 0x05
+#define BCM5401_SHADOW_SEL_IP_PHONE_SEED 0x06
+
+
+/* Shadow register selector == '000' */
+#define BCM5401_SHDW_NORMAL_DIAG_MODE BIT_3
+#define BCM5401_SHDW_NORMAL_DISABLE_MBP BIT_4
+#define BCM5401_SHDW_NORMAL_DISABLE_LOW_PWR BIT_5
+#define BCM5401_SHDW_NORMAL_DISABLE_INV_PRF BIT_6
+#define BCM5401_SHDW_NORMAL_DISABLE_PRF BIT_7
+#define BCM5401_SHDW_NORMAL_RX_SLICING_NORMAL BIT_NONE
+#define BCM5401_SHDW_NORMAL_RX_SLICING_4D BIT_8
+#define BCM5401_SHDW_NORMAL_RX_SLICING_3LVL_1D BIT_9
+#define BCM5401_SHDW_NORMAL_RX_SLICING_5LVL_1D (BIT_8 | BIT_9)
+#define BCM5401_SHDW_NORMAL_TX_6DB_CODING BIT_10
+#define BCM5401_SHDW_NORMAL_ENABLE_SM_DSP_CLOCK BIT_11
+#define BCM5401_SHDW_NORMAL_EDGERATE_CTRL_4NS BIT_NONE
+#define BCM5401_SHDW_NORMAL_EDGERATE_CTRL_5NS BIT_12
+#define BCM5401_SHDW_NORMAL_EDGERATE_CTRL_3NS BIT_13
+#define BCM5401_SHDW_NORMAL_EDGERATE_CTRL_0NS (BIT_12 | BIT_13)
+#define BCM5401_SHDW_NORMAL_EXT_PACKET_LENGTH BIT_14
+#define BCM5401_SHDW_NORMAL_EXTERNAL_LOOPBACK BIT_15
+
+
+/* Auxilliary status summary. */
+#define BCM540X_AUX_STATUS_REG 0x19
+
+#define BCM540X_AUX_LINK_PASS BIT_2
+#define BCM540X_AUX_SPEED_MASK (BIT_8 | BIT_9 | BIT_10)
+#define BCM540X_AUX_10BASET_HD BIT_8
+#define BCM540X_AUX_10BASET_FD BIT_9
+#define BCM540X_AUX_100BASETX_HD (BIT_8 | BIT_9)
+#define BCM540X_AUX_100BASET4 BIT_10
+#define BCM540X_AUX_100BASETX_FD (BIT_8 | BIT_10)
+#define BCM540X_AUX_100BASET_HD (BIT_9 | BIT_10)
+#define BCM540X_AUX_100BASET_FD (BIT_8 | BIT_9 | BIT_10)
+
+
+/* Interrupt status. */
+#define BCM540X_INT_STATUS_REG 0x1a
+
+#define BCM540X_INT_LINK_CHANGE BIT_1
+#define BCM540X_INT_SPEED_CHANGE BIT_2
+#define BCM540X_INT_DUPLEX_CHANGE BIT_3
+#define BCM540X_INT_AUTO_NEG_PAGE_RX BIT_10
+
+
+/* Interrupt mask register. */
+#define BCM540X_INT_MASK_REG 0x1b
+
+
+
+/******************************************************************************/
+/* Register definitions. */
+/******************************************************************************/
+
+typedef volatile LM_UINT8 T3_8BIT_REGISTER, *PT3_8BIT_REGISTER;
+typedef volatile LM_UINT16 T3_16BIT_REGISTER, *PT3_16BIT_REGISTER;
+typedef volatile LM_UINT32 T3_32BIT_REGISTER, *PT3_32BIT_REGISTER;
+
+typedef struct {
+ /* Big endian format. */
+ T3_32BIT_REGISTER High;
+ T3_32BIT_REGISTER Low;
+} T3_64BIT_REGISTER, *PT3_64BIT_REGISTER;
+
+typedef T3_64BIT_REGISTER T3_64BIT_HOST_ADDR, *PT3_64BIT_HOST_ADDR;
+
+#define T3_NUM_OF_DMA_DESC 256
+#define T3_NUM_OF_MBUF 768
+
+typedef struct
+{
+ T3_64BIT_REGISTER host_addr;
+ T3_32BIT_REGISTER nic_mbuf;
+ T3_16BIT_REGISTER len;
+ T3_16BIT_REGISTER cqid_sqid;
+ T3_32BIT_REGISTER flags;
+ T3_32BIT_REGISTER opaque1;
+ T3_32BIT_REGISTER opaque2;
+ T3_32BIT_REGISTER opaque3;
+}T3_DMA_DESC, *PT3_DMA_DESC;
+
+
+
+/******************************************************************************/
+/* Ring control block. */
+/******************************************************************************/
+
+typedef struct {
+ T3_64BIT_REGISTER HostRingAddr;
+
+ union {
+ struct {
+#ifdef BIG_ENDIAN_HOST
+ T3_16BIT_REGISTER MaxLen;
+ T3_16BIT_REGISTER Flags;
+#else /* BIG_ENDIAN_HOST */
+ T3_16BIT_REGISTER Flags;
+ T3_16BIT_REGISTER MaxLen;
+#endif
+ } s;
+
+ T3_32BIT_REGISTER MaxLen_Flags;
+ } u;
+
+ T3_32BIT_REGISTER NicRingAddr;
+} T3_RCB, *PT3_RCB;
+
+#define T3_RCB_FLAG_USE_EXT_RECV_BD BIT_0
+#define T3_RCB_FLAG_RING_DISABLED BIT_1
+
+
+
+/******************************************************************************/
+/* Status block. */
+/******************************************************************************/
+
+/*
+ * Size of status block is actually 0x50 bytes. Use 0x80 bytes for
+ * cache line alignment.
+ */
+#define T3_STATUS_BLOCK_SIZE 0x80
+
+typedef struct {
+ volatile LM_UINT32 Status;
+ #define STATUS_BLOCK_UPDATED BIT_0
+ #define STATUS_BLOCK_LINK_CHANGED_STATUS BIT_1
+ #define STATUS_BLOCK_ERROR BIT_2
+
+ volatile LM_UINT32 StatusTag;
+
+#ifdef BIG_ENDIAN_HOST
+ volatile LM_UINT16 RcvStdConIdx;
+ volatile LM_UINT16 RcvJumboConIdx;
+
+ volatile LM_UINT16 Reserved2;
+ volatile LM_UINT16 RcvMiniConIdx;
+
+ struct {
+ volatile LM_UINT16 SendConIdx; /* Send consumer index. */
+ volatile LM_UINT16 RcvProdIdx; /* Receive producer index. */
+ } Idx[16];
+#else /* BIG_ENDIAN_HOST */
+ volatile LM_UINT16 RcvJumboConIdx;
+ volatile LM_UINT16 RcvStdConIdx;
+
+ volatile LM_UINT16 RcvMiniConIdx;
+ volatile LM_UINT16 Reserved2;
+
+ struct {
+ volatile LM_UINT16 RcvProdIdx; /* Receive producer index. */
+ volatile LM_UINT16 SendConIdx; /* Send consumer index. */
+ } Idx[16];
+#endif
+} T3_STATUS_BLOCK, *PT3_STATUS_BLOCK;
+
+
+
+/******************************************************************************/
+/* Receive buffer descriptors. */
+/******************************************************************************/
+
+typedef struct {
+ T3_64BIT_HOST_ADDR HostAddr;
+
+#ifdef BIG_ENDIAN_HOST
+ volatile LM_UINT16 Index;
+ volatile LM_UINT16 Len;
+
+ volatile LM_UINT16 Type;
+ volatile LM_UINT16 Flags;
+
+ volatile LM_UINT16 IpCksum;
+ volatile LM_UINT16 TcpUdpCksum;
+
+ volatile LM_UINT16 ErrorFlag;
+ volatile LM_UINT16 VlanTag;
+#else /* BIG_ENDIAN_HOST */
+ volatile LM_UINT16 Len;
+ volatile LM_UINT16 Index;
+
+ volatile LM_UINT16 Flags;
+ volatile LM_UINT16 Type;
+
+ volatile LM_UINT16 TcpUdpCksum;
+ volatile LM_UINT16 IpCksum;
+
+ volatile LM_UINT16 VlanTag;
+ volatile LM_UINT16 ErrorFlag;
+#endif
+
+ volatile LM_UINT32 Reserved;
+ volatile LM_UINT32 Opaque;
+} T3_RCV_BD, *PT3_RCV_BD;
+
+
+typedef struct {
+ T3_64BIT_HOST_ADDR HostAddr[3];
+
+#ifdef BIG_ENDIAN_HOST
+ LM_UINT16 Len1;
+ LM_UINT16 Len2;
+
+ LM_UINT16 Len3;
+ LM_UINT16 Reserved1;
+#else /* BIG_ENDIAN_HOST */
+ LM_UINT16 Len2;
+ LM_UINT16 Len1;
+
+ LM_UINT16 Reserved1;
+ LM_UINT16 Len3;
+#endif
+
+ T3_RCV_BD StdRcvBd;
+} T3_EXT_RCV_BD, *PT3_EXT_RCV_BD;
+
+
+/* Error flags. */
+#define RCV_BD_ERR_BAD_CRC 0x0001
+#define RCV_BD_ERR_COLL_DETECT 0x0002
+#define RCV_BD_ERR_LINK_LOST_DURING_PKT 0x0004
+#define RCV_BD_ERR_PHY_DECODE_ERR 0x0008
+#define RCV_BD_ERR_ODD_NIBBLED_RCVD_MII 0x0010
+#define RCV_BD_ERR_MAC_ABORT 0x0020
+#define RCV_BD_ERR_LEN_LT_64 0x0040
+#define RCV_BD_ERR_TRUNC_NO_RESOURCES 0x0080
+#define RCV_BD_ERR_GIANT_FRAME_RCVD 0x0100
+
+
+/* Buffer descriptor flags. */
+#define RCV_BD_FLAG_END 0x0004
+#define RCV_BD_FLAG_JUMBO_RING 0x0020
+#define RCV_BD_FLAG_VLAN_TAG 0x0040
+#define RCV_BD_FLAG_FRAME_HAS_ERROR 0x0400
+#define RCV_BD_FLAG_MINI_RING 0x0800
+#define RCV_BD_FLAG_IP_CHKSUM_FIELD 0x1000
+#define RCV_BD_FLAG_TCP_UDP_CHKSUM_FIELD 0x2000
+#define RCV_BD_FLAG_TCP_PACKET 0x4000
+
+
+
+/******************************************************************************/
+/* Send buffer descriptor. */
+/******************************************************************************/
+
+typedef struct {
+ T3_64BIT_HOST_ADDR HostAddr;
+
+ union {
+ struct {
+#ifdef BIG_ENDIAN_HOST
+ LM_UINT16 Len;
+ LM_UINT16 Flags;
+#else /* BIG_ENDIAN_HOST */
+ LM_UINT16 Flags;
+ LM_UINT16 Len;
+#endif
+ } s1;
+
+ LM_UINT32 Len_Flags;
+ } u1;
+
+ union {
+ struct {
+#ifdef BIG_ENDIAN_HOST
+ LM_UINT16 Reserved;
+ LM_UINT16 VlanTag;
+#else /* BIG_ENDIAN_HOST */
+ LM_UINT16 VlanTag;
+ LM_UINT16 Reserved;
+#endif
+ } s2;
+
+ LM_UINT32 VlanTag;
+ } u2;
+} T3_SND_BD, *PT3_SND_BD;
+
+
+/* Send buffer descriptor flags. */
+#define SND_BD_FLAG_TCP_UDP_CKSUM 0x0001
+#define SND_BD_FLAG_IP_CKSUM 0x0002
+#define SND_BD_FLAG_END 0x0004
+#define SND_BD_FLAG_IP_FRAG 0x0008
+#define SND_BD_FLAG_IP_FRAG_END 0x0010
+#define SND_BD_FLAG_VLAN_TAG 0x0040
+#define SND_BD_FLAG_COAL_NOW 0x0080
+#define SND_BD_FLAG_CPU_PRE_DMA 0x0100
+#define SND_BD_FLAG_CPU_POST_DMA 0x0200
+#define SND_BD_FLAG_INSERT_SRC_ADDR 0x1000
+#define SND_BD_FLAG_CHOOSE_SRC_ADDR 0x6000
+#define SND_BD_FLAG_DONT_GEN_CRC 0x8000
+
+/* MBUFs */
+typedef struct T3_MBUF_FRAME_DESC {
+#ifdef BIG_ENDIAN_HOST
+ LM_UINT32 status_control;
+ union {
+ struct {
+ LM_UINT8 cqid;
+ LM_UINT8 reserved1;
+ LM_UINT16 length;
+ }s1;
+ LM_UINT32 word;
+ }u1;
+ union {
+ struct
+ {
+ LM_UINT16 ip_hdr_start;
+ LM_UINT16 tcp_udp_hdr_start;
+ }s2;
+
+ LM_UINT32 word;
+ }u2;
+
+ union {
+ struct {
+ LM_UINT16 data_start;
+ LM_UINT16 vlan_id;
+ }s3;
+
+ LM_UINT32 word;
+ }u3;
+
+ union {
+ struct {
+ LM_UINT16 ip_checksum;
+ LM_UINT16 tcp_udp_checksum;
+ }s4;
+
+ LM_UINT32 word;
+ }u4;
+
+ union {
+ struct {
+ LM_UINT16 pseudo_checksum;
+ LM_UINT16 checksum_status;
+ }s5;
+
+ LM_UINT32 word;
+ }u5;
+
+ union {
+ struct {
+ LM_UINT16 rule_match;
+ LM_UINT8 class;
+ LM_UINT8 rupt;
+ }s6;
+
+ LM_UINT32 word;
+ }u6;
+
+ union {
+ struct {
+ LM_UINT16 reserved2;
+ LM_UINT16 mbuf_num;
+ }s7;
+
+ LM_UINT32 word;
+ }u7;
+
+ LM_UINT32 reserved3;
+ LM_UINT32 reserved4;
+#else
+ LM_UINT32 status_control;
+ union {
+ struct {
+ LM_UINT16 length;
+ LM_UINT8 reserved1;
+ LM_UINT8 cqid;
+ }s1;
+ LM_UINT32 word;
+ }u1;
+ union {
+ struct
+ {
+ LM_UINT16 tcp_udp_hdr_start;
+ LM_UINT16 ip_hdr_start;
+ }s2;
+
+ LM_UINT32 word;
+ }u2;
+
+ union {
+ struct {
+ LM_UINT16 vlan_id;
+ LM_UINT16 data_start;
+ }s3;
+
+ LM_UINT32 word;
+ }u3;
+
+ union {
+ struct {
+ LM_UINT16 tcp_udp_checksum;
+ LM_UINT16 ip_checksum;
+ }s4;
+
+ LM_UINT32 word;
+ }u4;
+
+ union {
+ struct {
+ LM_UINT16 checksum_status;
+ LM_UINT16 pseudo_checksum;
+ }s5;
+
+ LM_UINT32 word;
+ }u5;
+
+ union {
+ struct {
+ LM_UINT8 rupt;
+ LM_UINT8 class;
+ LM_UINT16 rule_match;
+ }s6;
+
+ LM_UINT32 word;
+ }u6;
+
+ union {
+ struct {
+ LM_UINT16 mbuf_num;
+ LM_UINT16 reserved2;
+ }s7;
+
+ LM_UINT32 word;
+ }u7;
+
+ LM_UINT32 reserved3;
+ LM_UINT32 reserved4;
+#endif
+}T3_MBUF_FRAME_DESC,*PT3_MBUF_FRAME_DESC;
+
+typedef struct T3_MBUF_HDR {
+ union {
+ struct {
+ unsigned int C:1;
+ unsigned int F:1;
+ unsigned int reserved1:7;
+ unsigned int next_mbuf:16;
+ unsigned int length:7;
+ }s1;
+
+ LM_UINT32 word;
+ }u1;
+
+ LM_UINT32 next_frame_ptr;
+}T3_MBUF_HDR, *PT3_MBUF_HDR;
+
+typedef struct T3_MBUF
+{
+ T3_MBUF_HDR hdr;
+ union
+ {
+ struct {
+ T3_MBUF_FRAME_DESC frame_hdr;
+ LM_UINT32 data[20];
+ }s1;
+
+ struct {
+ LM_UINT32 data[30];
+ }s2;
+ }body;
+}T3_MBUF, *PT3_MBUF;
+
+#define T3_MBUF_BASE (T3_NIC_MBUF_POOL_ADDR >> 7)
+#define T3_MBUF_END ((T3_NIC_MBUF_POOL_ADDR + T3_NIC_MBUF_POOL_SIZE) >> 7)
+
+
+
+/******************************************************************************/
+/* Statistics block. */
+/******************************************************************************/
+
+typedef struct {
+ LM_UINT8 Reserved0[0x400-0x300];
+
+ /* Statistics maintained by Receive MAC. */
+ T3_64BIT_REGISTER ifHCInOctets;
+ T3_64BIT_REGISTER Reserved1;
+ T3_64BIT_REGISTER etherStatsFragments;
+ T3_64BIT_REGISTER ifHCInUcastPkts;
+ T3_64BIT_REGISTER ifHCInMulticastPkts;
+ T3_64BIT_REGISTER ifHCInBroadcastPkts;
+ T3_64BIT_REGISTER dot3StatsFCSErrors;
+ T3_64BIT_REGISTER dot3StatsAlignmentErrors;
+ T3_64BIT_REGISTER xonPauseFramesReceived;
+ T3_64BIT_REGISTER xoffPauseFramesReceived;
+ T3_64BIT_REGISTER macControlFramesReceived;
+ T3_64BIT_REGISTER xoffStateEntered;
+ T3_64BIT_REGISTER dot3StatsFramesTooLong;
+ T3_64BIT_REGISTER etherStatsJabbers;
+ T3_64BIT_REGISTER etherStatsUndersizePkts;
+ T3_64BIT_REGISTER inRangeLengthError;
+ T3_64BIT_REGISTER outRangeLengthError;
+ T3_64BIT_REGISTER etherStatsPkts64Octets;
+ T3_64BIT_REGISTER etherStatsPkts65Octetsto127Octets;
+ T3_64BIT_REGISTER etherStatsPkts128Octetsto255Octets;
+ T3_64BIT_REGISTER etherStatsPkts256Octetsto511Octets;
+ T3_64BIT_REGISTER etherStatsPkts512Octetsto1023Octets;
+ T3_64BIT_REGISTER etherStatsPkts1024Octetsto1522Octets;
+ T3_64BIT_REGISTER etherStatsPkts1523Octetsto2047Octets;
+ T3_64BIT_REGISTER etherStatsPkts2048Octetsto4095Octets;
+ T3_64BIT_REGISTER etherStatsPkts4096Octetsto8191Octets;
+ T3_64BIT_REGISTER etherStatsPkts8192Octetsto9022Octets;
+
+ T3_64BIT_REGISTER Unused1[37];
+
+ /* Statistics maintained by Transmit MAC. */
+ T3_64BIT_REGISTER ifHCOutOctets;
+ T3_64BIT_REGISTER Reserved2;
+ T3_64BIT_REGISTER etherStatsCollisions;
+ T3_64BIT_REGISTER outXonSent;
+ T3_64BIT_REGISTER outXoffSent;
+ T3_64BIT_REGISTER flowControlDone;
+ T3_64BIT_REGISTER dot3StatsInternalMacTransmitErrors;
+ T3_64BIT_REGISTER dot3StatsSingleCollisionFrames;
+ T3_64BIT_REGISTER dot3StatsMultipleCollisionFrames;
+ T3_64BIT_REGISTER dot3StatsDeferredTransmissions;
+ T3_64BIT_REGISTER Reserved3;
+ T3_64BIT_REGISTER dot3StatsExcessiveCollisions;
+ T3_64BIT_REGISTER dot3StatsLateCollisions;
+ T3_64BIT_REGISTER dot3Collided2Times;
+ T3_64BIT_REGISTER dot3Collided3Times;
+ T3_64BIT_REGISTER dot3Collided4Times;
+ T3_64BIT_REGISTER dot3Collided5Times;
+ T3_64BIT_REGISTER dot3Collided6Times;
+ T3_64BIT_REGISTER dot3Collided7Times;
+ T3_64BIT_REGISTER dot3Collided8Times;
+ T3_64BIT_REGISTER dot3Collided9Times;
+ T3_64BIT_REGISTER dot3Collided10Times;
+ T3_64BIT_REGISTER dot3Collided11Times;
+ T3_64BIT_REGISTER dot3Collided12Times;
+ T3_64BIT_REGISTER dot3Collided13Times;
+ T3_64BIT_REGISTER dot3Collided14Times;
+ T3_64BIT_REGISTER dot3Collided15Times;
+ T3_64BIT_REGISTER ifHCOutUcastPkts;
+ T3_64BIT_REGISTER ifHCOutMulticastPkts;
+ T3_64BIT_REGISTER ifHCOutBroadcastPkts;
+ T3_64BIT_REGISTER dot3StatsCarrierSenseErrors;
+ T3_64BIT_REGISTER ifOutDiscards;
+ T3_64BIT_REGISTER ifOutErrors;
+
+ T3_64BIT_REGISTER Unused2[31];
+
+ /* Statistics maintained by Receive List Placement. */
+ T3_64BIT_REGISTER COSIfHCInPkts[16];
+ T3_64BIT_REGISTER COSFramesDroppedDueToFilters;
+ T3_64BIT_REGISTER nicDmaWriteQueueFull;
+ T3_64BIT_REGISTER nicDmaWriteHighPriQueueFull;
+ T3_64BIT_REGISTER nicNoMoreRxBDs;
+ T3_64BIT_REGISTER ifInDiscards;
+ T3_64BIT_REGISTER ifInErrors;
+ T3_64BIT_REGISTER nicRecvThresholdHit;
+
+ T3_64BIT_REGISTER Unused3[9];
+
+ /* Statistics maintained by Send Data Initiator. */
+ T3_64BIT_REGISTER COSIfHCOutPkts[16];
+ T3_64BIT_REGISTER nicDmaReadQueueFull;
+ T3_64BIT_REGISTER nicDmaReadHighPriQueueFull;
+ T3_64BIT_REGISTER nicSendDataCompQueueFull;
+
+ /* Statistics maintained by Host Coalescing. */
+ T3_64BIT_REGISTER nicRingSetSendProdIndex;
+ T3_64BIT_REGISTER nicRingStatusUpdate;
+ T3_64BIT_REGISTER nicInterrupts;
+ T3_64BIT_REGISTER nicAvoidedInterrupts;
+ T3_64BIT_REGISTER nicSendThresholdHit;
+
+ LM_UINT8 Reserved4[0xb00-0x9c0];
+} T3_STATS_BLOCK, *PT3_STATS_BLOCK;
+
+
+
+/******************************************************************************/
+/* PCI configuration registers. */
+/******************************************************************************/
+
+typedef struct {
+ T3_16BIT_REGISTER VendorId;
+ T3_16BIT_REGISTER DeviceId;
+
+ T3_16BIT_REGISTER Command;
+ T3_16BIT_REGISTER Status;
+
+ T3_32BIT_REGISTER ClassCodeRevId;
+
+ T3_8BIT_REGISTER CacheLineSize;
+ T3_8BIT_REGISTER LatencyTimer;
+ T3_8BIT_REGISTER HeaderType;
+ T3_8BIT_REGISTER Bist;
+
+ T3_32BIT_REGISTER MemBaseAddrLow;
+ T3_32BIT_REGISTER MemBaseAddrHigh;
+
+ LM_UINT8 Unused1[20];
+
+ T3_16BIT_REGISTER SubsystemVendorId;
+ T3_16BIT_REGISTER SubsystemId;
+
+ T3_32BIT_REGISTER RomBaseAddr;
+
+ T3_8BIT_REGISTER PciXCapiblityPtr;
+ LM_UINT8 Unused2[7];
+
+ T3_8BIT_REGISTER IntLine;
+ T3_8BIT_REGISTER IntPin;
+ T3_8BIT_REGISTER MinGnt;
+ T3_8BIT_REGISTER MaxLat;
+
+ T3_8BIT_REGISTER PciXCapabilities;
+ T3_8BIT_REGISTER PmCapabilityPtr;
+ T3_16BIT_REGISTER PciXCommand;
+
+ T3_32BIT_REGISTER PciXStatus;
+
+ T3_8BIT_REGISTER PmCapabilityId;
+ T3_8BIT_REGISTER VpdCapabilityPtr;
+ T3_16BIT_REGISTER PmCapabilities;
+
+ T3_16BIT_REGISTER PmCtrlStatus;
+ #define PM_CTRL_PME_STATUS BIT_15
+ #define PM_CTRL_PME_ENABLE BIT_8
+ #define PM_CTRL_PME_POWER_STATE_D0 0
+ #define PM_CTRL_PME_POWER_STATE_D1 1
+ #define PM_CTRL_PME_POWER_STATE_D2 2
+ #define PM_CTRL_PME_POWER_STATE_D3H 3
+
+ T3_8BIT_REGISTER BridgeSupportExt;
+ T3_8BIT_REGISTER PmData;
+
+ T3_8BIT_REGISTER VpdCapabilityId;
+ T3_8BIT_REGISTER MsiCapabilityPtr;
+ T3_16BIT_REGISTER VpdAddrFlag;
+ #define VPD_FLAG_WRITE (1 << 15)
+ #define VPD_FLAG_RW_MASK (1 << 15)
+ #define VPD_FLAG_READ 0
+
+
+ T3_32BIT_REGISTER VpdData;
+
+ T3_8BIT_REGISTER MsiCapabilityId;
+ T3_8BIT_REGISTER NextCapabilityPtr;
+ T3_16BIT_REGISTER MsiCtrl;
+ #define MSI_CTRL_64BIT_CAP (1 << 7)
+ #define MSI_CTRL_MSG_ENABLE(x) (x << 4)
+ #define MSI_CTRL_MSG_CAP(x) (x << 1)
+ #define MSI_CTRL_ENABLE (1 << 0)
+
+
+ T3_32BIT_REGISTER MsiAddrLow;
+ T3_32BIT_REGISTER MsiAddrHigh;
+
+ T3_16BIT_REGISTER MsiData;
+ T3_16BIT_REGISTER Unused3;
+
+ T3_32BIT_REGISTER MiscHostCtrl;
+ #define MISC_HOST_CTRL_CLEAR_INT BIT_0
+ #define MISC_HOST_CTRL_MASK_PCI_INT BIT_1
+ #define MISC_HOST_CTRL_ENABLE_ENDIAN_BYTE_SWAP BIT_2
+ #define MISC_HOST_CTRL_ENABLE_ENDIAN_WORD_SWAP BIT_3
+ #define MISC_HOST_CTRL_ENABLE_PCI_STATE_REG_RW BIT_4
+ #define MISC_HOST_CTRL_ENABLE_CLK_REG_RW BIT_5
+ #define MISC_HOST_CTRL_ENABLE_REG_WORD_SWAP BIT_6
+ #define MISC_HOST_CTRL_ENABLE_INDIRECT_ACCESS BIT_7
+ #define MISC_HOST_CTRL_ENABLE_INT_MASK_MODE BIT_8
+ #define MISC_HOST_CTRL_ENABLE_TAGGED_STATUS_MODE BIT_9
+
+ T3_32BIT_REGISTER DmaReadWriteCtrl;
+ #define DMA_CTRL_WRITE_BOUNDARY_MASK (BIT_11 | BIT_12 | BIT_13)
+ #define DMA_CTRL_WRITE_BOUNDARY_DISABLE 0
+ #define DMA_CTRL_WRITE_BOUNDARY_16 BIT_11
+ #define DMA_CTRL_WRITE_BOUNDARY_32 BIT_12
+ #define DMA_CTRL_WRITE_BOUNDARY_64 (BIT_12 | BIT_11)
+ #define DMA_CTRL_WRITE_BOUNDARY_128 BIT_13
+ #define DMA_CTRL_WRITE_BOUNDARY_256 (BIT_13 | BIT_11)
+ #define DMA_CTRL_WRITE_BOUNDARY_512 (BIT_13 | BIT_12)
+ #define DMA_CTRL_WRITE_BOUNDARY_1024 (BIT_13 | BIT_12 | BIT_11)
+ #define DMA_CTRL_WRITE_ONE_DMA_AT_ONCE BIT_14
+
+
+ T3_32BIT_REGISTER PciState;
+ #define T3_PCI_STATE_FORCE_PCI_RESET BIT_0
+ #define T3_PCI_STATE_INTERRUPT_NOT_ACTIVE BIT_1
+ #define T3_PCI_STATE_NOT_PCI_X_BUS BIT_2
+ #define T3_PCI_STATE_HIGH_BUS_SPEED BIT_3
+ #define T3_PCI_STATE_32BIT_PCI_BUS BIT_4
+ #define T3_PCI_STATE_PCI_ROM_ENABLE BIT_5
+ #define T3_PCI_STATE_PCI_ROM_RETRY_ENABLE BIT_6
+ #define T3_PCI_STATE_FLAT_VIEW BIT_8
+ #define T3_PCI_STATE_RETRY_SAME_DMA BIT_13
+
+ T3_32BIT_REGISTER ClockCtrl;
+ #define T3_PCI_CLKCTRL_TXCPU_CLK_DISABLE BIT_11
+ #define T3_PCI_CLKCTRL_RXCPU_CLK_DISABLE BIT_10
+ #define T3_PCI_CLKCTRL_CORE_CLK_DISABLE BIT_9
+
+ T3_32BIT_REGISTER RegBaseAddr;
+
+ T3_32BIT_REGISTER MemWindowBaseAddr;
+
+#ifdef NIC_CPU_VIEW
+ /* These registers are ONLY visible to NIC CPU */
+ T3_32BIT_REGISTER PowerConsumed;
+ T3_32BIT_REGISTER PowerDissipated;
+#else /* NIC_CPU_VIEW */
+ T3_32BIT_REGISTER RegData;
+ T3_32BIT_REGISTER MemWindowData;
+#endif /* !NIC_CPU_VIEW */
+
+ T3_32BIT_REGISTER ModeCtrl;
+
+ T3_32BIT_REGISTER MiscCfg;
+
+ T3_32BIT_REGISTER MiscLocalCtrl;
+
+ T3_32BIT_REGISTER Unused4;
+
+ /* NOTE: Big/Little-endian clarification needed. Are these register */
+ /* in big or little endian formate. */
+ T3_64BIT_REGISTER StdRingProdIdx;
+ T3_64BIT_REGISTER RcvRetRingConIdx;
+ T3_64BIT_REGISTER SndProdIdx;
+
+ LM_UINT8 Unused5[80];
+} T3_PCI_CONFIGURATION, *PT3_PCI_CONFIGURATION;
+
+#define PCIX_CMD_MAX_SPLIT_MASK 0x0070
+#define PCIX_CMD_MAX_SPLIT_SHL 4
+#define PCIX_CMD_MAX_BURST_MASK 0x000c
+#define PCIX_CMD_MAX_BURST_SHL 2
+#define PCIX_CMD_MAX_BURST_CPIOB 2
+
+/******************************************************************************/
+/* Mac control registers. */
+/******************************************************************************/
+
+typedef struct {
+ /* MAC mode control. */
+ T3_32BIT_REGISTER Mode;
+ #define MAC_MODE_GLOBAL_RESET BIT_0
+ #define MAC_MODE_HALF_DUPLEX BIT_1
+ #define MAC_MODE_PORT_MODE_MASK (BIT_2 | BIT_3)
+ #define MAC_MODE_PORT_MODE_TBI (BIT_2 | BIT_3)
+ #define MAC_MODE_PORT_MODE_GMII BIT_3
+ #define MAC_MODE_PORT_MODE_MII BIT_2
+ #define MAC_MODE_PORT_MODE_NONE BIT_NONE
+ #define MAC_MODE_PORT_INTERNAL_LOOPBACK BIT_4
+ #define MAC_MODE_TAGGED_MAC_CONTROL BIT_7
+ #define MAC_MODE_TX_BURSTING BIT_8
+ #define MAC_MODE_MAX_DEFER BIT_9
+ #define MAC_MODE_LINK_POLARITY BIT_10
+ #define MAC_MODE_ENABLE_RX_STATISTICS BIT_11
+ #define MAC_MODE_CLEAR_RX_STATISTICS BIT_12
+ #define MAC_MODE_FLUSH_RX_STATISTICS BIT_13
+ #define MAC_MODE_ENABLE_TX_STATISTICS BIT_14
+ #define MAC_MODE_CLEAR_TX_STATISTICS BIT_15
+ #define MAC_MODE_FLUSH_TX_STATISTICS BIT_16
+ #define MAC_MODE_SEND_CONFIGS BIT_17
+ #define MAC_MODE_DETECT_MAGIC_PACKET_ENABLE BIT_18
+ #define MAC_MODE_ACPI_POWER_ON_ENABLE BIT_19
+ #define MAC_MODE_ENABLE_MIP BIT_20
+ #define MAC_MODE_ENABLE_TDE BIT_21
+ #define MAC_MODE_ENABLE_RDE BIT_22
+ #define MAC_MODE_ENABLE_FHDE BIT_23
+
+ /* MAC status */
+ T3_32BIT_REGISTER Status;
+ #define MAC_STATUS_PCS_SYNCED BIT_0
+ #define MAC_STATUS_SIGNAL_DETECTED BIT_1
+ #define MAC_STATUS_RECEIVING_CFG BIT_2
+ #define MAC_STATUS_CFG_CHANGED BIT_3
+ #define MAC_STATUS_SYNC_CHANGED BIT_4
+ #define MAC_STATUS_PORT_DECODE_ERROR BIT_10
+ #define MAC_STATUS_LINK_STATE_CHANGED BIT_12
+ #define MAC_STATUS_MI_COMPLETION BIT_22
+ #define MAC_STATUS_MI_INTERRUPT BIT_23
+ #define MAC_STATUS_AP_ERROR BIT_24
+ #define MAC_STATUS_ODI_ERROR BIT_25
+ #define MAC_STATUS_RX_STATS_OVERRUN BIT_26
+ #define MAC_STATUS_TX_STATS_OVERRUN BIT_27
+
+ /* Event Enable */
+ T3_32BIT_REGISTER MacEvent;
+ #define MAC_EVENT_ENABLE_PORT_DECODE_ERR BIT_10
+ #define MAC_EVENT_ENABLE_LINK_STATE_CHANGED_ATTN BIT_12
+ #define MAC_EVENT_ENABLE_MI_COMPLETION BIT_22
+ #define MAC_EVENT_ENABLE_MI_INTERRUPT BIT_23
+ #define MAC_EVENT_ENABLE_AP_ERROR BIT_24
+ #define MAC_EVENT_ENABLE_ODI_ERROR BIT_25
+ #define MAC_EVENT_ENABLE_RX_STATS_OVERRUN BIT_26
+ #define MAC_EVENT_ENABLE_TX_STATS_OVERRUN BIT_27
+
+ /* Led control. */
+ T3_32BIT_REGISTER LedCtrl;
+ #define LED_CTRL_OVERRIDE_LINK_LED BIT_0
+ #define LED_CTRL_1000MBPS_LED_ON BIT_1
+ #define LED_CTRL_100MBPS_LED_ON BIT_2
+ #define LED_CTRL_10MBPS_LED_ON BIT_3
+ #define LED_CTRL_OVERRIDE_TRAFFIC_LED BIT_4
+ #define LED_CTRL_BLINK_TRAFFIC_LED BIT_5
+ #define LED_CTRL_TRAFFIC_LED BIT_6
+ #define LED_CTRL_1000MBPS_LED_STATUS BIT_7
+ #define LED_CTRL_100MBPS_LED_STATUS BIT_8
+ #define LED_CTRL_10MBPS_LED_STATUS BIT_9
+ #define LED_CTRL_TRAFFIC_LED_STATUS BIT_10
+ #define LED_CTRL_MAC_MODE BIT_NONE
+ #define LED_CTRL_PHY_MODE_1 BIT_11
+ #define LED_CTRL_PHY_MODE_2 BIT_12
+ #define LED_CTRL_BLINK_RATE_MASK 0x7ff80000
+ #define LED_CTRL_OVERRIDE_BLINK_PERIOD BIT_19
+ #define LED_CTRL_OVERRIDE_BLINK_RATE BIT_31
+
+ /* MAC addresses. */
+ struct {
+ T3_32BIT_REGISTER High; /* Upper 2 bytes. */
+ T3_32BIT_REGISTER Low; /* Lower 4 bytes. */
+ } MacAddr[4];
+
+ /* ACPI Mbuf pointer. */
+ T3_32BIT_REGISTER AcpiMbufPtr;
+
+ /* ACPI Length and Offset. */
+ T3_32BIT_REGISTER AcpiLengthOffset;
+ #define ACPI_LENGTH_MASK 0xffff
+ #define ACPI_OFFSET_MASK 0x0fff0000
+ #define ACPI_LENGTH(x) x
+ #define ACPI_OFFSET(x) ((x) << 16)
+
+ /* Transmit random backoff. */
+ T3_32BIT_REGISTER TxBackoffSeed;
+ #define MAC_TX_BACKOFF_SEED_MASK 0x3ff
+
+ /* Receive MTU */
+ T3_32BIT_REGISTER MtuSize;
+ #define MAC_RX_MTU_MASK 0xffff
+
+ /* Gigabit PCS Test. */
+ T3_32BIT_REGISTER PcsTest;
+ #define MAC_PCS_TEST_DATA_PATTERN_MASK 0x0fffff
+ #define MAC_PCS_TEST_ENABLE BIT_20
+
+ /* Transmit Gigabit Auto-Negotiation. */
+ T3_32BIT_REGISTER TxAutoNeg;
+ #define MAC_AN_TX_AN_DATA_MASK 0xffff
+
+ /* Receive Gigabit Auto-Negotiation. */
+ T3_32BIT_REGISTER RxAutoNeg;
+ #define MAC_AN_RX_AN_DATA_MASK 0xffff
+
+ /* MI Communication. */
+ T3_32BIT_REGISTER MiCom;
+ #define MI_COM_CMD_MASK (BIT_26 | BIT_27)
+ #define MI_COM_CMD_WRITE BIT_26
+ #define MI_COM_CMD_READ BIT_27
+ #define MI_COM_READ_FAILED BIT_28
+ #define MI_COM_START BIT_29
+ #define MI_COM_BUSY BIT_29
+
+ #define MI_COM_PHY_ADDR_MASK 0x1f
+ #define MI_COM_FIRST_PHY_ADDR_BIT 21
+
+ #define MI_COM_PHY_REG_ADDR_MASK 0x1f
+ #define MI_COM_FIRST_PHY_REG_ADDR_BIT 16
+
+ #define MI_COM_PHY_DATA_MASK 0xffff
+
+ /* MI Status. */
+ T3_32BIT_REGISTER MiStatus;
+ #define MI_STATUS_ENABLE_LINK_STATUS_ATTN BIT_0
+
+ /* MI Mode. */
+ T3_32BIT_REGISTER MiMode;
+ #define MI_MODE_CLOCK_SPEED_10MHZ BIT_0
+ #define MI_MODE_USE_SHORT_PREAMBLE BIT_1
+ #define MI_MODE_AUTO_POLLING_ENABLE BIT_4
+ #define MI_MODE_CORE_CLOCK_SPEED_62MHZ BIT_15
+
+ /* Auto-polling status. */
+ T3_32BIT_REGISTER AutoPollStatus;
+ #define AUTO_POLL_ERROR BIT_0
+
+ /* Transmit MAC mode. */
+ T3_32BIT_REGISTER TxMode;
+ #define TX_MODE_RESET BIT_0
+ #define TX_MODE_ENABLE BIT_1
+ #define TX_MODE_ENABLE_FLOW_CONTROL BIT_4
+ #define TX_MODE_ENABLE_BIG_BACKOFF BIT_5
+ #define TX_MODE_ENABLE_LONG_PAUSE BIT_6
+
+ /* Transmit MAC status. */
+ T3_32BIT_REGISTER TxStatus;
+ #define TX_STATUS_RX_CURRENTLY_XOFFED BIT_0
+ #define TX_STATUS_SENT_XOFF BIT_1
+ #define TX_STATUS_SENT_XON BIT_2
+ #define TX_STATUS_LINK_UP BIT_3
+ #define TX_STATUS_ODI_UNDERRUN BIT_4
+ #define TX_STATUS_ODI_OVERRUN BIT_5
+
+ /* Transmit MAC length. */
+ T3_32BIT_REGISTER TxLengths;
+ #define TX_LEN_SLOT_TIME_MASK 0xff
+ #define TX_LEN_IPG_MASK 0x0f00
+ #define TX_LEN_IPG_CRS_MASK (BIT_12 | BIT_13)
+
+ /* Receive MAC mode. */
+ T3_32BIT_REGISTER RxMode;
+ #define RX_MODE_RESET BIT_0
+ #define RX_MODE_ENABLE BIT_1
+ #define RX_MODE_ENABLE_FLOW_CONTROL BIT_2
+ #define RX_MODE_KEEP_MAC_CONTROL BIT_3
+ #define RX_MODE_KEEP_PAUSE BIT_4
+ #define RX_MODE_ACCEPT_OVERSIZED BIT_5
+ #define RX_MODE_ACCEPT_RUNTS BIT_6
+ #define RX_MODE_LENGTH_CHECK BIT_7
+ #define RX_MODE_PROMISCUOUS_MODE BIT_8
+ #define RX_MODE_NO_CRC_CHECK BIT_9
+ #define RX_MODE_KEEP_VLAN_TAG BIT_10
+
+ /* Receive MAC status. */
+ T3_32BIT_REGISTER RxStatus;
+ #define RX_STATUS_REMOTE_TRANSMITTER_XOFFED BIT_0
+ #define RX_STATUS_XOFF_RECEIVED BIT_1
+ #define RX_STATUS_XON_RECEIVED BIT_2
+
+ /* Hash registers. */
+ T3_32BIT_REGISTER HashReg[4];
+
+ /* Receive placement rules registers. */
+ struct {
+ T3_32BIT_REGISTER Rule;
+ T3_32BIT_REGISTER Value;
+ } RcvRules[16];
+
+ #define RCV_DISABLE_RULE_MASK 0x7fffffff
+
+ #define RCV_RULE1_REJECT_BROADCAST_IDX 0x00
+ #define REJECT_BROADCAST_RULE1_RULE 0xc2000000
+ #define REJECT_BROADCAST_RULE1_VALUE 0xffffffff
+
+ #define RCV_RULE2_REJECT_BROADCAST_IDX 0x01
+ #define REJECT_BROADCAST_RULE2_RULE 0x86000004
+ #define REJECT_BROADCAST_RULE2_VALUE 0xffffffff
+
+#if INCLUDE_5701_AX_FIX
+ #define RCV_LAST_RULE_IDX 0x04
+#else
+ #define RCV_LAST_RULE_IDX 0x02
+#endif
+
+ T3_32BIT_REGISTER RcvRuleCfg;
+ #define RX_RULE_DEFAULT_CLASS (1 << 3)
+
+ LM_UINT8 Reserved1[140];
+
+ T3_32BIT_REGISTER SerdesCfg;
+ T3_32BIT_REGISTER SerdesStatus;
+
+ LM_UINT8 Reserved2[104];
+
+ volatile LM_UINT8 TxMacState[16];
+ volatile LM_UINT8 RxMacState[20];
+
+ LM_UINT8 Reserved3[476];
+
+ T3_32BIT_REGISTER RxStats[26];
+
+ LM_UINT8 Reserved4[24];
+
+ T3_32BIT_REGISTER TxStats[28];
+
+ LM_UINT8 Reserved5[784];
+} T3_MAC_CONTROL, *PT3_MAC_CONTROL;
+
+
+
+/******************************************************************************/
+/* Send data initiator control registers. */
+/******************************************************************************/
+
+typedef struct {
+ T3_32BIT_REGISTER Mode;
+ #define T3_SND_DATA_IN_MODE_RESET BIT_0
+ #define T3_SND_DATA_IN_MODE_ENABLE BIT_1
+ #define T3_SND_DATA_IN_MODE_STATS_OFLW_ATTN_ENABLE BIT_2
+
+ T3_32BIT_REGISTER Status;
+ #define T3_SND_DATA_IN_STATUS_STATS_OFLW_ATTN BIT_2
+
+ T3_32BIT_REGISTER StatsCtrl;
+ #define T3_SND_DATA_IN_STATS_CTRL_ENABLE BIT_0
+ #define T3_SND_DATA_IN_STATS_CTRL_FASTER_UPDATE BIT_1
+ #define T3_SND_DATA_IN_STATS_CTRL_CLEAR BIT_2
+ #define T3_SND_DATA_IN_STATS_CTRL_FLUSH BIT_3
+ #define T3_SND_DATA_IN_STATS_CTRL_FORCE_ZERO BIT_4
+
+ T3_32BIT_REGISTER StatsEnableMask;
+ T3_32BIT_REGISTER StatsIncMask;
+
+ LM_UINT8 Reserved[108];
+
+ T3_32BIT_REGISTER ClassOfServCnt[16];
+ T3_32BIT_REGISTER DmaReadQFullCnt;
+ T3_32BIT_REGISTER DmaPriorityReadQFullCnt;
+ T3_32BIT_REGISTER SdcQFullCnt;
+
+ T3_32BIT_REGISTER NicRingSetSendProdIdxCnt;
+ T3_32BIT_REGISTER StatusUpdatedCnt;
+ T3_32BIT_REGISTER InterruptsCnt;
+ T3_32BIT_REGISTER AvoidInterruptsCnt;
+ T3_32BIT_REGISTER SendThresholdHitCnt;
+
+ /* Unused space. */
+ LM_UINT8 Unused[800];
+} T3_SEND_DATA_INITIATOR, *PT3_SEND_DATA_INITIATOR;
+
+
+
+/******************************************************************************/
+/* Send data completion control registers. */
+/******************************************************************************/
+
+typedef struct {
+ T3_32BIT_REGISTER Mode;
+ #define SND_DATA_COMP_MODE_RESET BIT_0
+ #define SND_DATA_COMP_MODE_ENABLE BIT_1
+
+ /* Unused space. */
+ LM_UINT8 Unused[1020];
+} T3_SEND_DATA_COMPLETION, *PT3_SEND_DATA_COMPLETION;
+
+
+
+/******************************************************************************/
+/* Send BD Ring Selector Control Registers. */
+/******************************************************************************/
+
+typedef struct {
+ T3_32BIT_REGISTER Mode;
+ #define SND_BD_SEL_MODE_RESET BIT_0
+ #define SND_BD_SEL_MODE_ENABLE BIT_1
+ #define SND_BD_SEL_MODE_ATTN_ENABLE BIT_2
+
+ T3_32BIT_REGISTER Status;
+ #define SND_BD_SEL_STATUS_ERROR_ATTN BIT_2
+
+ T3_32BIT_REGISTER HwDiag;
+
+ /* Unused space. */
+ LM_UINT8 Unused1[52];
+
+ /* Send BD Ring Selector Local NIC Send BD Consumer Index. */
+ T3_32BIT_REGISTER NicSendBdSelConIdx[16];
+
+ /* Unused space. */
+ LM_UINT8 Unused2[896];
+} T3_SEND_BD_SELECTOR, *PT3_SEND_BD_SELECTOR;
+
+
+
+/******************************************************************************/
+/* Send BD initiator control registers. */
+/******************************************************************************/
+
+typedef struct {
+ T3_32BIT_REGISTER Mode;
+ #define SND_BD_IN_MODE_RESET BIT_0
+ #define SND_BD_IN_MODE_ENABLE BIT_1
+ #define SND_BD_IN_MODE_ATTN_ENABLE BIT_2
+
+ T3_32BIT_REGISTER Status;
+ #define SND_BD_IN_STATUS_ERROR_ATTN BIT_2
+
+ /* Send BD initiator local NIC send BD producer index. */
+ T3_32BIT_REGISTER NicSendBdInProdIdx[16];
+
+ /* Unused space. */
+ LM_UINT8 Unused2[952];
+} T3_SEND_BD_INITIATOR, *PT3_SEND_BD_INITIATOR;
+
+
+
+/******************************************************************************/
+/* Send BD Completion Control. */
+/******************************************************************************/
+
+typedef struct {
+ T3_32BIT_REGISTER Mode;
+ #define SND_BD_COMP_MODE_RESET BIT_0
+ #define SND_BD_COMP_MODE_ENABLE BIT_1
+ #define SND_BD_COMP_MODE_ATTN_ENABLE BIT_2
+
+ /* Unused space. */
+ LM_UINT8 Unused2[1020];
+} T3_SEND_BD_COMPLETION, *PT3_SEND_BD_COMPLETION;
+
+
+
+/******************************************************************************/
+/* Receive list placement control registers. */
+/******************************************************************************/
+
+typedef struct {
+ /* Mode. */
+ T3_32BIT_REGISTER Mode;
+ #define RCV_LIST_PLMT_MODE_RESET BIT_0
+ #define RCV_LIST_PLMT_MODE_ENABLE BIT_1
+ #define RCV_LIST_PLMT_MODE_CLASS0_ATTN_ENABLE BIT_2
+ #define RCV_LIST_PLMT_MODE_MAPPING_OOR_ATTN_ENABLE BIT_3
+ #define RCV_LIST_PLMT_MODE_STATS_OFLOW_ATTN_ENABLE BIT_4
+
+ /* Status. */
+ T3_32BIT_REGISTER Status;
+ #define RCV_LIST_PLMT_STATUS_CLASS0_ATTN BIT_2
+ #define RCV_LIST_PLMT_STATUS_MAPPING_ATTN BIT_3
+ #define RCV_LIST_PLMT_STATUS_STATS_OFLOW_ATTN BIT_4
+
+ /* Receive selector list lock register. */
+ T3_32BIT_REGISTER Lock;
+ #define RCV_LIST_SEL_LOCK_REQUEST_MASK 0xffff
+ #define RCV_LIST_SEL_LOCK_GRANT_MASK 0xffff0000
+
+ /* Selector non-empty bits. */
+ T3_32BIT_REGISTER NonEmptyBits;
+ #define RCV_LIST_SEL_NON_EMPTY_MASK 0xffff
+
+ /* Receive list placement configuration register. */
+ T3_32BIT_REGISTER Config;
+
+ /* Receive List Placement statistics Control. */
+ T3_32BIT_REGISTER StatsCtrl;
+#define RCV_LIST_STATS_ENABLE BIT_0
+#define RCV_LIST_STATS_FAST_UPDATE BIT_1
+
+ /* Receive List Placement statistics Enable Mask. */
+ T3_32BIT_REGISTER StatsEnableMask;
+
+ /* Receive List Placement statistics Increment Mask. */
+ T3_32BIT_REGISTER StatsIncMask;
+
+ /* Unused space. */
+ LM_UINT8 Unused1[224];
+
+ struct {
+ T3_32BIT_REGISTER Head;
+ T3_32BIT_REGISTER Tail;
+ T3_32BIT_REGISTER Count;
+
+ /* Unused space. */
+ LM_UINT8 Unused[4];
+ } RcvSelectorList[16];
+
+ /* Local statistics counter. */
+ T3_32BIT_REGISTER ClassOfServCnt[16];
+
+ T3_32BIT_REGISTER DropDueToFilterCnt;
+ T3_32BIT_REGISTER DmaWriteQFullCnt;
+ T3_32BIT_REGISTER DmaHighPriorityWriteQFullCnt;
+ T3_32BIT_REGISTER NoMoreReceiveBdCnt;
+ T3_32BIT_REGISTER IfInDiscardsCnt;
+ T3_32BIT_REGISTER IfInErrorsCnt;
+ T3_32BIT_REGISTER RcvThresholdHitCnt;
+
+ /* Another unused space. */
+ LM_UINT8 Unused2[420];
+} T3_RCV_LIST_PLACEMENT, *PT3_RCV_LIST_PLACEMENT;
+
+
+
+/******************************************************************************/
+/* Receive Data and Receive BD Initiator Control. */
+/******************************************************************************/
+
+typedef struct {
+ /* Mode. */
+ T3_32BIT_REGISTER Mode;
+ #define RCV_DATA_BD_IN_MODE_RESET BIT_0
+ #define RCV_DATA_BD_IN_MODE_ENABLE BIT_1
+ #define RCV_DATA_BD_IN_MODE_JUMBO_BD_NEEDED BIT_2
+ #define RCV_DATA_BD_IN_MODE_FRAME_TOO_BIG BIT_3
+ #define RCV_DATA_BD_IN_MODE_INVALID_RING_SIZE BIT_4
+
+ /* Status. */
+ T3_32BIT_REGISTER Status;
+ #define RCV_DATA_BD_IN_STATUS_JUMBO_BD_NEEDED BIT_2
+ #define RCV_DATA_BD_IN_STATUS_FRAME_TOO_BIG BIT_3
+ #define RCV_DATA_BD_IN_STATUS_INVALID_RING_SIZE BIT_4
+
+ /* Split frame minium size. */
+ T3_32BIT_REGISTER SplitFrameMinSize;
+
+ /* Unused space. */
+ LM_UINT8 Unused1[0x2440-0x240c];
+
+ /* Receive RCBs. */
+ T3_RCB JumboRcvRcb;
+ T3_RCB StdRcvRcb;
+ T3_RCB MiniRcvRcb;
+
+ /* Receive Data and Receive BD Ring Initiator Local NIC Receive */
+ /* BD Consumber Index. */
+ T3_32BIT_REGISTER NicJumboConIdx;
+ T3_32BIT_REGISTER NicStdConIdx;
+ T3_32BIT_REGISTER NicMiniConIdx;
+
+ /* Unused space. */
+ LM_UINT8 Unused2[4];
+
+ /* Receive Data and Receive BD Initiator Local Receive Return ProdIdx. */
+ T3_32BIT_REGISTER RcvDataBdProdIdx[16];
+
+ /* Receive Data and Receive BD Initiator Hardware Diagnostic. */
+ T3_32BIT_REGISTER HwDiag;
+
+ /* Unused space. */
+ LM_UINT8 Unused3[828];
+} T3_RCV_DATA_BD_INITIATOR, *PT3_RCV_DATA_BD_INITIATOR;
+
+
+
+/******************************************************************************/
+/* Receive Data Completion Control Registes. */
+/******************************************************************************/
+
+typedef struct {
+ T3_32BIT_REGISTER Mode;
+ #define RCV_DATA_COMP_MODE_RESET BIT_0
+ #define RCV_DATA_COMP_MODE_ENABLE BIT_1
+ #define RCV_DATA_COMP_MODE_ATTN_ENABLE BIT_2
+
+ /* Unused spaced. */
+ LM_UINT8 Unused[1020];
+} T3_RCV_DATA_COMPLETION, *PT3_RCV_DATA_COMPLETION;
+
+
+
+/******************************************************************************/
+/* Receive BD Initiator Control. */
+/******************************************************************************/
+
+typedef struct {
+ T3_32BIT_REGISTER Mode;
+ #define RCV_BD_IN_MODE_RESET BIT_0
+ #define RCV_BD_IN_MODE_ENABLE BIT_1
+ #define RCV_BD_IN_MODE_BD_IN_DIABLED_RCB_ATTN_ENABLE BIT_2
+
+ T3_32BIT_REGISTER Status;
+ #define RCV_BD_IN_STATUS_BD_IN_DIABLED_RCB_ATTN BIT_2
+
+ T3_32BIT_REGISTER NicJumboRcvProdIdx;
+ T3_32BIT_REGISTER NicStdRcvProdIdx;
+ T3_32BIT_REGISTER NicMiniRcvProdIdx;
+
+ T3_32BIT_REGISTER MiniRcvThreshold;
+ T3_32BIT_REGISTER StdRcvThreshold;
+ T3_32BIT_REGISTER JumboRcvThreshold;
+
+ /* Unused space. */
+ LM_UINT8 Unused[992];
+} T3_RCV_BD_INITIATOR, *PT3_RCV_BD_INITIATOR;
+
+
+
+/******************************************************************************/
+/* Receive BD Completion Control Registers. */
+/******************************************************************************/
+
+typedef struct {
+ T3_32BIT_REGISTER Mode;
+ #define RCV_BD_COMP_MODE_RESET BIT_0
+ #define RCV_BD_COMP_MODE_ENABLE BIT_1
+ #define RCV_BD_COMP_MODE_ATTN_ENABLE BIT_2
+
+ T3_32BIT_REGISTER Status;
+ #define RCV_BD_COMP_STATUS_ERROR_ATTN BIT_2
+
+ T3_32BIT_REGISTER NicJumboRcvBdProdIdx;
+ T3_32BIT_REGISTER NicStdRcvBdProdIdx;
+ T3_32BIT_REGISTER NicMiniRcvBdProdIdx;
+
+ /* Unused space. */
+ LM_UINT8 Unused[1004];
+} T3_RCV_BD_COMPLETION, *PT3_RCV_BD_COMPLETION;
+
+
+
+/******************************************************************************/
+/* Receive list selector control register. */
+/******************************************************************************/
+
+typedef struct {
+ T3_32BIT_REGISTER Mode;
+ #define RCV_LIST_SEL_MODE_RESET BIT_0
+ #define RCV_LIST_SEL_MODE_ENABLE BIT_1
+ #define RCV_LIST_SEL_MODE_ATTN_ENABLE BIT_2
+
+ T3_32BIT_REGISTER Status;
+ #define RCV_LIST_SEL_STATUS_ERROR_ATTN BIT_2
+
+ /* Unused space. */
+ LM_UINT8 Unused[1016];
+} T3_RCV_LIST_SELECTOR, *PT3_RCV_LIST_SELECTOR;
+
+
+
+/******************************************************************************/
+/* Mbuf cluster free registers. */
+/******************************************************************************/
+
+typedef struct {
+ T3_32BIT_REGISTER Mode;
+#define MBUF_CLUSTER_FREE_MODE_RESET BIT_0
+#define MBUF_CLUSTER_FREE_MODE_ENABLE BIT_1
+
+ T3_32BIT_REGISTER Status;
+
+ /* Unused space. */
+ LM_UINT8 Unused[1016];
+} T3_MBUF_CLUSTER_FREE, *PT3_MBUF_CLUSTER_FREE;
+
+
+
+/******************************************************************************/
+/* Host coalescing control registers. */
+/******************************************************************************/
+
+typedef struct {
+ /* Mode. */
+ T3_32BIT_REGISTER Mode;
+ #define HOST_COALESCE_RESET BIT_0
+ #define HOST_COALESCE_ENABLE BIT_1
+ #define HOST_COALESCE_ATTN BIT_2
+ #define HOST_COALESCE_NOW BIT_3
+ #define HOST_COALESCE_FULL_STATUS_MODE BIT_NONE
+ #define HOST_COALESCE_64_BYTE_STATUS_MODE BIT_7
+ #define HOST_COALESCE_32_BYTE_STATUS_MODE BIT_8
+ #define HOST_COALESCE_CLEAR_TICKS_ON_RX_BD_EVENT BIT_9
+ #define HOST_COALESCE_CLEAR_TICKS_ON_TX_BD_EVENT BIT_10
+ #define HOST_COALESCE_NO_INT_ON_COALESCE_NOW_MODE BIT_11
+ #define HOST_COALESCE_NO_INT_ON_FORCE_DMAD_MODE BIT_12
+
+ /* Status. */
+ T3_32BIT_REGISTER Status;
+ #define HOST_COALESCE_ERROR_ATTN BIT_2
+
+ /* Receive coalescing ticks. */
+ T3_32BIT_REGISTER RxCoalescingTicks;
+
+ /* Send coalescing ticks. */
+ T3_32BIT_REGISTER TxCoalescingTicks;
+
+ /* Receive max coalesced frames. */
+ T3_32BIT_REGISTER RxMaxCoalescedFrames;
+
+ /* Send max coalesced frames. */
+ T3_32BIT_REGISTER TxMaxCoalescedFrames;
+
+ /* Receive coalescing ticks during interrupt. */
+ T3_32BIT_REGISTER RxCoalescedTickDuringInt;
+
+ /* Send coalescing ticks during interrupt. */
+ T3_32BIT_REGISTER TxCoalescedTickDuringInt;
+
+ /* Receive max coalesced frames during interrupt. */
+ T3_32BIT_REGISTER RxMaxCoalescedFramesDuringInt;
+
+ /* Send max coalesced frames during interrupt. */
+ T3_32BIT_REGISTER TxMaxCoalescedFramesDuringInt;
+
+ /* Statistics tick. */
+ T3_32BIT_REGISTER StatsCoalescingTicks;
+
+ /* Unused space. */
+ LM_UINT8 Unused2[4];
+
+ /* Statistics host address. */
+ T3_64BIT_REGISTER StatsBlkHostAddr;
+
+ /* Status block host address.*/
+ T3_64BIT_REGISTER StatusBlkHostAddr;
+
+ /* Statistics NIC address. */
+ T3_32BIT_REGISTER StatsBlkNicAddr;
+
+ /* Statust block NIC address. */
+ T3_32BIT_REGISTER StatusBlkNicAddr;
+
+ /* Flow attention registers. */
+ T3_32BIT_REGISTER FlowAttn;
+
+ /* Unused space. */
+ LM_UINT8 Unused3[4];
+
+ T3_32BIT_REGISTER NicJumboRcvBdConIdx;
+ T3_32BIT_REGISTER NicStdRcvBdConIdx;
+ T3_32BIT_REGISTER NicMiniRcvBdConIdx;
+
+ /* Unused space. */
+ LM_UINT8 Unused4[36];
+
+ T3_32BIT_REGISTER NicRetProdIdx[16];
+ T3_32BIT_REGISTER NicSndBdConIdx[16];
+
+ /* Unused space. */
+ LM_UINT8 Unused5[768];
+} T3_HOST_COALESCING, *PT3_HOST_COALESCING;
+
+
+
+/******************************************************************************/
+/* Memory arbiter registers. */
+/******************************************************************************/
+
+typedef struct {
+ T3_32BIT_REGISTER Mode;
+#define T3_MEM_ARBITER_MODE_RESET BIT_0
+#define T3_MEM_ARBITER_MODE_ENABLE BIT_1
+
+ T3_32BIT_REGISTER Status;
+
+ T3_32BIT_REGISTER ArbTrapAddrLow;
+ T3_32BIT_REGISTER ArbTrapAddrHigh;
+
+ /* Unused space. */
+ LM_UINT8 Unused[1008];
+} T3_MEM_ARBITER, *PT3_MEM_ARBITER;
+
+
+
+/******************************************************************************/
+/* Buffer manager control register. */
+/******************************************************************************/
+
+typedef struct {
+ T3_32BIT_REGISTER Mode;
+ #define BUFMGR_MODE_RESET BIT_0
+ #define BUFMGR_MODE_ENABLE BIT_1
+ #define BUFMGR_MODE_ATTN_ENABLE BIT_2
+ #define BUFMGR_MODE_BM_TEST BIT_3
+ #define BUFMGR_MODE_MBUF_LOW_ATTN_ENABLE BIT_4
+
+ T3_32BIT_REGISTER Status;
+ #define BUFMGR_STATUS_ERROR BIT_2
+ #define BUFMGR_STATUS_MBUF_LOW BIT_4
+
+ T3_32BIT_REGISTER MbufPoolAddr;
+ T3_32BIT_REGISTER MbufPoolSize;
+ T3_32BIT_REGISTER MbufReadDmaLowWaterMark;
+ T3_32BIT_REGISTER MbufMacRxLowWaterMark;
+ T3_32BIT_REGISTER MbufHighWaterMark;
+
+ T3_32BIT_REGISTER RxCpuMbufAllocReq;
+ #define BUFMGR_MBUF_ALLOC_BIT BIT_31
+ T3_32BIT_REGISTER RxCpuMbufAllocResp;
+ T3_32BIT_REGISTER TxCpuMbufAllocReq;
+ T3_32BIT_REGISTER TxCpuMbufAllocResp;
+
+ T3_32BIT_REGISTER DmaDescPoolAddr;
+ T3_32BIT_REGISTER DmaDescPoolSize;
+ T3_32BIT_REGISTER DmaLowWaterMark;
+ T3_32BIT_REGISTER DmaHighWaterMark;
+
+ T3_32BIT_REGISTER RxCpuDmaAllocReq;
+ T3_32BIT_REGISTER RxCpuDmaAllocResp;
+ T3_32BIT_REGISTER TxCpuDmaAllocReq;
+ T3_32BIT_REGISTER TxCpuDmaAllocResp;
+
+ T3_32BIT_REGISTER Hwdiag[3];
+
+ /* Unused space. */
+ LM_UINT8 Unused[936];
+} T3_BUFFER_MANAGER, *PT3_BUFFER_MANAGER;
+
+
+
+/******************************************************************************/
+/* Read DMA control registers. */
+/******************************************************************************/
+
+typedef struct {
+ T3_32BIT_REGISTER Mode;
+ #define DMA_READ_MODE_RESET BIT_0
+ #define DMA_READ_MODE_ENABLE BIT_1
+ #define DMA_READ_MODE_TARGET_ABORT_ATTN_ENABLE BIT_2
+ #define DMA_READ_MODE_MASTER_ABORT_ATTN_ENABLE BIT_3
+ #define DMA_READ_MODE_PARITY_ERROR_ATTN_ENABLE BIT_4
+ #define DMA_READ_MODE_ADDR_OVERFLOW_ATTN_ENABLE BIT_5
+ #define DMA_READ_MODE_FIFO_OVERRUN_ATTN_ENABLE BIT_6
+ #define DMA_READ_MODE_FIFO_UNDERRUN_ATTN_ENABLE BIT_7
+ #define DMA_READ_MODE_FIFO_OVERREAD_ATTN_ENABLE BIT_8
+ #define DMA_READ_MODE_LONG_READ_ATTN_ENABLE BIT_9
+ #define DMA_READ_MODE_SPLIT_ENABLE BIT_11
+ #define DMA_READ_MODE_SPLIT_RESET BIT_12
+
+ T3_32BIT_REGISTER Status;
+ #define DMA_READ_STATUS_TARGET_ABORT_ATTN BIT_2
+ #define DMA_READ_STATUS_MASTER_ABORT_ATTN BIT_3
+ #define DMA_READ_STATUS_PARITY_ERROR_ATTN BIT_4
+ #define DMA_READ_STATUS_ADDR_OVERFLOW_ATTN BIT_5
+ #define DMA_READ_STATUS_FIFO_OVERRUN_ATTN BIT_6
+ #define DMA_READ_STATUS_FIFO_UNDERRUN_ATTN BIT_7
+ #define DMA_READ_STATUS_FIFO_OVERREAD_ATTN BIT_8
+ #define DMA_READ_STATUS_LONG_READ_ATTN BIT_9
+
+ /* Unused space. */
+ LM_UINT8 Unused[1016];
+} T3_DMA_READ, *PT3_DMA_READ;
+
+typedef union T3_CPU
+{
+ struct
+ {
+ T3_32BIT_REGISTER mode;
+ #define CPU_MODE_HALT BIT_10
+ #define CPU_MODE_RESET BIT_0
+ T3_32BIT_REGISTER state;
+ T3_32BIT_REGISTER EventMask;
+ T3_32BIT_REGISTER reserved1[4];
+ T3_32BIT_REGISTER PC;
+ T3_32BIT_REGISTER Instruction;
+ T3_32BIT_REGISTER SpadUnderflow;
+ T3_32BIT_REGISTER WatchdogClear;
+ T3_32BIT_REGISTER WatchdogVector;
+ T3_32BIT_REGISTER WatchdogSavedPC;
+ T3_32BIT_REGISTER HardwareBp;
+ T3_32BIT_REGISTER reserved2[3];
+ T3_32BIT_REGISTER WatchdogSavedState;
+ T3_32BIT_REGISTER LastBrchAddr;
+ T3_32BIT_REGISTER SpadUnderflowSet;
+ T3_32BIT_REGISTER reserved3[(0x200-0x50)/4];
+ T3_32BIT_REGISTER Regs[32];
+ T3_32BIT_REGISTER reserved4[(0x400-0x280)/4];
+ }reg;
+}T3_CPU, *PT3_CPU;
+
+/******************************************************************************/
+/* Write DMA control registers. */
+/******************************************************************************/
+
+typedef struct {
+ T3_32BIT_REGISTER Mode;
+ #define DMA_WRITE_MODE_RESET BIT_0
+ #define DMA_WRITE_MODE_ENABLE BIT_1
+ #define DMA_WRITE_MODE_TARGET_ABORT_ATTN_ENABLE BIT_2
+ #define DMA_WRITE_MODE_MASTER_ABORT_ATTN_ENABLE BIT_3
+ #define DMA_WRITE_MODE_PARITY_ERROR_ATTN_ENABLE BIT_4
+ #define DMA_WRITE_MODE_ADDR_OVERFLOW_ATTN_ENABLE BIT_5
+ #define DMA_WRITE_MODE_FIFO_OVERRUN_ATTN_ENABLE BIT_6
+ #define DMA_WRITE_MODE_FIFO_UNDERRUN_ATTN_ENABLE BIT_7
+ #define DMA_WRITE_MODE_FIFO_OVERREAD_ATTN_ENABLE BIT_8
+ #define DMA_WRITE_MODE_LONG_READ_ATTN_ENABLE BIT_9
+
+ T3_32BIT_REGISTER Status;
+ #define DMA_WRITE_STATUS_TARGET_ABORT_ATTN BIT_2
+ #define DMA_WRITE_STATUS_MASTER_ABORT_ATTN BIT_3
+ #define DMA_WRITE_STATUS_PARITY_ERROR_ATTN BIT_4
+ #define DMA_WRITE_STATUS_ADDR_OVERFLOW_ATTN BIT_5
+ #define DMA_WRITE_STATUS_FIFO_OVERRUN_ATTN BIT_6
+ #define DMA_WRITE_STATUS_FIFO_UNDERRUN_ATTN BIT_7
+ #define DMA_WRITE_STATUS_FIFO_OVERREAD_ATTN BIT_8
+ #define DMA_WRITE_STATUS_LONG_READ_ATTN BIT_9
+
+ /* Unused space. */
+ LM_UINT8 Unused[1016];
+} T3_DMA_WRITE, *PT3_DMA_WRITE;
+
+
+
+/******************************************************************************/
+/* Mailbox registers. */
+/******************************************************************************/
+
+typedef struct {
+ /* Interrupt mailbox registers. */
+ T3_64BIT_REGISTER Interrupt[4];
+
+ /* General mailbox registers. */
+ T3_64BIT_REGISTER General[8];
+
+ /* Reload statistics mailbox. */
+ T3_64BIT_REGISTER ReloadStat;
+
+ /* Receive BD ring producer index registers. */
+ T3_64BIT_REGISTER RcvStdProdIdx;
+ T3_64BIT_REGISTER RcvJumboProdIdx;
+ T3_64BIT_REGISTER RcvMiniProdIdx;
+
+ /* Receive return ring consumer index registers. */
+ T3_64BIT_REGISTER RcvRetConIdx[16];
+
+ /* Send BD ring host producer index registers. */
+ T3_64BIT_REGISTER SendHostProdIdx[16];
+
+ /* Send BD ring nic producer index registers. */
+ T3_64BIT_REGISTER SendNicProdIdx[16];
+}T3_MAILBOX, *PT3_MAILBOX;
+
+typedef struct {
+ T3_MAILBOX Mailbox;
+
+ /* Priority mailbox registers. */
+ T3_32BIT_REGISTER HighPriorityEventVector;
+ T3_32BIT_REGISTER HighPriorityEventMask;
+ T3_32BIT_REGISTER LowPriorityEventVector;
+ T3_32BIT_REGISTER LowPriorityEventMask;
+
+ /* Unused space. */
+ LM_UINT8 Unused[496];
+} T3_GRC_MAILBOX, *PT3_GRC_MAILBOX;
+
+
+/******************************************************************************/
+/* Flow through queues. */
+/******************************************************************************/
+
+typedef struct {
+ T3_32BIT_REGISTER Reset;
+
+ LM_UINT8 Unused[12];
+
+ T3_32BIT_REGISTER DmaNormalReadFtqCtrl;
+ T3_32BIT_REGISTER DmaNormalReadFtqFullCnt;
+ T3_32BIT_REGISTER DmaNormalReadFtqFifoEnqueueDequeue;
+ T3_32BIT_REGISTER DmaNormalReadFtqFifoWritePeek;
+
+ T3_32BIT_REGISTER DmaHighReadFtqCtrl;
+ T3_32BIT_REGISTER DmaHighReadFtqFullCnt;
+ T3_32BIT_REGISTER DmaHighReadFtqFifoEnqueueDequeue;
+ T3_32BIT_REGISTER DmaHighReadFtqFifoWritePeek;
+
+ T3_32BIT_REGISTER DmaCompDiscardFtqCtrl;
+ T3_32BIT_REGISTER DmaCompDiscardFtqFullCnt;
+ T3_32BIT_REGISTER DmaCompDiscardFtqFifoEnqueueDequeue;
+ T3_32BIT_REGISTER DmaCompDiscardFtqFifoWritePeek;
+
+ T3_32BIT_REGISTER SendBdCompFtqCtrl;
+ T3_32BIT_REGISTER SendBdCompFtqFullCnt;
+ T3_32BIT_REGISTER SendBdCompFtqFifoEnqueueDequeue;
+ T3_32BIT_REGISTER SendBdCompFtqFifoWritePeek;
+
+ T3_32BIT_REGISTER SendDataInitiatorFtqCtrl;
+ T3_32BIT_REGISTER SendDataInitiatorFtqFullCnt;
+ T3_32BIT_REGISTER SendDataInitiatorFtqFifoEnqueueDequeue;
+ T3_32BIT_REGISTER SendDataInitiatorFtqFifoWritePeek;
+
+ T3_32BIT_REGISTER DmaNormalWriteFtqCtrl;
+ T3_32BIT_REGISTER DmaNormalWriteFtqFullCnt;
+ T3_32BIT_REGISTER DmaNormalWriteFtqFifoEnqueueDequeue;
+ T3_32BIT_REGISTER DmaNormalWriteFtqFifoWritePeek;
+
+ T3_32BIT_REGISTER DmaHighWriteFtqCtrl;
+ T3_32BIT_REGISTER DmaHighWriteFtqFullCnt;
+ T3_32BIT_REGISTER DmaHighWriteFtqFifoEnqueueDequeue;
+ T3_32BIT_REGISTER DmaHighWriteFtqFifoWritePeek;
+
+ T3_32BIT_REGISTER SwType1FtqCtrl;
+ T3_32BIT_REGISTER SwType1FtqFullCnt;
+ T3_32BIT_REGISTER SwType1FtqFifoEnqueueDequeue;
+ T3_32BIT_REGISTER SwType1FtqFifoWritePeek;
+
+ T3_32BIT_REGISTER SendDataCompFtqCtrl;
+ T3_32BIT_REGISTER SendDataCompFtqFullCnt;
+ T3_32BIT_REGISTER SendDataCompFtqFifoEnqueueDequeue;
+ T3_32BIT_REGISTER SendDataCompFtqFifoWritePeek;
+
+ T3_32BIT_REGISTER HostCoalesceFtqCtrl;
+ T3_32BIT_REGISTER HostCoalesceFtqFullCnt;
+ T3_32BIT_REGISTER HostCoalesceFtqFifoEnqueueDequeue;
+ T3_32BIT_REGISTER HostCoalesceFtqFifoWritePeek;
+
+ T3_32BIT_REGISTER MacTxFtqCtrl;
+ T3_32BIT_REGISTER MacTxFtqFullCnt;
+ T3_32BIT_REGISTER MacTxFtqFifoEnqueueDequeue;
+ T3_32BIT_REGISTER MacTxFtqFifoWritePeek;
+
+ T3_32BIT_REGISTER MbufClustFreeFtqCtrl;
+ T3_32BIT_REGISTER MbufClustFreeFtqFullCnt;
+ T3_32BIT_REGISTER MbufClustFreeFtqFifoEnqueueDequeue;
+ T3_32BIT_REGISTER MbufClustFreeFtqFifoWritePeek;
+
+ T3_32BIT_REGISTER RcvBdCompFtqCtrl;
+ T3_32BIT_REGISTER RcvBdCompFtqFullCnt;
+ T3_32BIT_REGISTER RcvBdCompFtqFifoEnqueueDequeue;
+ T3_32BIT_REGISTER RcvBdCompFtqFifoWritePeek;
+
+ T3_32BIT_REGISTER RcvListPlmtFtqCtrl;
+ T3_32BIT_REGISTER RcvListPlmtFtqFullCnt;
+ T3_32BIT_REGISTER RcvListPlmtFtqFifoEnqueueDequeue;
+ T3_32BIT_REGISTER RcvListPlmtFtqFifoWritePeek;
+
+ T3_32BIT_REGISTER RcvDataBdInitiatorFtqCtrl;
+ T3_32BIT_REGISTER RcvDataBdInitiatorFtqFullCnt;
+ T3_32BIT_REGISTER RcvDataBdInitiatorFtqFifoEnqueueDequeue;
+ T3_32BIT_REGISTER RcvDataBdInitiatorFtqFifoWritePeek;
+
+ T3_32BIT_REGISTER RcvDataCompFtqCtrl;
+ T3_32BIT_REGISTER RcvDataCompFtqFullCnt;
+ T3_32BIT_REGISTER RcvDataCompFtqFifoEnqueueDequeue;
+ T3_32BIT_REGISTER RcvDataCompFtqFifoWritePeek;
+
+ T3_32BIT_REGISTER SwType2FtqCtrl;
+ T3_32BIT_REGISTER SwType2FtqFullCnt;
+ T3_32BIT_REGISTER SwType2FtqFifoEnqueueDequeue;
+ T3_32BIT_REGISTER SwType2FtqFifoWritePeek;
+
+ /* Unused space. */
+ LM_UINT8 Unused2[736];
+} T3_FTQ, *PT3_FTQ;
+
+
+
+/******************************************************************************/
+/* Message signaled interrupt registers. */
+/******************************************************************************/
+
+typedef struct {
+ T3_32BIT_REGISTER Mode;
+#define MSI_MODE_RESET BIT_0
+#define MSI_MODE_ENABLE BIT_1
+ T3_32BIT_REGISTER Status;
+
+ T3_32BIT_REGISTER MsiFifoAccess;
+
+ /* Unused space. */
+ LM_UINT8 Unused[1012];
+} T3_MSG_SIGNALED_INT, *PT3_MSG_SIGNALED_INT;
+
+
+
+/******************************************************************************/
+/* DMA Completion registes. */
+/******************************************************************************/
+
+typedef struct {
+ T3_32BIT_REGISTER Mode;
+ #define DMA_COMP_MODE_RESET BIT_0
+ #define DMA_COMP_MODE_ENABLE BIT_1
+
+ /* Unused space. */
+ LM_UINT8 Unused[1020];
+} T3_DMA_COMPLETION, *PT3_DMA_COMPLETION;
+
+
+
+/******************************************************************************/
+/* GRC registers. */
+/******************************************************************************/
+
+typedef struct {
+ /* Mode control register. */
+ T3_32BIT_REGISTER Mode;
+ #define GRC_MODE_UPDATE_ON_COALESCING BIT_0
+ #define GRC_MODE_BYTE_SWAP_NON_FRAME_DATA BIT_1
+ #define GRC_MODE_WORD_SWAP_NON_FRAME_DATA BIT_2
+ #define GRC_MODE_BYTE_SWAP_DATA BIT_4
+ #define GRC_MODE_WORD_SWAP_DATA BIT_5
+ #define GRC_MODE_SPLIT_HEADER_MODE BIT_8
+ #define GRC_MODE_NO_FRAME_CRACKING BIT_9
+ #define GRC_MODE_INCLUDE_CRC BIT_10
+ #define GRC_MODE_ALLOW_BAD_FRAMES BIT_11
+ #define GRC_MODE_NO_INTERRUPT_ON_SENDS BIT_13
+ #define GRC_MODE_NO_INTERRUPT_ON_RECEIVE BIT_14
+ #define GRC_MODE_FORCE_32BIT_PCI_BUS_MODE BIT_15
+ #define GRC_MODE_HOST_STACK_UP BIT_16
+ #define GRC_MODE_HOST_SEND_BDS BIT_17
+ #define GRC_MODE_TX_NO_PSEUDO_HEADER_CHKSUM BIT_20
+ #define GRC_MODE_RX_NO_PSEUDO_HEADER_CHKSUM BIT_23
+ #define GRC_MODE_INT_ON_TX_CPU_ATTN BIT_24
+ #define GRC_MODE_INT_ON_RX_CPU_ATTN BIT_25
+ #define GRC_MODE_INT_ON_MAC_ATTN BIT_26
+ #define GRC_MODE_INT_ON_DMA_ATTN BIT_27
+ #define GRC_MODE_INT_ON_FLOW_ATTN BIT_28
+ #define GRC_MODE_4X_NIC_BASED_SEND_RINGS BIT_29
+ #define GRC_MODE_MULTICAST_FRAME_ENABLE BIT_30
+
+ /* Misc configuration register. */
+ T3_32BIT_REGISTER MiscCfg;
+ #define GRC_MISC_CFG_CORE_CLOCK_RESET BIT_0
+ #define GRC_MISC_PRESCALAR_TIMER_MASK 0xfe
+ #define GRC_MISC_BD_ID_MASK 0x0001e000
+ #define GRC_MISC_BD_ID_5700 0x0001e000
+ #define GRC_MISC_BD_ID_5701 0x00000000
+ #define GRC_MISC_BD_ID_5703 0x00000000
+ #define GRC_MISC_BD_ID_5703S 0x00002000
+ #define GRC_MISC_BD_ID_5702FE 0x00004000
+ #define GRC_MISC_BD_ID_5704 0x00000000
+ #define GRC_MISC_BD_ID_5704CIOBE 0x00004000
+
+ /* Miscellaneous local control register. */
+ T3_32BIT_REGISTER LocalCtrl;
+ #define GRC_MISC_LOCAL_CTRL_INT_ACTIVE BIT_0
+ #define GRC_MISC_LOCAL_CTRL_CLEAR_INT BIT_1
+ #define GRC_MISC_LOCAL_CTRL_SET_INT BIT_2
+ #define GRC_MISC_LOCAL_CTRL_INT_ON_ATTN BIT_3
+ #define GRC_MISC_LOCAL_CTRL_GPIO_INPUT0 BIT_8
+ #define GRC_MISC_LOCAL_CTRL_GPIO_INPUT1 BIT_9
+ #define GRC_MISC_LOCAL_CTRL_GPIO_INPUT2 BIT_10
+ #define GRC_MISC_LOCAL_CTRL_GPIO_OE0 BIT_11
+ #define GRC_MISC_LOCAL_CTRL_GPIO_OE1 BIT_12
+ #define GRC_MISC_LOCAL_CTRL_GPIO_OE2 BIT_13
+ #define GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT0 BIT_14
+ #define GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT1 BIT_15
+ #define GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT2 BIT_16
+ #define GRC_MISC_LOCAL_CTRL_ENABLE_EXT_MEMORY BIT_17
+ #define GRC_MISC_LOCAL_CTRL_BANK_SELECT BIT_21
+ #define GRC_MISC_LOCAL_CTRL_SSRAM_TYPE BIT_22
+
+ #define GRC_MISC_MEMSIZE_256K 0
+ #define GRC_MISC_MEMSIZE_512K (1 << 18)
+ #define GRC_MISC_MEMSIZE_1024K (2 << 18)
+ #define GRC_MISC_MEMSIZE_2048K (3 << 18)
+ #define GRC_MISC_MEMSIZE_4096K (4 << 18)
+ #define GRC_MISC_MEMSIZE_8192K (5 << 18)
+ #define GRC_MISC_MEMSIZE_16M (6 << 18)
+ #define GRC_MISC_LOCAL_CTRL_AUTO_SEEPROM BIT_24
+
+
+ T3_32BIT_REGISTER Timer;
+
+ T3_32BIT_REGISTER RxCpuEvent;
+ T3_32BIT_REGISTER RxTimerRef;
+ T3_32BIT_REGISTER RxCpuSemaphore;
+ T3_32BIT_REGISTER RemoteRxCpuAttn;
+
+ T3_32BIT_REGISTER TxCpuEvent;
+ T3_32BIT_REGISTER TxTimerRef;
+ T3_32BIT_REGISTER TxCpuSemaphore;
+ T3_32BIT_REGISTER RemoteTxCpuAttn;
+
+ T3_64BIT_REGISTER MemoryPowerUp;
+
+ T3_32BIT_REGISTER EepromAddr;
+ #define SEEPROM_ADDR_WRITE 0
+ #define SEEPROM_ADDR_READ (1 << 31)
+ #define SEEPROM_ADDR_RW_MASK 0x80000000
+ #define SEEPROM_ADDR_COMPLETE (1 << 30)
+ #define SEEPROM_ADDR_FSM_RESET (1 << 29)
+ #define SEEPROM_ADDR_DEV_ID(x) (x << 26)
+ #define SEEPROM_ADDR_DEV_ID_MASK 0x1c000000
+ #define SEEPROM_ADDR_START (1 << 25)
+ #define SEEPROM_ADDR_CLK_PERD(x) (x << 16)
+ #define SEEPROM_ADDR_ADDRESS(x) (x & 0xfffc)
+ #define SEEPROM_ADDR_ADDRESS_MASK 0x0000ffff
+
+ #define SEEPROM_CLOCK_PERIOD 60
+ #define SEEPROM_CHIP_SIZE (64 * 1024)
+
+ T3_32BIT_REGISTER EepromData;
+ T3_32BIT_REGISTER EepromCtrl;
+
+ T3_32BIT_REGISTER MdiCtrl;
+ T3_32BIT_REGISTER SepromDelay;
+
+ /* Unused space. */
+ LM_UINT8 Unused[948];
+} T3_GRC, *PT3_GRC;
+
+
+/******************************************************************************/
+/* NVRAM control registers. */
+/******************************************************************************/
+
+typedef struct
+{
+ T3_32BIT_REGISTER Cmd;
+ #define NVRAM_CMD_RESET BIT_0
+ #define NVRAM_CMD_DONE BIT_3
+ #define NVRAM_CMD_DO_IT BIT_4
+ #define NVRAM_CMD_WR BIT_5
+ #define NVRAM_CMD_RD BIT_NONE
+ #define NVRAM_CMD_ERASE BIT_6
+ #define NVRAM_CMD_FIRST BIT_7
+ #define NVRAM_CMD_LAST BIT_8
+
+ T3_32BIT_REGISTER Status;
+ T3_32BIT_REGISTER WriteData;
+
+ T3_32BIT_REGISTER Addr;
+ #define NVRAM_ADDRESS_MASK 0xffffff
+
+ T3_32BIT_REGISTER ReadData;
+
+ /* Flash config 1 register. */
+ T3_32BIT_REGISTER Config1;
+ #define FLASH_INTERFACE_ENABLE BIT_0
+ #define FLASH_SSRAM_BUFFERRED_MODE BIT_1
+ #define FLASH_PASS_THRU_MODE BIT_2
+ #define FLASH_BIT_BANG_MODE BIT_3
+ #define FLASH_COMPAT_BYPASS BIT_31
+
+ /* Buffered flash (Atmel: AT45DB011B) specific information */
+ #define BUFFERED_FLASH_PAGE_POS 9
+ #define BUFFERED_FLASH_BYTE_ADDR_MASK ((1<<BUFFERED_FLASH_PAGE_POS) - 1)
+ #define BUFFERED_FLASH_PAGE_SIZE 264
+ #define BUFFERED_FLASH_PHY_PAGE_SIZE 512
+
+ T3_32BIT_REGISTER Config2;
+ T3_32BIT_REGISTER Config3;
+ T3_32BIT_REGISTER SwArb;
+ #define SW_ARB_REQ_SET0 BIT_0
+ #define SW_ARB_REQ_SET1 BIT_1
+ #define SW_ARB_REQ_SET2 BIT_2
+ #define SW_ARB_REQ_SET3 BIT_3
+ #define SW_ARB_REQ_CLR0 BIT_4
+ #define SW_ARB_REQ_CLR1 BIT_5
+ #define SW_ARB_REQ_CLR2 BIT_6
+ #define SW_ARB_REQ_CLR3 BIT_7
+ #define SW_ARB_GNT0 BIT_8
+ #define SW_ARB_GNT1 BIT_9
+ #define SW_ARB_GNT2 BIT_10
+ #define SW_ARB_GNT3 BIT_11
+ #define SW_ARB_REQ0 BIT_12
+ #define SW_ARB_REQ1 BIT_13
+ #define SW_ARB_REQ2 BIT_14
+ #define SW_ARB_REQ3 BIT_15
+
+ /* Unused space. */
+ LM_UINT8 Unused[988];
+} T3_NVRAM, *PT3_NVRAM;
+
+
+/******************************************************************************/
+/* NIC's internal memory. */
+/******************************************************************************/
+
+typedef struct {
+ /* Page zero for the internal CPUs. */
+ LM_UINT8 PageZero[0x100]; /* 0x0000 */
+
+ /* Send RCBs. */
+ T3_RCB SendRcb[16]; /* 0x0100 */
+
+ /* Receive Return RCBs. */
+ T3_RCB RcvRetRcb[16]; /* 0x0200 */
+
+ /* Statistics block. */
+ T3_STATS_BLOCK StatsBlk; /* 0x0300 */
+
+ /* Status block. */
+ T3_STATUS_BLOCK StatusBlk; /* 0x0b00 */
+
+ /* Reserved for software. */
+ LM_UINT8 Reserved[1200]; /* 0x0b50 */
+
+ /* Unmapped region. */
+ LM_UINT8 Unmapped[4096]; /* 0x1000 */
+
+ /* DMA descriptors. */
+ LM_UINT8 DmaDesc[8192]; /* 0x2000 */
+
+ /* Buffer descriptors. */
+ LM_UINT8 BufferDesc[16384]; /* 0x4000 */
+} T3_FIRST_32K_SRAM, *PT3_FIRST_32K_SRAM;
+
+
+
+/******************************************************************************/
+/* Memory layout. */
+/******************************************************************************/
+
+typedef struct {
+ /* PCI configuration registers. */
+ T3_PCI_CONFIGURATION PciCfg;
+
+ /* Unused. */
+ LM_UINT8 Unused1[0x100]; /* 0x0100 */
+
+ /* Mailbox . */
+ T3_MAILBOX Mailbox; /* 0x0200 */
+
+ /* MAC control registers. */
+ T3_MAC_CONTROL MacCtrl; /* 0x0400 */
+
+ /* Send data initiator control registers. */
+ T3_SEND_DATA_INITIATOR SndDataIn; /* 0x0c00 */
+
+ /* Send data completion Control registers. */
+ T3_SEND_DATA_COMPLETION SndDataComp; /* 0x1000 */
+
+ /* Send BD ring selector. */
+ T3_SEND_BD_SELECTOR SndBdSel; /* 0x1400 */
+
+ /* Send BD initiator control registers. */
+ T3_SEND_BD_INITIATOR SndBdIn; /* 0x1800 */
+
+ /* Send BD completion control registers. */
+ T3_SEND_BD_COMPLETION SndBdComp; /* 0x1c00 */
+
+ /* Receive list placement control registers. */
+ T3_RCV_LIST_PLACEMENT RcvListPlmt; /* 0x2000 */
+
+ /* Receive Data and Receive BD Initiator Control. */
+ T3_RCV_DATA_BD_INITIATOR RcvDataBdIn; /* 0x2400 */
+
+ /* Receive Data Completion Control */
+ T3_RCV_DATA_COMPLETION RcvDataComp; /* 0x2800 */
+
+ /* Receive BD Initiator Control Registers. */
+ T3_RCV_BD_INITIATOR RcvBdIn; /* 0x2c00 */
+
+ /* Receive BD Completion Control Registers. */
+ T3_RCV_BD_COMPLETION RcvBdComp; /* 0x3000 */
+
+ /* Receive list selector control registers. */
+ T3_RCV_LIST_SELECTOR RcvListSel; /* 0x3400 */
+
+ /* Mbuf cluster free registers. */
+ T3_MBUF_CLUSTER_FREE MbufClusterFree; /* 0x3800 */
+
+ /* Host coalescing control registers. */
+ T3_HOST_COALESCING HostCoalesce; /* 0x3c00 */
+
+ /* Memory arbiter control registers. */
+ T3_MEM_ARBITER MemArbiter; /* 0x4000 */
+
+ /* Buffer manger control registers. */
+ T3_BUFFER_MANAGER BufMgr; /* 0x4400 */
+
+ /* Read DMA control registers. */
+ T3_DMA_READ DmaRead; /* 0x4800 */
+
+ /* Write DMA control registers. */
+ T3_DMA_WRITE DmaWrite; /* 0x4c00 */
+
+ T3_CPU rxCpu; /* 0x5000 */
+ T3_CPU txCpu; /* 0x5400 */
+
+ /* Mailboxes. */
+ T3_GRC_MAILBOX GrcMailbox; /* 0x5800 */
+
+ /* Flow Through queues. */
+ T3_FTQ Ftq; /* 0x5c00 */
+
+ /* Message signaled interrupt registes. */
+ T3_MSG_SIGNALED_INT Msi; /* 0x6000 */
+
+ /* DMA completion registers. */
+ T3_DMA_COMPLETION DmaComp; /* 0x6400 */
+
+ /* GRC registers. */
+ T3_GRC Grc; /* 0x6800 */
+
+ /* Unused space. */
+ LM_UINT8 Unused2[1024]; /* 0x6c00 */
+
+ /* NVRAM registers. */
+ T3_NVRAM Nvram; /* 0x7000 */
+
+ /* Unused space. */
+ LM_UINT8 Unused3[3072]; /* 0x7400 */
+
+ /* The 32k memory window into the NIC's */
+ /* internal memory. The memory window is */
+ /* controlled by the Memory Window Base */
+ /* Address register. This register is located */
+ /* in the PCI configuration space. */
+ union { /* 0x8000 */
+ T3_FIRST_32K_SRAM First32k;
+
+ /* Use the memory window base address register to determine the */
+ /* MBUF segment. */
+ LM_UINT32 Mbuf[32768/4];
+ LM_UINT32 MemBlock32K[32768/4];
+ } uIntMem;
+} T3_STD_MEM_MAP, *PT3_STD_MEM_MAP;
+
+
+/******************************************************************************/
+/* Adapter info. */
+/******************************************************************************/
+
+typedef struct
+{
+ LM_UINT16 Svid;
+ LM_UINT16 Ssid;
+ LM_UINT32 PhyId;
+ LM_UINT32 Serdes; /* 0 = copper PHY, 1 = Serdes */
+} LM_ADAPTER_INFO, *PLM_ADAPTER_INFO;
+
+
+/******************************************************************************/
+/* Packet queues. */
+/******************************************************************************/
+
+DECLARE_QUEUE_TYPE(LM_RX_PACKET_Q, MAX_RX_PACKET_DESC_COUNT);
+DECLARE_QUEUE_TYPE(LM_TX_PACKET_Q, MAX_TX_PACKET_DESC_COUNT);
+
+
+
+/******************************************************************************/
+/* Tx counters. */
+/******************************************************************************/
+
+typedef struct {
+ LM_COUNTER TxPacketGoodCnt;
+ LM_COUNTER TxBytesGoodCnt;
+ LM_COUNTER TxPacketAbortedCnt;
+ LM_COUNTER NoSendBdLeftCnt;
+ LM_COUNTER NoMapRegisterLeftCnt;
+ LM_COUNTER TooManyFragmentsCnt;
+ LM_COUNTER NoTxPacketDescCnt;
+} LM_TX_COUNTERS, *PLM_TX_COUNTERS;
+
+
+
+/******************************************************************************/
+/* Rx counters. */
+/******************************************************************************/
+
+typedef struct {
+ LM_COUNTER RxPacketGoodCnt;
+ LM_COUNTER RxBytesGoodCnt;
+ LM_COUNTER RxPacketErrCnt;
+ LM_COUNTER RxErrCrcCnt;
+ LM_COUNTER RxErrCollCnt;
+ LM_COUNTER RxErrLinkLostCnt;
+ LM_COUNTER RxErrPhyDecodeCnt;
+ LM_COUNTER RxErrOddNibbleCnt;
+ LM_COUNTER RxErrMacAbortCnt;
+ LM_COUNTER RxErrShortPacketCnt;
+ LM_COUNTER RxErrNoResourceCnt;
+ LM_COUNTER RxErrLargePacketCnt;
+} LM_RX_COUNTERS, *PLM_RX_COUNTERS;
+
+
+
+/******************************************************************************/
+/* Receive producer rings. */
+/******************************************************************************/
+
+typedef enum {
+ T3_UNKNOWN_RCV_PROD_RING = 0,
+ T3_STD_RCV_PROD_RING = 1,
+ T3_MINI_RCV_PROD_RING = 2,
+ T3_JUMBO_RCV_PROD_RING = 3
+} T3_RCV_PROD_RING, *PT3_RCV_PROD_RING;
+
+
+
+/******************************************************************************/
+/* Packet descriptor. */
+/******************************************************************************/
+
+#define LM_PACKET_SIGNATURE_TX 0x6861766b
+#define LM_PACKET_SIGNATURE_RX 0x6b766168
+
+typedef struct _LM_PACKET {
+ /* Set in LM. */
+ LM_STATUS PacketStatus;
+
+ /* Set in LM for Rx, in UM for Tx. */
+ LM_UINT32 PacketSize;
+
+ LM_UINT16 Flags;
+
+ LM_UINT16 VlanTag;
+
+ union {
+ /* Send info. */
+ struct {
+ /* Set up by UM. */
+ LM_UINT32 FragCount;
+
+ } Tx;
+
+ /* Receive info. */
+ struct {
+ /* This descriptor belongs to either Std, Mini, or Jumbo ring. */
+ T3_RCV_PROD_RING RcvProdRing;
+
+ /* Receive buffer size */
+ LM_UINT32 RxBufferSize;
+
+ /* Checksum information. */
+ LM_UINT16 IpChecksum;
+ LM_UINT16 TcpUdpChecksum;
+
+ } Rx;
+ } u;
+} LM_PACKET;
+
+
+
+/******************************************************************************/
+/* Tigon3 device block. */
+/******************************************************************************/
+
+typedef struct _LM_DEVICE_BLOCK {
+ int index; /* Device ID */
+ /* Memory view. */
+ PT3_STD_MEM_MAP pMemView;
+
+ /* Base address of the block of memory in which the LM_PACKET descriptors */
+ /* are allocated from. */
+ PLM_VOID pPacketDescBase;
+
+ LM_UINT32 MiscHostCtrl;
+ LM_UINT32 GrcLocalCtrl;
+ LM_UINT32 DmaReadWriteCtrl;
+ LM_UINT32 PciState;
+
+ /* Rx info */
+ LM_UINT32 RxStdDescCnt;
+ LM_UINT32 RxStdQueuedCnt;
+ LM_UINT32 RxStdProdIdx;
+
+ PT3_RCV_BD pRxStdBdVirt;
+ LM_PHYSICAL_ADDRESS RxStdBdPhy;
+
+ LM_UINT32 RxPacketDescCnt;
+ LM_RX_PACKET_Q RxPacketFreeQ;
+ LM_RX_PACKET_Q RxPacketReceivedQ;
+
+ /* Receive info. */
+ PT3_RCV_BD pRcvRetBdVirt;
+ LM_PHYSICAL_ADDRESS RcvRetBdPhy;
+ LM_UINT32 RcvRetConIdx;
+
+#if T3_JUMBO_RCV_RCB_ENTRY_COUNT
+ LM_UINT32 RxJumboDescCnt;
+ LM_UINT32 RxJumboBufferSize;
+ LM_UINT32 RxJumboQueuedCnt;
+
+ LM_UINT32 RxJumboProdIdx;
+
+ PT3_RCV_BD pRxJumboBdVirt;
+ LM_PHYSICAL_ADDRESS RxJumboBdPhy;
+#endif /* T3_JUMBO_RCV_RCB_ENTRY_COUNT */
+
+ /* These values are used by the upper module to inform the protocol */
+ /* of the maximum transmit/receive packet size. */
+ LM_UINT32 TxMtu; /* Does not include CRC. */
+ LM_UINT32 RxMtu; /* Does not include CRC. */
+
+ /* We need to shadow the EMAC, Rx, Tx mode registers. With B0 silicon, */
+ /* we may have problems reading any MAC registers in 10mb mode. */
+ LM_UINT32 MacMode;
+ LM_UINT32 RxMode;
+ LM_UINT32 TxMode;
+
+ /* MiMode register. */
+ LM_UINT32 MiMode;
+
+ /* Host coalesce mode register. */
+ LM_UINT32 CoalesceMode;
+
+ /* Send info. */
+ LM_UINT32 TxPacketDescCnt;
+
+ /* Tx info. */
+ LM_TX_PACKET_Q TxPacketFreeQ;
+ LM_TX_PACKET_Q TxPacketActiveQ;
+ LM_TX_PACKET_Q TxPacketXmittedQ;
+
+ /* Pointers to SendBd. */
+ PT3_SND_BD pSendBdVirt;
+ LM_PHYSICAL_ADDRESS SendBdPhy; /* Only valid for Host based Send BD. */
+
+ /* Send producer and consumer indices. */
+ LM_UINT32 SendProdIdx;
+ LM_UINT32 SendConIdx;
+
+ /* Number of BD left. */
+ atomic_t SendBdLeft;
+
+ T3_SND_BD ShadowSendBd[T3_SEND_RCB_ENTRY_COUNT];
+
+ /* Counters. */
+ LM_RX_COUNTERS RxCounters;
+ LM_TX_COUNTERS TxCounters;
+
+ /* Host coalescing parameters. */
+ LM_UINT32 RxCoalescingTicks;
+ LM_UINT32 TxCoalescingTicks;
+ LM_UINT32 RxMaxCoalescedFrames;
+ LM_UINT32 TxMaxCoalescedFrames;
+ LM_UINT32 StatsCoalescingTicks;
+ LM_UINT32 RxCoalescingTicksDuringInt;
+ LM_UINT32 TxCoalescingTicksDuringInt;
+ LM_UINT32 RxMaxCoalescedFramesDuringInt;
+ LM_UINT32 TxMaxCoalescedFramesDuringInt;
+
+ /* DMA water marks. */
+ LM_UINT32 DmaMbufLowMark;
+ LM_UINT32 RxMacMbufLowMark;
+ LM_UINT32 MbufHighMark;
+
+ /* Status block. */
+ PT3_STATUS_BLOCK pStatusBlkVirt;
+ LM_PHYSICAL_ADDRESS StatusBlkPhy;
+
+ /* Statistics block. */
+ PT3_STATS_BLOCK pStatsBlkVirt;
+ LM_PHYSICAL_ADDRESS StatsBlkPhy;
+
+ /* Current receive mask. */
+ LM_UINT32 ReceiveMask;
+
+ /* Task offload capabilities. */
+ LM_TASK_OFFLOAD TaskOffloadCap;
+
+ /* Task offload selected. */
+ LM_TASK_OFFLOAD TaskToOffload;
+
+ /* Wake up capability. */
+ LM_WAKE_UP_MODE WakeUpModeCap;
+
+ /* Wake up capability. */
+ LM_WAKE_UP_MODE WakeUpMode;
+
+ /* Flow control. */
+ LM_FLOW_CONTROL FlowControlCap;
+ LM_FLOW_CONTROL FlowControl;
+
+ /* Enable or disable PCI MWI. */
+ LM_UINT32 EnableMWI;
+
+ /* Enable 5701 tagged status mode. */
+ LM_UINT32 UseTaggedStatus;
+
+ /* NIC will not compute the pseudo header checksum. The driver or OS */
+ /* must seed the checksum field with the pseudo checksum. */
+ LM_UINT32 NoTxPseudoHdrChksum;
+
+ /* The receive checksum in the BD does not include the pseudo checksum. */
+ /* The OS or the driver must calculate the pseudo checksum and add it to */
+ /* the checksum in the BD. */
+ LM_UINT32 NoRxPseudoHdrChksum;
+
+ /* Current node address. */
+ LM_UINT8 NodeAddress[8];
+
+ /* The adapter's node address. */
+ LM_UINT8 PermanentNodeAddress[8];
+
+ /* Adapter info. */
+ LM_UINT16 BusNum;
+ LM_UINT8 DevNum;
+ LM_UINT8 FunctNum;
+ LM_UINT16 PciVendorId;
+ LM_UINT16 PciDeviceId;
+ LM_UINT32 BondId;
+ LM_UINT8 Irq;
+ LM_UINT8 IntPin;
+ LM_UINT8 CacheLineSize;
+ LM_UINT8 PciRevId;
+#if PCIX_TARGET_WORKAROUND
+ LM_UINT32 EnablePciXFix;
+#endif
+ LM_UINT32 UndiFix; /* new, jimmy */
+ LM_UINT32 PciCommandStatusWords;
+ LM_UINT32 ChipRevId;
+ LM_UINT16 SubsystemVendorId;
+ LM_UINT16 SubsystemId;
+#if 0 /* Jimmy, deleted in new driver */
+ LM_UINT32 MemBaseLow;
+ LM_UINT32 MemBaseHigh;
+ LM_UINT32 MemBaseSize;
+#endif
+ PLM_UINT8 pMappedMemBase;
+
+ /* Saved PCI configuration registers for restoring after a reset. */
+ LM_UINT32 SavedCacheLineReg;
+
+ /* Phy info. */
+ LM_UINT32 PhyAddr;
+ LM_UINT32 PhyId;
+
+ /* Requested phy settings. */
+ LM_REQUESTED_MEDIA_TYPE RequestedMediaType;
+
+ /* Disable auto-negotiation. */
+ LM_UINT32 DisableAutoNeg;
+
+ /* Ways for the MAC to get link change interrupt. */
+ LM_UINT32 PhyIntMode;
+ #define T3_PHY_INT_MODE_AUTO 0
+ #define T3_PHY_INT_MODE_MI_INTERRUPT 1
+ #define T3_PHY_INT_MODE_LINK_READY 2
+ #define T3_PHY_INT_MODE_AUTO_POLLING 3
+
+ /* Ways to determine link change status. */
+ LM_UINT32 LinkChngMode;
+ #define T3_LINK_CHNG_MODE_AUTO 0
+ #define T3_LINK_CHNG_MODE_USE_STATUS_REG 1
+ #define T3_LINK_CHNG_MODE_USE_STATUS_BLOCK 2
+
+
+ /* LED mode. */
+ LM_UINT32 LedMode;
+
+ #define LED_MODE_AUTO 0
+
+ /* 5700/01 LED mode. */
+ #define LED_MODE_THREE_LINK 1
+ #define LED_MODE_LINK10 2
+
+ /* 5703/02/04 LED mode. */
+ #define LED_MODE_OPEN_DRAIN 1
+ #define LED_MODE_OUTPUT 2
+
+ /* WOL Speed */
+ LM_UINT32 WolSpeed;
+ #define WOL_SPEED_10MB 1
+ #define WOL_SPEED_100MB 2
+
+ /* Reset the PHY on initialization. */
+ LM_UINT32 ResetPhyOnInit;
+
+ LM_UINT32 RestoreOnWakeUp;
+ LM_REQUESTED_MEDIA_TYPE WakeUpRequestedMediaType;
+ LM_UINT32 WakeUpDisableAutoNeg;
+
+ /* Current phy settings. */
+ LM_MEDIA_TYPE MediaType;
+ LM_LINE_SPEED LineSpeed;
+ LM_LINE_SPEED OldLineSpeed;
+ LM_DUPLEX_MODE DuplexMode;
+ LM_STATUS LinkStatus;
+ LM_UINT32 advertising; /* Jimmy, new! */
+ LM_UINT32 advertising1000; /* Jimmy, new! */
+
+ /* Multicast address list. */
+ LM_UINT32 McEntryCount;
+ LM_UINT8 McTable[LM_MAX_MC_TABLE_SIZE][LM_MC_ENTRY_SIZE];
+
+ /* Use NIC or Host based send BD. */
+ LM_UINT32 NicSendBd;
+
+ /* Athlon fix. */
+ LM_UINT32 DelayPciGrant;
+
+ /* Enable OneDmaAtOnce */
+ LM_UINT32 OneDmaAtOnce;
+
+ /* Split Mode flags, Jimmy new */
+ LM_UINT32 SplitModeEnable;
+ LM_UINT32 SplitModeMaxReq;
+
+ /* Init flag. */
+ LM_BOOL InitDone;
+
+ /* Shutdown flag. Set by the upper module. */
+ LM_BOOL ShuttingDown;
+
+ /* Flag to determine whether to call LM_QueueRxPackets or not in */
+ /* LM_ResetAdapter routine. */
+ LM_BOOL QueueRxPackets;
+
+ LM_UINT32 MbufBase;
+ LM_UINT32 MbufSize;
+
+ /* TRUE if we have a SERDES PHY. */
+ LM_UINT32 EnableTbi;
+
+ /* Ethernet@WireSpeed. */
+ LM_UINT32 EnableWireSpeed;
+
+ LM_UINT32 EepromWp;
+
+#if INCLUDE_TBI_SUPPORT
+ /* Autoneg state info. */
+ AN_STATE_INFO AnInfo;
+ LM_UINT32 PollTbiLink;
+ LM_UINT32 IgnoreTbiLinkChange;
+#endif
+ char PartNo[24];
+ char BootCodeVer[16];
+ char BusSpeedStr[24]; /* Jimmy, new! */
+ LM_UINT32 PhyCrcCount;
+} LM_DEVICE_BLOCK;
+
+
+#define T3_REG_CPU_VIEW 0xc0000000
+
+#define T3_BLOCK_DMA_RD (1 << 0)
+#define T3_BLOCK_DMA_COMP (1 << 1)
+#define T3_BLOCK_RX_BD_INITIATOR (1 << 2)
+#define T3_BLOCK_RX_BD_COMP (1 << 3)
+#define T3_BLOCK_DMA_WR (1 << 4)
+#define T3_BLOCK_MSI_HANDLER (1 << 5)
+#define T3_BLOCK_RX_LIST_PLMT (1 << 6)
+#define T3_BLOCK_RX_LIST_SELECTOR (1 << 7)
+#define T3_BLOCK_RX_DATA_INITIATOR (1 << 8)
+#define T3_BLOCK_RX_DATA_COMP (1 << 9)
+#define T3_BLOCK_HOST_COALESING (1 << 10)
+#define T3_BLOCK_MAC_RX_ENGINE (1 << 11)
+#define T3_BLOCK_MBUF_CLUSTER_FREE (1 << 12)
+#define T3_BLOCK_SEND_BD_INITIATOR (1 << 13)
+#define T3_BLOCK_SEND_BD_COMP (1 << 14)
+#define T3_BLOCK_SEND_BD_SELECTOR (1 << 15)
+#define T3_BLOCK_SEND_DATA_INITIATOR (1 << 16)
+#define T3_BLOCK_SEND_DATA_COMP (1 << 17)
+#define T3_BLOCK_MAC_TX_ENGINE (1 << 18)
+#define T3_BLOCK_MEM_ARBITOR (1 << 19)
+#define T3_BLOCK_MBUF_MANAGER (1 << 20)
+#define T3_BLOCK_MAC_GLOBAL (1 << 21)
+
+#define LM_ENABLE 1
+#define LM_DISABLE 2
+
+#define RX_CPU_EVT_SW0 0
+#define RX_CPU_EVT_SW1 1
+#define RX_CPU_EVT_RLP 2
+#define RX_CPU_EVT_SW3 3
+#define RX_CPU_EVT_RLS 4
+#define RX_CPU_EVT_SW4 5
+#define RX_CPU_EVT_RX_BD_COMP 6
+#define RX_CPU_EVT_SW5 7
+#define RX_CPU_EVT_RDI 8
+#define RX_CPU_EVT_DMA_WR 9
+#define RX_CPU_EVT_DMA_RD 10
+#define RX_CPU_EVT_SWQ 11
+#define RX_CPU_EVT_SW6 12
+#define RX_CPU_EVT_RDC 13
+#define RX_CPU_EVT_SW7 14
+#define RX_CPU_EVT_HOST_COALES 15
+#define RX_CPU_EVT_SW8 16
+#define RX_CPU_EVT_HIGH_DMA_WR 17
+#define RX_CPU_EVT_HIGH_DMA_RD 18
+#define RX_CPU_EVT_SW9 19
+#define RX_CPU_EVT_DMA_ATTN 20
+#define RX_CPU_EVT_LOW_P_MBOX 21
+#define RX_CPU_EVT_HIGH_P_MBOX 22
+#define RX_CPU_EVT_SW10 23
+#define RX_CPU_EVT_TX_CPU_ATTN 24
+#define RX_CPU_EVT_MAC_ATTN 25
+#define RX_CPU_EVT_RX_CPU_ATTN 26
+#define RX_CPU_EVT_FLOW_ATTN 27
+#define RX_CPU_EVT_SW11 28
+#define RX_CPU_EVT_TIMER 29
+#define RX_CPU_EVT_SW12 30
+#define RX_CPU_EVT_SW13 31
+
+/* RX-CPU event */
+#define RX_CPU_EVENT_SW_EVENT0 (1 << RX_CPU_EVT_SW0)
+#define RX_CPU_EVENT_SW_EVENT1 (1 << RX_CPU_EVT_SW1)
+#define RX_CPU_EVENT_RLP (1 << RX_CPU_EVT_RLP)
+#define RX_CPU_EVENT_SW_EVENT3 (1 << RX_CPU_EVT_SW3)
+#define RX_CPU_EVENT_RLS (1 << RX_CPU_EVT_RLS)
+#define RX_CPU_EVENT_SW_EVENT4 (1 << RX_CPU_EVT_SW4)
+#define RX_CPU_EVENT_RX_BD_COMP (1 << RX_CPU_EVT_RX_BD_COMP)
+#define RX_CPU_EVENT_SW_EVENT5 (1 << RX_CPU_EVT_SW5)
+#define RX_CPU_EVENT_RDI (1 << RX_CPU_EVT_RDI)
+#define RX_CPU_EVENT_DMA_WR (1 << RX_CPU_EVT_DMA_WR)
+#define RX_CPU_EVENT_DMA_RD (1 << RX_CPU_EVT_DMA_RD)
+#define RX_CPU_EVENT_SWQ (1 << RX_CPU_EVT_SWQ)
+#define RX_CPU_EVENT_SW_EVENT6 (1 << RX_CPU_EVT_SW6)
+#define RX_CPU_EVENT_RDC (1 << RX_CPU_EVT_RDC)
+#define RX_CPU_EVENT_SW_EVENT7 (1 << RX_CPU_EVT_SW7)
+#define RX_CPU_EVENT_HOST_COALES (1 << RX_CPU_EVT_HOST_COALES)
+#define RX_CPU_EVENT_SW_EVENT8 (1 << RX_CPU_EVT_SW8)
+#define RX_CPU_EVENT_HIGH_DMA_WR (1 << RX_CPU_EVT_HIGH_DMA_WR)
+#define RX_CPU_EVENT_HIGH_DMA_RD (1 << RX_CPU_EVT_HIGH_DMA_RD)
+#define RX_CPU_EVENT_SW_EVENT9 (1 << RX_CPU_EVT_SW9)
+#define RX_CPU_EVENT_DMA_ATTN (1 << RX_CPU_EVT_DMA_ATTN)
+#define RX_CPU_EVENT_LOW_P_MBOX (1 << RX_CPU_EVT_LOW_P_MBOX)
+#define RX_CPU_EVENT_HIGH_P_MBOX (1 << RX_CPU_EVT_HIGH_P_MBOX)
+#define RX_CPU_EVENT_SW_EVENT10 (1 << RX_CPU_EVT_SW10)
+#define RX_CPU_EVENT_TX_CPU_ATTN (1 << RX_CPU_EVT_TX_CPU_ATTN)
+#define RX_CPU_EVENT_MAC_ATTN (1 << RX_CPU_EVT_MAC_ATTN)
+#define RX_CPU_EVENT_RX_CPU_ATTN (1 << RX_CPU_EVT_RX_CPU_ATTN)
+#define RX_CPU_EVENT_FLOW_ATTN (1 << RX_CPU_EVT_FLOW_ATTN)
+#define RX_CPU_EVENT_SW_EVENT11 (1 << RX_CPU_EVT_SW11)
+#define RX_CPU_EVENT_TIMER (1 << RX_CPU_EVT_TIMER)
+#define RX_CPU_EVENT_SW_EVENT12 (1 << RX_CPU_EVT_SW12)
+#define RX_CPU_EVENT_SW_EVENT13 (1 << RX_CPU_EVT_SW13)
+
+#define RX_CPU_MASK (RX_CPU_EVENT_SW_EVENT0 | \
+ RX_CPU_EVENT_RLP | \
+ RX_CPU_EVENT_RDI | \
+ RX_CPU_EVENT_RDC)
+
+#define TX_CPU_EVT_SW0 0
+#define TX_CPU_EVT_SW1 1
+#define TX_CPU_EVT_SW2 2
+#define TX_CPU_EVT_SW3 3
+#define TX_CPU_EVT_TX_MAC 4
+#define TX_CPU_EVT_SW4 5
+#define TX_CPU_EVT_SBDC 6
+#define TX_CPU_EVT_SW5 7
+#define TX_CPU_EVT_SDI 8
+#define TX_CPU_EVT_DMA_WR 9
+#define TX_CPU_EVT_DMA_RD 10
+#define TX_CPU_EVT_SWQ 11
+#define TX_CPU_EVT_SW6 12
+#define TX_CPU_EVT_SDC 13
+#define TX_CPU_EVT_SW7 14
+#define TX_CPU_EVT_HOST_COALES 15
+#define TX_CPU_EVT_SW8 16
+#define TX_CPU_EVT_HIGH_DMA_WR 17
+#define TX_CPU_EVT_HIGH_DMA_RD 18
+#define TX_CPU_EVT_SW9 19
+#define TX_CPU_EVT_DMA_ATTN 20
+#define TX_CPU_EVT_LOW_P_MBOX 21
+#define TX_CPU_EVT_HIGH_P_MBOX 22
+#define TX_CPU_EVT_SW10 23
+#define TX_CPU_EVT_RX_CPU_ATTN 24
+#define TX_CPU_EVT_MAC_ATTN 25
+#define TX_CPU_EVT_TX_CPU_ATTN 26
+#define TX_CPU_EVT_FLOW_ATTN 27
+#define TX_CPU_EVT_SW11 28
+#define TX_CPU_EVT_TIMER 29
+#define TX_CPU_EVT_SW12 30
+#define TX_CPU_EVT_SW13 31
+
+
+/* TX-CPU event */
+#define TX_CPU_EVENT_SW_EVENT0 (1 << TX_CPU_EVT_SW0)
+#define TX_CPU_EVENT_SW_EVENT1 (1 << TX_CPU_EVT_SW1)
+#define TX_CPU_EVENT_SW_EVENT2 (1 << TX_CPU_EVT_SW2)
+#define TX_CPU_EVENT_SW_EVENT3 (1 << TX_CPU_EVT_SW3)
+#define TX_CPU_EVENT_TX_MAC (1 << TX_CPU_EVT_TX_MAC)
+#define TX_CPU_EVENT_SW_EVENT4 (1 << TX_CPU_EVT_SW4)
+#define TX_CPU_EVENT_SBDC (1 << TX_CPU_EVT_SBDC)
+#define TX_CPU_EVENT_SW_EVENT5 (1 << TX_CPU_EVT_SW5)
+#define TX_CPU_EVENT_SDI (1 << TX_CPU_EVT_SDI)
+#define TX_CPU_EVENT_DMA_WR (1 << TX_CPU_EVT_DMA_WR)
+#define TX_CPU_EVENT_DMA_RD (1 << TX_CPU_EVT_DMA_RD)
+#define TX_CPU_EVENT_SWQ (1 << TX_CPU_EVT_SWQ)
+#define TX_CPU_EVENT_SW_EVENT6 (1 << TX_CPU_EVT_SW6)
+#define TX_CPU_EVENT_SDC (1 << TX_CPU_EVT_SDC)
+#define TX_CPU_EVENT_SW_EVENT7 (1 << TX_CPU_EVT_SW7)
+#define TX_CPU_EVENT_HOST_COALES (1 << TX_CPU_EVT_HOST_COALES)
+#define TX_CPU_EVENT_SW_EVENT8 (1 << TX_CPU_EVT_SW8)
+#define TX_CPU_EVENT_HIGH_DMA_WR (1 << TX_CPU_EVT_HIGH_DMA_WR)
+#define TX_CPU_EVENT_HIGH_DMA_RD (1 << TX_CPU_EVT_HIGH_DMA_RD)
+#define TX_CPU_EVENT_SW_EVENT9 (1 << TX_CPU_EVT_SW9)
+#define TX_CPU_EVENT_DMA_ATTN (1 << TX_CPU_EVT_DMA_ATTN)
+#define TX_CPU_EVENT_LOW_P_MBOX (1 << TX_CPU_EVT_LOW_P_MBOX)
+#define TX_CPU_EVENT_HIGH_P_MBOX (1 << TX_CPU_EVT_HIGH_P_MBOX)
+#define TX_CPU_EVENT_SW_EVENT10 (1 << TX_CPU_EVT_SW10)
+#define TX_CPU_EVENT_RX_CPU_ATTN (1 << TX_CPU_EVT_RX_CPU_ATTN)
+#define TX_CPU_EVENT_MAC_ATTN (1 << TX_CPU_EVT_MAC_ATTN)
+#define TX_CPU_EVENT_TX_CPU_ATTN (1 << TX_CPU_EVT_TX_CPU_ATTN)
+#define TX_CPU_EVENT_FLOW_ATTN (1 << TX_CPU_EVT_FLOW_ATTN)
+#define TX_CPU_EVENT_SW_EVENT11 (1 << TX_CPU_EVT_SW11)
+#define TX_CPU_EVENT_TIMER (1 << TX_CPU_EVT_TIMER)
+#define TX_CPU_EVENT_SW_EVENT12 (1 << TX_CPU_EVT_SW12)
+#define TX_CPU_EVENT_SW_EVENT13 (1 << TX_CPU_EVT_SW13)
+
+
+#define TX_CPU_MASK (TX_CPU_EVENT_SW_EVENT0 | \
+ TX_CPU_EVENT_SDI | \
+ TX_CPU_EVENT_SDC)
+
+
+#define T3_FTQ_TYPE1_UNDERFLOW_BIT (1 << 29)
+#define T3_FTQ_TYPE1_PASS_BIT (1 << 30)
+#define T3_FTQ_TYPE1_SKIP_BIT (1 << 31)
+
+#define T3_FTQ_TYPE2_UNDERFLOW_BIT (1 << 13)
+#define T3_FTQ_TYPE2_PASS_BIT (1 << 14)
+#define T3_FTQ_TYPE2_SKIP_BIT (1 << 15)
+
+#define T3_QID_DMA_READ 1
+#define T3_QID_DMA_HIGH_PRI_READ 2
+#define T3_QID_DMA_COMP_DX 3
+#define T3_QID_SEND_BD_COMP 4
+#define T3_QID_SEND_DATA_INITIATOR 5
+#define T3_QID_DMA_WRITE 6
+#define T3_QID_DMA_HIGH_PRI_WRITE 7
+#define T3_QID_SW_TYPE_1 8
+#define T3_QID_SEND_DATA_COMP 9
+#define T3_QID_HOST_COALESCING 10
+#define T3_QID_MAC_TX 11
+#define T3_QID_MBUF_CLUSTER_FREE 12
+#define T3_QID_RX_BD_COMP 13
+#define T3_QID_RX_LIST_PLM 14
+#define T3_QID_RX_DATA_BD_INITIATOR 15
+#define T3_QID_RX_DATA_COMP 16
+#define T3_QID_SW_TYPE2 17
+
+LM_STATUS LM_LoadFirmware(PLM_DEVICE_BLOCK pDevice,
+ PT3_FWIMG_INFO pFwImg,
+ LM_UINT32 LoadCpu,
+ LM_UINT32 StartCpu);
+
+/******************************************************************************/
+/* NIC register read/write macros. */
+/******************************************************************************/
+
+#if 0 /* Jimmy */
+/* MAC register access. */
+LM_UINT32 LM_RegRdInd(PLM_DEVICE_BLOCK pDevice, LM_UINT32 Register);
+LM_VOID LM_RegWrInd(PLM_DEVICE_BLOCK pDevice, LM_UINT32 Register,
+ LM_UINT32 Value32);
+
+/* MAC memory access. */
+LM_UINT32 LM_MemRdInd(PLM_DEVICE_BLOCK pDevice, LM_UINT32 MemAddr);
+LM_VOID LM_MemWrInd(PLM_DEVICE_BLOCK pDevice, LM_UINT32 MemAddr,
+ LM_UINT32 Value32);
+
+#if PCIX_TARGET_WORKAROUND
+
+/* use memory-mapped accesses for mailboxes and reads, UNDI accesses
+ for writes to all other registers */
+#define REG_RD(pDevice, OffsetName) \
+ readl(&((pDevice)->pMemView->OffsetName))
+
+#define REG_WR(pDevice, OffsetName, Value32) \
+ (((OFFSETOF(T3_STD_MEM_MAP, OffsetName) >=0x200 ) && \
+ (OFFSETOF(T3_STD_MEM_MAP, OffsetName) <0x400)) || \
+ ((pDevice)->EnablePciXFix == FALSE)) ? \
+ (void) writel(Value32, &((pDevice)->pMemView->OffsetName)) : \
+ LM_RegWrInd(pDevice, OFFSETOF(T3_STD_MEM_MAP, OffsetName), Value32)
+
+#define MB_REG_RD(pDevice, OffsetName) \
+ readl(&((pDevice)->pMemView->OffsetName))
+
+#define MB_REG_WR(pDevice, OffsetName, Value32) \
+ writel(Value32, &((pDevice)->pMemView->OffsetName))
+
+#define REG_RD_OFFSET(pDevice, Offset) \
+ readl(&((LM_UINT8 *) (pDevice)->pMemView + Offset))
+
+#define REG_WR_OFFSET(pDevice, Offset, Value32) \
+ (((Offset >=0x200 ) && (Offset < 0x400)) || \
+ ((pDevice)->EnablePciXFix == FALSE)) ? \
+ (void) writel(Value32, ((LM_UINT8 *) (pDevice)->pMemView + Offset)) : \
+ LM_RegWrInd(pDevice, Offset, Value32)
+
+#define MEM_RD(pDevice, AddrName) \
+ LM_MemRdInd(pDevice, OFFSETOF(T3_FIRST_32K_SRAM, AddrName))
+#define MEM_WR(pDevice, AddrName, Value32) \
+ LM_MemWrInd(pDevice, OFFSETOF(T3_FIRST_32K_SRAM, AddrName), Value32)
+
+#define MEM_RD_OFFSET(pDevice, Offset) \
+ LM_MemRdInd(pDevice, Offset)
+#define MEM_WR_OFFSET(pDevice, Offset, Value32) \
+ LM_MemWrInd(pDevice, Offset, Value32)
+
+#else /* normal target access path below */
+
+/* Register access. */
+#define REG_RD(pDevice, OffsetName) \
+ readl(&((pDevice)->pMemView->OffsetName))
+#define REG_WR(pDevice, OffsetName, Value32) \
+ writel(Value32, &((pDevice)->pMemView->OffsetName))
+
+#define REG_RD_OFFSET(pDevice, Offset) \
+ readl(((LM_UINT8 *) (pDevice)->pMemView + Offset))
+#define REG_WR_OFFSET(pDevice, Offset, Value32) \
+ writel(Value32, ((LM_UINT8 *) (pDevice)->pMemView + Offset))
+
+
+/* There could be problem access the memory window directly. For now, */
+/* we have to go through the PCI configuration register. */
+#define MEM_RD(pDevice, AddrName) \
+ LM_MemRdInd(pDevice, OFFSETOF(T3_FIRST_32K_SRAM, AddrName))
+#define MEM_WR(pDevice, AddrName, Value32) \
+ LM_MemWrInd(pDevice, OFFSETOF(T3_FIRST_32K_SRAM, AddrName), Value32)
+
+#define MEM_RD_OFFSET(pDevice, Offset) \
+ LM_MemRdInd(pDevice, Offset)
+#define MEM_WR_OFFSET(pDevice, Offset, Value32) \
+ LM_MemWrInd(pDevice, Offset, Value32)
+
+#endif /* PCIX_TARGET_WORKAROUND */
+
+#endif /* Jimmy, merging */
+
+ /* Jimmy...rest of file is new stuff! */
+/******************************************************************************/
+/* NIC register read/write macros. */
+/******************************************************************************/
+
+/* MAC register access. */
+LM_UINT32 LM_RegRdInd(PLM_DEVICE_BLOCK pDevice, LM_UINT32 Register);
+LM_VOID LM_RegWrInd(PLM_DEVICE_BLOCK pDevice, LM_UINT32 Register,
+ LM_UINT32 Value32);
+
+/* MAC memory access. */
+LM_UINT32 LM_MemRdInd(PLM_DEVICE_BLOCK pDevice, LM_UINT32 MemAddr);
+LM_VOID LM_MemWrInd(PLM_DEVICE_BLOCK pDevice, LM_UINT32 MemAddr,
+ LM_UINT32 Value32);
+
+#define MB_REG_WR(pDevice, OffsetName, Value32) \
+ ((pDevice)->UndiFix) ? \
+ LM_RegWrInd(pDevice, OFFSETOF(T3_STD_MEM_MAP, OffsetName)+0x5600, \
+ Value32) : \
+ (void) __raw_writel(Value32, &((pDevice)->pMemView->OffsetName))
+
+#define MB_REG_RD(pDevice, OffsetName) \
+ (((pDevice)->UndiFix) ? \
+ LM_RegRdInd(pDevice, OFFSETOF(T3_STD_MEM_MAP, OffsetName)+0x5600) : \
+ __raw_readl(&((pDevice)->pMemView->OffsetName)))
+
+#define REG_RD(pDevice, OffsetName) \
+ (((pDevice)->UndiFix) ? \
+ LM_RegRdInd(pDevice, OFFSETOF(T3_STD_MEM_MAP, OffsetName)) : \
+ __raw_readl(&((pDevice)->pMemView->OffsetName)))
+
+#if PCIX_TARGET_WORKAROUND
+
+#define REG_WR(pDevice, OffsetName, Value32) \
+ ((pDevice)->EnablePciXFix == FALSE) ? \
+ (void) __raw_writel(Value32, &((pDevice)->pMemView->OffsetName)) : \
+ LM_RegWrInd(pDevice, OFFSETOF(T3_STD_MEM_MAP, OffsetName), Value32)
+
+#else
+
+#define REG_WR(pDevice, OffsetName, Value32) \
+ __raw_writel(Value32, &((pDevice)->pMemView->OffsetName))
+
+#endif
+
+#define MEM_RD(pDevice, AddrName) \
+ LM_MemRdInd(pDevice, OFFSETOF(T3_FIRST_32K_SRAM, AddrName))
+#define MEM_WR(pDevice, AddrName, Value32) \
+ LM_MemWrInd(pDevice, OFFSETOF(T3_FIRST_32K_SRAM, AddrName), Value32)
+
+#define MEM_RD_OFFSET(pDevice, Offset) \
+ LM_MemRdInd(pDevice, Offset)
+#define MEM_WR_OFFSET(pDevice, Offset, Value32) \
+ LM_MemWrInd(pDevice, Offset, Value32)
+
+#endif /* TIGON3_H */
+
--- /dev/null
+/*
+ * (C) Copyright 2001
+ * Erik Theisen, Wave 7 Optics, etheisen@mindspring.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
+ */
+
+/*
+ * Dallas Semiconductor's DS1621 Digital Thermometer and Thermostat.
+ */
+
+#include <common.h>
+
+#ifdef CONFIG_DTT_DS1621
+#if !defined(CFG_EEPROM_PAGE_WRITE_ENABLE) || \
+ (CFG_EEPROM_PAGE_WRITE_BITS < 1)
+# error "CFG_EEPROM_PAGE_WRITE_ENABLE must be defined and CFG_EEPROM_PAGE_WRITE_BITS must be greater than 1 to use CONFIG_DTT_DS1621"
+#endif
+#include <i2c.h>
+#include <dtt.h>
+
+/*
+ * Device code
+ */
+#define DTT_I2C_DEV_CODE 0x48 /* Dallas Semi's DS1621 */
+
+int dtt_read(int sensor, int reg)
+{
+ int dlen;
+ uchar data[2];
+
+ /*
+ * Calculate sensor address and command.
+ *
+ */
+ sensor = DTT_I2C_DEV_CODE + (sensor & 0x07); /* Calculate addr of ds1621*/
+
+ /*
+ * Prepare to handle 2 byte result.
+ */
+ if ((reg == DTT_READ_TEMP) ||
+ (reg == DTT_TEMP_HIGH) || (reg == DTT_TEMP_LOW))
+ dlen = 2;
+ else
+ dlen = 1;
+
+ /*
+ * Now try to read the register.
+ */
+ if (i2c_read(sensor, reg, 1, data, dlen) != 0)
+ return 1;
+
+ /*
+ * Handle 2 byte result.
+ */
+ if (dlen == 2)
+ return ((int)((short)data[1] + (((short)data[0]) << 8)));
+
+ return (int)data[0];
+} /* dtt_read() */
+
+
+int dtt_write(int sensor, int reg, int val)
+{
+ int dlen;
+ uchar data[2];
+
+ /*
+ * Calculate sensor address and register.
+ *
+ */
+ sensor = DTT_I2C_DEV_CODE + (sensor & sensor);
+
+ /*
+ * Handle various data sizes.
+ */
+ if ((reg == DTT_READ_TEMP) ||
+ (reg == DTT_TEMP_HIGH) || (reg == DTT_TEMP_LOW)) {
+ dlen = 2;
+ data[0] = (char)((val >> 8) & 0xff); /* MSB first */
+ data[1] = (char)(val & 0xff);
+ }
+ else if ((reg == DTT_WRITE_START_CONV) || (reg == DTT_WRITE_STOP_CONV)) {
+ dlen = 0;
+ data[0] = (char)0;
+ data[1] = (char)0;
+ }
+ else {
+ dlen = 1;
+ data[0] = (char)(val & 0xff);
+ }
+
+ /*
+ * Write value to device.
+ */
+ if (i2c_write(sensor, reg, 1, data, dlen) != 0)
+ return 1;
+
+ return 0;
+} /* dtt_write() */
+
+
+static int _dtt_init(int sensor)
+{
+ int val;
+
+ /*
+ * Setup High Temp.
+ */
+ val = ((CFG_DTT_MAX_TEMP * 2) << 7) & 0xff80;
+ if (dtt_write(sensor, DTT_TEMP_HIGH, val) != 0)
+ return 1;
+ udelay(50000); /* Max 50ms */
+
+ /*
+ * Setup Low Temp - hysteresis.
+ */
+ val = (((CFG_DTT_MAX_TEMP - CFG_DTT_HYSTERESIS) * 2) << 7) & 0xff80;
+ if (dtt_write(sensor, DTT_TEMP_LOW, val) != 0)
+ return 1;
+ udelay(50000); /* Max 50ms */
+
+ /*
+ * Setup configuraton register
+ *
+ * Clear THF & TLF, Reserved = 1, Polarity = Active Low, One Shot = YES
+ *
+ * We run in polled mode, since there isn't any way to know if this
+ * lousy device is ready to provide temperature readings on power up.
+ */
+ val = 0x9;
+ if (dtt_write(sensor, DTT_CONFIG, val) != 0)
+ return 1;
+ udelay(50000); /* Max 50ms */
+
+ return 0;
+} /* _dtt_init() */
+
+
+int dtt_init (void)
+{
+ int i;
+ unsigned char sensors[] = CONFIG_DTT_SENSORS;
+
+ for (i = 0; i < sizeof(sensors); i++) {
+ if (_dtt_init(sensors[i]) != 0)
+ printf("DTT%d: FAILED\n", i+1);
+ else
+ printf("DTT%d: %i C\n", i+1, dtt_get_temp(sensors[i]));
+ }
+
+ return (0);
+} /* dtt_init() */
+
+
+int dtt_get_temp(int sensor)
+{
+ int i;
+
+ /*
+ * Start a conversion, may take up to 1 second.
+ */
+ dtt_write(sensor, DTT_WRITE_START_CONV, 0);
+ for (i = 0; i <= 10; i++) {
+ udelay(100000);
+ if (dtt_read(sensor, DTT_CONFIG) & 0x80)
+ break;
+ }
+
+ return (dtt_read(sensor, DTT_READ_TEMP) / 256);
+} /* dtt_get_temp() */
+
+
+#endif /* CONFIG_DTT_DS1621 */
+
--- /dev/null
+/*
+ * (C) Copyright 2001
+ * Bill Hunter, Wave 7 Optics, williamhunter@mediaone.net
+ *
+ * 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
+ */
+
+/*
+ * On Semiconductor's LM75 Temperature Sensor
+ */
+
+#include <common.h>
+
+#ifdef CONFIG_DTT_LM75
+#if !defined(CFG_EEPROM_PAGE_WRITE_ENABLE) || \
+ (CFG_EEPROM_PAGE_WRITE_BITS < 1)
+# error "CFG_EEPROM_PAGE_WRITE_ENABLE must be defined and CFG_EEPROM_PAGE_WRITE_BITS must be greater than 1 to use CONFIG_DTT_LM75"
+#endif
+
+#include <i2c.h>
+#include <dtt.h>
+
+
+/*
+ * Device code
+ */
+#define DTT_I2C_DEV_CODE 0x48 /* ON Semi's LM75 device */
+
+int dtt_read(int sensor, int reg)
+{
+ int dlen;
+ uchar data[2];
+
+ /*
+ * Validate 'reg' param
+ */
+ if((reg < 0) || (reg > 3))
+ return -1;
+
+ /*
+ * Calculate sensor address and register.
+ */
+ sensor = DTT_I2C_DEV_CODE + (sensor & 0x07); /* calculate address of lm75 */
+
+ /*
+ * Prepare to handle 2 byte result.
+ */
+ if ((reg == DTT_READ_TEMP) ||
+ (reg == DTT_TEMP_HYST) ||
+ (reg == DTT_TEMP_SET))
+ dlen = 2;
+ else
+ dlen = 1;
+
+ /*
+ * Now try to read the register.
+ */
+ if (i2c_read(sensor, reg, 1, data, dlen) != 0)
+ return -1;
+
+ /*
+ * Handle 2 byte result.
+ */
+ if (dlen == 2)
+ return ((int)((short)data[1] + (((short)data[0]) << 8)));
+
+
+ return (int)data[0];
+} /* dtt_read() */
+
+
+int dtt_write(int sensor, int reg, int val)
+{
+ int dlen;
+ uchar data[2];
+
+ /*
+ * Validate 'reg' param
+ */
+ if ((reg < 0) || (reg > 3))
+ return 1;
+
+ /*
+ * Calculate sensor address and register.
+ */
+ sensor = DTT_I2C_DEV_CODE + (sensor & 0x07); /* calculate address of lm75 */
+
+ /*
+ * Handle 2 byte values.
+ */
+ if ((reg == DTT_READ_TEMP) ||
+ (reg == DTT_TEMP_HYST) ||
+ (reg == DTT_TEMP_SET)) {
+ dlen = 2;
+ data[0] = (char)((val >> 8) & 0xff); /* MSB first */
+ data[1] = (char)(val & 0xff);
+ } else {
+ dlen = 1;
+ data[0] = (char)(val & 0xff);
+ }
+
+ /*
+ * Write value to register.
+ */
+ if (i2c_write(sensor, reg, 1, data, dlen) != 0)
+ return 1;
+
+ return 0;
+} /* dtt_write() */
+
+
+static int _dtt_init(int sensor)
+{
+ int val;
+
+ /*
+ * Setup TSET ( trip point ) register
+ */
+ val = ((CFG_DTT_MAX_TEMP * 2) << 7) & 0xff80; /* trip */
+ if (dtt_write(sensor, DTT_TEMP_SET, val) != 0)
+ return 1;
+
+ /*
+ * Setup THYST ( untrip point ) register - Hysteresis
+ */
+ val = (((CFG_DTT_MAX_TEMP - CFG_DTT_HYSTERESIS) * 2) << 7) & 0xff80;
+ if (dtt_write(sensor, DTT_TEMP_HYST, val) != 0)
+ return 1;
+
+ /*
+ * Setup configuraton register
+ */
+ /* config = 6 sample integration, int mode, active low, and enable */
+ val = 0x18;
+ if (dtt_write(sensor, DTT_CONFIG, val) != 0)
+ return 1;
+
+ return 0;
+} /* _dtt_init() */
+
+
+int dtt_init (void)
+{
+ int i;
+ unsigned char sensors[] = CONFIG_DTT_SENSORS;
+ const char *const header = "DTT: ";
+
+ for (i = 0; i < sizeof(sensors); i++) {
+ if (_dtt_init(sensors[i]) != 0)
+ printf("%s%d FAILED INIT\n", header, i+1);
+ else
+ printf("%s%d is %i C\n", header, i+1,
+ dtt_get_temp(sensors[i]));
+ }
+
+ return (0);
+} /* dtt_init() */
+
+int dtt_get_temp(int sensor)
+{
+ return (dtt_read(sensor, DTT_READ_TEMP) / 256);
+} /* dtt_get_temp() */
+
+#endif /* CONFIG_DTT_LM75 */
+
--- /dev/null
+/*
+ * (C) Copyright 2002
+ * Rich Ireland, Enterasys Networks, rireland@enterasys.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 <fpga.h>
+
+#ifndef _ALTERA_H_
+#define _ALTERA_H_
+
+/*
+ * Note that this is just Altera FPGA interface boilerplate.
+ * There is no support for Altera devices yet.
+ *
+ * See include/xilinx.h for a working example.
+ */
+
+/* In your board's config.h file you should define CONFIG_FPGA as such:
+ * #define CONFIG_FPGA (CFG_ALTERA_xxx | CFG_ALTERA_IF_xxx )
+ */
+
+/* Altera Model definitions */
+#define CFG_ALTERA_xxxx ( CFG_FPGA_ALTERA | CFG_FPGA_DEV( 0x1 ))
+/* Add new models here */
+
+/* Altera Interface definitions */
+#define CFG_ALTERA_IF_xxx CFG_FPGA_IF( 0x1 )
+/* Add new interfaces here */
+
+typedef enum { /* typedef Altera_iface */
+ min_altera_iface_type, /* insert all new types after this */
+/* Add new interfaces here */
+ max_altera_iface_type /* insert all new types before this */
+} Altera_iface; /* end, typedef Altera_iface */
+
+typedef enum { /* typedef Altera_Family */
+ min_altera_type, /* insert all new types after this */
+/* Add new models here */
+ max_altera_type /* insert all new types before this */
+} Altera_Family; /* end, typedef Altera_Family */
+
+typedef struct { /* typedef Altera_desc */
+ Altera_Family family; /* part type */
+ Altera_iface iface; /* interface type */
+ size_t size; /* bytes of data part can accept */
+ void * base; /* base interface address */
+} Altera_desc; /* end, typedef Altera_desc */
+
+extern int altera_load( Altera_desc *desc, void *image, size_t size );
+extern int altera_dump( Altera_desc *desc, void *buf, size_t bsize );
+extern int altera_info( Altera_desc *desc );
+extern int altera_reloc( Altera_desc *desc, ulong reloc_off );
+
+#endif /* _ALTERA_H_ */
--- /dev/null
+/*
+ * Copyright 1995, Russell King.
+ * Various bits and pieces copyrights include:
+ * Linus Torvalds (test_bit).
+ *
+ * bit 0 is the LSB of addr; bit 32 is the LSB of (addr+1).
+ *
+ * Please note that the code in this file should never be included
+ * from user space. Many of these are not implemented in assembler
+ * since they would be too costly. Also, they require priviledged
+ * instructions (which are not available from user mode) to ensure
+ * that they are atomic.
+ */
+
+#ifndef __ASM_ARM_BITOPS_H
+#define __ASM_ARM_BITOPS_H
+
+#ifdef __KERNEL__
+
+#define smp_mb__before_clear_bit() do { } while (0)
+#define smp_mb__after_clear_bit() do { } while (0)
+
+/*
+ * Function prototypes to keep gcc -Wall happy.
+ */
+extern void set_bit(int nr, volatile void * addr);
+
+static inline void __set_bit(int nr, volatile void *addr)
+{
+ ((unsigned char *) addr)[nr >> 3] |= (1U << (nr & 7));
+}
+
+extern void clear_bit(int nr, volatile void * addr);
+
+static inline void __clear_bit(int nr, volatile void *addr)
+{
+ ((unsigned char *) addr)[nr >> 3] &= ~(1U << (nr & 7));
+}
+
+extern void change_bit(int nr, volatile void * addr);
+
+static inline void __change_bit(int nr, volatile void *addr)
+{
+ ((unsigned char *) addr)[nr >> 3] ^= (1U << (nr & 7));
+}
+
+extern int test_and_set_bit(int nr, volatile void * addr);
+
+static inline int __test_and_set_bit(int nr, volatile void *addr)
+{
+ unsigned int mask = 1 << (nr & 7);
+ unsigned int oldval;
+
+ oldval = ((unsigned char *) addr)[nr >> 3];
+ ((unsigned char *) addr)[nr >> 3] = oldval | mask;
+ return oldval & mask;
+}
+
+extern int test_and_clear_bit(int nr, volatile void * addr);
+
+static inline int __test_and_clear_bit(int nr, volatile void *addr)
+{
+ unsigned int mask = 1 << (nr & 7);
+ unsigned int oldval;
+
+ oldval = ((unsigned char *) addr)[nr >> 3];
+ ((unsigned char *) addr)[nr >> 3] = oldval & ~mask;
+ return oldval & mask;
+}
+
+extern int test_and_change_bit(int nr, volatile void * addr);
+
+static inline int __test_and_change_bit(int nr, volatile void *addr)
+{
+ unsigned int mask = 1 << (nr & 7);
+ unsigned int oldval;
+
+ oldval = ((unsigned char *) addr)[nr >> 3];
+ ((unsigned char *) addr)[nr >> 3] = oldval ^ mask;
+ return oldval & mask;
+}
+
+extern int find_first_zero_bit(void * addr, unsigned size);
+extern int find_next_zero_bit(void * addr, int size, int offset);
+
+/*
+ * This routine doesn't need to be atomic.
+ */
+static inline int test_bit(int nr, const void * addr)
+{
+ return ((unsigned char *) addr)[nr >> 3] & (1U << (nr & 7));
+}
+
+/*
+ * ffz = Find First Zero in word. Undefined if no zero exists,
+ * so code should check against ~0UL first..
+ */
+static inline unsigned long ffz(unsigned long word)
+{
+ int k;
+
+ word = ~word;
+ k = 31;
+ if (word & 0x0000ffff) { k -= 16; word <<= 16; }
+ if (word & 0x00ff0000) { k -= 8; word <<= 8; }
+ if (word & 0x0f000000) { k -= 4; word <<= 4; }
+ if (word & 0x30000000) { k -= 2; word <<= 2; }
+ if (word & 0x40000000) { k -= 1; }
+ return k;
+}
+
+/*
+ * ffs: find first bit set. This is defined the same way as
+ * the libc and compiler builtin ffs routines, therefore
+ * differs in spirit from the above ffz (man ffs).
+ */
+
+#define ffs(x) generic_ffs(x)
+
+/*
+ * hweightN: returns the hamming weight (i.e. the number
+ * of bits set) of a N-bit word
+ */
+
+#define hweight32(x) generic_hweight32(x)
+#define hweight16(x) generic_hweight16(x)
+#define hweight8(x) generic_hweight8(x)
+
+#define ext2_set_bit test_and_set_bit
+#define ext2_clear_bit test_and_clear_bit
+#define ext2_test_bit test_bit
+#define ext2_find_first_zero_bit find_first_zero_bit
+#define ext2_find_next_zero_bit find_next_zero_bit
+
+/* Bitmap functions for the minix filesystem. */
+#define minix_test_and_set_bit(nr,addr) test_and_set_bit(nr,addr)
+#define minix_set_bit(nr,addr) set_bit(nr,addr)
+#define minix_test_and_clear_bit(nr,addr) test_and_clear_bit(nr,addr)
+#define minix_test_bit(nr,addr) test_bit(nr,addr)
+#define minix_find_first_zero_bit(addr,size) find_first_zero_bit(addr,size)
+
+#endif /* __KERNEL__ */
+
+#endif /* _ARM_BITOPS_H */
--- /dev/null
+/*
+ * linux/include/asm-arm/proc-armv/ptrace.h
+ *
+ * Copyright (C) 1996-1999 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef __ASM_PROC_PTRACE_H
+#define __ASM_PROC_PTRACE_H
+
+#include <linux/config.h>
+
+#define USR26_MODE 0x00
+#define FIQ26_MODE 0x01
+#define IRQ26_MODE 0x02
+#define SVC26_MODE 0x03
+#define USR_MODE 0x10
+#define FIQ_MODE 0x11
+#define IRQ_MODE 0x12
+#define SVC_MODE 0x13
+#define ABT_MODE 0x17
+#define UND_MODE 0x1b
+#define SYSTEM_MODE 0x1f
+#define MODE_MASK 0x1f
+#define T_BIT 0x20
+#define F_BIT 0x40
+#define I_BIT 0x80
+#define CC_V_BIT (1 << 28)
+#define CC_C_BIT (1 << 29)
+#define CC_Z_BIT (1 << 30)
+#define CC_N_BIT (1 << 31)
+#define PCMASK 0
+
+#ifndef __ASSEMBLY__
+
+/* this struct defines the way the registers are stored on the
+ stack during a system call. */
+
+struct pt_regs {
+ long uregs[18];
+};
+
+#define ARM_cpsr uregs[16]
+#define ARM_pc uregs[15]
+#define ARM_lr uregs[14]
+#define ARM_sp uregs[13]
+#define ARM_ip uregs[12]
+#define ARM_fp uregs[11]
+#define ARM_r10 uregs[10]
+#define ARM_r9 uregs[9]
+#define ARM_r8 uregs[8]
+#define ARM_r7 uregs[7]
+#define ARM_r6 uregs[6]
+#define ARM_r5 uregs[5]
+#define ARM_r4 uregs[4]
+#define ARM_r3 uregs[3]
+#define ARM_r2 uregs[2]
+#define ARM_r1 uregs[1]
+#define ARM_r0 uregs[0]
+#define ARM_ORIG_r0 uregs[17]
+
+#ifdef __KERNEL__
+
+#define user_mode(regs) \
+ (((regs)->ARM_cpsr & 0xf) == 0)
+
+#ifdef CONFIG_ARM_THUMB
+#define thumb_mode(regs) \
+ (((regs)->ARM_cpsr & T_BIT))
+#else
+#define thumb_mode(regs) (0)
+#endif
+
+#define processor_mode(regs) \
+ ((regs)->ARM_cpsr & MODE_MASK)
+
+#define interrupts_enabled(regs) \
+ (!((regs)->ARM_cpsr & I_BIT))
+
+#define fast_interrupts_enabled(regs) \
+ (!((regs)->ARM_cpsr & F_BIT))
+
+#define condition_codes(regs) \
+ ((regs)->ARM_cpsr & (CC_V_BIT|CC_C_BIT|CC_Z_BIT|CC_N_BIT))
+
+/* Are the current registers suitable for user mode?
+ * (used to maintain security in signal handlers)
+ */
+static inline int valid_user_regs(struct pt_regs *regs)
+{
+ if ((regs->ARM_cpsr & 0xf) == 0 &&
+ (regs->ARM_cpsr & (F_BIT|I_BIT)) == 0)
+ return 1;
+
+ /*
+ * Force CPSR to something logical...
+ */
+ regs->ARM_cpsr &= (CC_V_BIT|CC_C_BIT|CC_Z_BIT|CC_N_BIT|0x10);
+
+ return 0;
+}
+
+#endif /* __KERNEL__ */
+
+#endif /* __ASSEMBLY__ */
+
+#endif
+
--- /dev/null
+/*
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Marius Groeger <mgroeger@sysgo.de>
+ *
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Alex Zuepke <azu@sysgo.de>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef _U_BOOT_ARM_H_
+#define _U_BOOT_ARM_H_ 1
+
+/* for the following variables, see start.S */
+extern ulong _armboot_start; /* code start */
+extern ulong _armboot_end_data; /* code + data end */
+extern ulong _armboot_end; /* BSS end */
+extern ulong IRQ_STACK_START; /* top of IRQ stack */
+extern ulong FIQ_STACK_START; /* top of FIQ stack */
+extern ulong _armboot_real_end; /* first usable RAM address */
+
+/* cpu/.../cpu.c */
+int cpu_init(void);
+int cleanup_before_linux(void);
+
+/* board/.../... */
+int board_init(void);
+int dram_init (void);
+
+/* ------------------------------------------------------------ */
+/* Here is a list of some prototypes which are incompatible to */
+/* the U-Boot implementation */
+/* To be fixed! */
+/* ------------------------------------------------------------ */
+/* common/cmd_nvedit.c */
+void setenv (char *, char *);
+
+/* cpu/.../interrupt.c */
+void reset_timer_masked (void);
+ulong get_timer_masked (void);
+void udelay_masked (unsigned long usec);
+
+#endif /* _U_BOOT_ARM_H_ */
--- /dev/null
+/*
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Marius Groeger <mgroeger@sysgo.de>
+ *
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Alex Zuepke <azu@sysgo.de>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef _U_BOOT_H_
+#define _U_BOOT_H_ 1
+
+typedef struct bd_info {
+ int bi_baudrate; /* serial console baudrate */
+ unsigned long bi_ip_addr; /* IP Address */
+ unsigned char bi_enetaddr[6]; /* Ethernet adress */
+ struct environment_s *bi_env;
+ ulong bi_arch_number; /* unique id for this board */
+ ulong bi_boot_params; /* where this board expects params */
+ struct /* RAM configuration */
+ {
+ ulong start;
+ ulong size;
+ } bi_dram[CONFIG_NR_DRAM_BANKS];
+} bd_t;
+
+#define bi_env_data bi_env->data
+#define bi_env_crc bi_env->crc
+
+#endif /* _U_BOOT_H_ */
--- /dev/null
+/*
+ * (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
+ */
+
+#ifndef _CMD_BSP_H_
+#define _CMD_BSP_H_
+
+#include <common.h>
+#include <command.h>
+
+#if (CONFIG_COMMANDS & CFG_CMD_BSP)
+
+/* ----- LWMON -----------------------------------------------------------------
+ */
+#if defined(CONFIG_LWMON)
+
+#define CMD_TBL_BSP MK_CMD_TBL_ENTRY( \
+ "pic", 3, 4, 1, do_pic, \
+ "pic - read and write PIC registers\n", \
+ "read reg - read PIC register `reg'\n" \
+ "pic write reg val - write value `val' to PIC register `reg'\n" \
+), MK_CMD_TBL_ENTRY( \
+ "kbd", 3, 1, 1, do_kbd, \
+ "kbd - read keyboard status\n", \
+ NULL \
+), MK_CMD_TBL_ENTRY( \
+ "lsb", 3, 2, 1, do_lsb, \
+ "lsb - check and set LSB switch\n", \
+ "on - switch LSB on\n" \
+ "lsb off - switch LSB off\n" \
+ "lsb - print current setting\n" \
+),
+int do_pic (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
+int do_kbd (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
+int do_lsb (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
+
+#endif /* CONFIG_LWMON */
+/* ----------------------------------------------------------------------------*/
+
+/* ----- PCU E -----------------------------------------------------------------
+ */
+#if defined(CONFIG_PCU_E)
+
+#define CMD_TBL_BSP MK_CMD_TBL_ENTRY( \
+ "puma", 4, 4, 1, do_puma, \
+ "puma - access PUMA FPGA\n", \
+ "status - print PUMA status\n" \
+ "puma load addr len - load PUMA configuration data\n" \
+),
+int do_puma (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
+
+#endif /* CONFIG_PCU_E */
+/* ----------------------------------------------------------------------------*/
+
+/* ----- CCM/SCM ---------------------------------------------------------------
+ */
+#if defined(CONFIG_CCM) || defined(CONFIG_SCM)
+
+#define CMD_TBL_BSP MK_CMD_TBL_ENTRY( \
+ "fpga", 4, 4, 1, do_fpga, \
+ "fpga - access FPGA(s)\n", \
+ "fpga status [name] - print FPGA status\n" \
+ "fpga reset [name] - reset FPGA\n" \
+ "fpga load [name] addr - load FPGA configuration data\n" \
+),
+int do_fpga (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
+
+#endif /* CONFIG_CCM, CONFIG_SCM */
+/* ----------------------------------------------------------------------------*/
+
+/* ----- PIP405 -----------------------------------------------------------------
+ */
+#if defined(CONFIG_PIP405)
+
+#define CMD_TBL_BSP MK_CMD_TBL_ENTRY( \
+ "pip405", 4, 6, 1, do_pip405, \
+ "pip405 - PIP405 specific Cmds\n", \
+ "flash mem [SrcAddr] - updates U-Boot with image in memory\n" \
+ "pip405 flash floppy [SrcAddr] - updates U-Boot with image from floppy\n" \
+ "pip405 flash mps - updates U-Boot with image from MPS\n" \
+),
+int do_pip405 (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
+
+#endif /* CONFIG_PIP405 */
+/* ----------------------------------------------------------------------------*/
+/* ----- MIP405 -----------------------------------------------------------------
+ */
+#if defined(CONFIG_MIP405)
+
+#define CMD_TBL_BSP MK_CMD_TBL_ENTRY( \
+ "mip405", 4, 6, 1, do_mip405, \
+ "mip405 - MIP405 specific Cmds\n", \
+ "flash mem [SrcAddr] - updates U-Boot with image in memory\n" \
+ "mip405 flash mps - updates U-Boot with image from MPS\n" \
+),
+int do_mip405 (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
+
+#endif /* CONFIG_MIP405 */
+/* ----------------------------------------------------------------------------*/
+
+/* ----- DASA_SIM ---------------------------------------------------------------
+ */
+#if defined(CONFIG_DASA_SIM)
+
+#define CMD_TBL_BSP MK_CMD_TBL_ENTRY( \
+ "pci9054", 7, 3, 1, do_pci9054, \
+ "pci9054 - PLX PCI9054 EEPROM access\n", \
+ "pci9054 info - print EEPROM values\n" \
+ "pci9054 update - updates EEPROM with default values\n" \
+),
+int do_pci9054 (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
+
+#endif /* CONFIG_DASA_SIM */
+/* ----------------------------------------------------------------------------*/
+
+/* ----- HYMOD -----------------------------------------------------------------
+ */
+#if defined(CONFIG_HYMOD)
+
+#define CMD_TBL_BSP MK_CMD_TBL_ENTRY( \
+ "fpga", 4, 6, 1, do_fpga, \
+ "fpga - FPGA sub-system\n", \
+ "load [type] addr size\n" \
+ " - write the configuration data at memory address `addr',\n" \
+ " size `size' bytes, into the FPGA of type `type' (either\n" \
+ " `main' or `mezz', default `main'). e.g.\n" \
+ " `fpga load 100000 7d8f'\n" \
+ " loads the main FPGA with config data at address 100000\n" \
+ " HEX, size 7d8f HEX (32143 DEC) bytes\n" \
+ "fpga tftp file addr\n" \
+ " - transfers `file' from the tftp server into memory at\n" \
+ " address `addr', then writes the entire file contents\n" \
+ " into the main FPGA\n" \
+ "fpga store addr\n" \
+ " - read configuration data from the main FPGA (the mezz\n" \
+ " FPGA is write-only), into address `addr'. There must be\n" \
+ " enough memory available at `addr' to hold all the config\n"\
+ " data - the size of which is determined by VC:???\n" \
+ "fpga info\n" \
+ " - print information about the Hymod FPGA, namely the\n" \
+ " memory addresses at which the four FPGA local bus\n" \
+ " address spaces appear in the physical address space\n" \
+), MK_CMD_TBL_ENTRY( \
+ "eeclear", 4, 1, 0, do_eecl, \
+ "eeclear - Clear the eeprom on a Hymod board \n", \
+ "[type]\n" \
+ " - write zeroes into the EEPROM on the board of type `type'\n"\
+ " (`type' is either `main' or `mezz' - default `main')\n" \
+ " Note: the EEPROM write enable jumper must be installed\n" \
+),
+int do_fpga (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
+int do_eecl (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
+
+#endif /* CONFIG_HYMOD */
+/* ----------------------------------------------------------------------------*/
+/* CRAY405 (L1) */
+#if defined (CONFIG_CRAYL1)
+#define CMD_TBL_BSP MK_CMD_TBL_ENTRY( \
+ "L1cmd", 5, 4, 1, do_crayL1, \
+ "L1cmd - L1 update, setup, commands \n", \
+ "L1cmd update - update flash images from host\n" \
+ "L1cmd boot - nfs or ramboot L1\n" \
+),
+int do_crayL1 (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
+#endif /* CONFIG_CRAY405 */
+/* ----------------------------------------------------------------------------*/
+
+#if defined (CONFIG_EVB64260)
+/* ----- EVB64260 -------------------------------------------------------------*/
+#ifdef CONFIG_ZUMA_V2
+#define CMD_TBL_BSP ZUMA_TBL_ENTRY
+
+#define ZUMA_TBL_ENTRY MK_CMD_TBL_ENTRY( \
+ "zinit", 5, 1, 0, do_zuma_init_pbb, \
+ "zinit - init zuma pbb\n", \
+ "\n" \
+ " - init zuma pbb\n" \
+), MK_CMD_TBL_ENTRY( \
+ "zdtest", 6, 3, 1, do_zuma_test_dma, \
+ "zdtest - run dma test\n", \
+ "[cmd [count]]\n" \
+ " - run dma cmd (w=0,v=1,cp=2,cmp=3,wi=4,vi=5), count bytes\n" \
+), MK_CMD_TBL_ENTRY( \
+ "zminit", 5, 1, 0, do_zuma_init_mbox, \
+ "zminit - init zuma mbox\n", \
+ "\n" \
+ " - init zuma mbox\n" \
+),
+
+int do_zuma_init_pbb (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
+int do_zuma_test_dma (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
+int do_zuma_init_mbox (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
+
+void zuma_init_pbb(void);
+int zuma_mbox_init(void);
+int zuma_test_dma(int cmd, int size);
+#else
+#define CMD_TBL_BSP
+#endif /* ZUMA_NTL */
+
+#endif /* CONFIG_EVB64260 */
+/* ----------------------------------------------------------------------------*/
+
+/* -----W7O--------------------------------------------------------------------*/
+#if defined(CONFIG_W7O)
+
+#define CMD_TBL_BSP MK_CMD_TBL_ENTRY( \
+ "vpd", 3, 2, 1, do_vpd, \
+ "vpd - Read Vital Product Data\n", \
+ "[dev_addr]\n" \
+ " - Read VPD Data from default address, or device address 'dev_addr'.\n" \
+),
+
+extern int do_vpd (cmd_tbl_t *, int, int, char *[]);
+
+#endif /* CONFIG_W7O */
+/* ----------------------------------------------------------------------------*/
+
+/* ---- PCIPPC2 / PCIPPC6 -----------------------------------------------------*/
+#if defined(CONFIG_PCIPPC2) || defined(CONFIG_PCIPPC6)
+#if defined(CONFIG_WATCHDOG)
+
+#define CMD_TBL_BSP MK_CMD_TBL_ENTRY( \
+ "wd", 3, 2, 1, do_wd, \
+ "wd - check and set watchdog\n", \
+ "on - switch watchDog on\n" \
+ "wd off - switch watchdog off\n" \
+ "wd - print current status\n" \
+),
+
+extern int do_wd (cmd_tbl_t *, int, int, char *[]);
+
+#else
+#define CMD_TBL_BSP
+#endif /* CONFIG_WATCHDOG */
+
+#endif /* CONFIG_PCIPPC2 , CONFIG_PCIPPC6 */
+/* ----------------------------------------------------------------------------*/
+
+/* ----- PN62 -----------------------------------------------------------------*/
+#if defined(CONFIG_PN62)
+
+#define CMD_TBL_BSP MK_CMD_TBL_ENTRY( \
+ "loadpci", 5, 2, 1, do_loadpci, \
+ "loadpci - load binary file over PCI\n", \
+ "[addr]\n" \
+ " - load binary file over PCI to address 'addr'\n" \
+), MK_CMD_TBL_ENTRY( \
+ "led" , 3, 3, 1, do_led, \
+ "led - set LED 0..11 on the PN62 board\n", \
+ "i fun\n" \
+ " - set 'i'th LED to function 'fun'\n" \
+),
+
+extern int do_loadpci (cmd_tbl_t *, int, int, char *[]);
+extern int do_led (cmd_tbl_t *, int, int, char *[]);
+#endif /* CONFIG_PN62 */
+/* ----------------------------------------------------------------------------*/
+
+/* ----- TRAB ------------------------------------------------------------------
+ */
+#if defined(CONFIG_TRAB)
+
+#define CMD_TBL_BSP MK_CMD_TBL_ENTRY( \
+ "kbd", 3, 1, 1, do_kbd, \
+ "kbd - read keyboard status\n", \
+ NULL \
+),
+
+int do_kbd (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
+
+#endif /* CONFIG_TRAB */
+/* ----------------------------------------------------------------------------*/
+
+#else
+#define CMD_TBL_BSP
+#endif /* CFG_CMD_BSP */
+
+/* ----- R360MPI ---------------------------------------------------------------
+ */
+#if defined(CONFIG_R360MPI)
+
+#define CMD_TBL_BSP MK_CMD_TBL_ENTRY( \
+ "kbd", 3, 1, 1, do_kbd, \
+ "kbd - read keyboard status\n", \
+ NULL \
+),
+
+int do_kbd (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
+
+#endif /* CONFIG_R360MPI */
+/* ----------------------------------------------------------------------------*/
+
+#endif /* _CMD_BSP_H_ */
--- /dev/null
+/*
+ * (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
+ */
+
+/*
+ *
+ * Configuration settings for the CU824 board.
+ *
+ */
+
+/* ------------------------------------------------------------------------- */
+
+/*
+ * board/config.h - configuration options, board specific
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+/*
+ * High Level Configuration Options
+ * (easy to change)
+ */
+
+#define CONFIG_MPC824X 1
+#define CONFIG_MPC8245 1
+#define CONFIG_BMW 1
+
+#define CONFIG_BCM570x 1 /* Use Broadcom BCM570x Ethernet Driver */
+#define CONFIG_TIGON3 1
+
+#define CONFIG_CONS_INDEX 1
+#define CONFIG_BAUDRATE 9600
+#define CFG_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 }
+
+#define CONFIG_CLOCKS_IN_MHZ 1 /* clocks passsed to Linux in MHz */
+
+#define CONFIG_BOOTCOMMAND "bootm FF820000" /* autoboot command */
+#define CONFIG_BOOTDELAY 5
+
+#define CFG_MAX_DOC_DEVICE 1 /* Only use Onboard TSOP-16MB device */
+#define DOC_PASSIVE_PROBE 1
+#define CFG_DOC_SUPPORT_2000 1
+#define CFG_DOC_SUPPORT_MILLENNIUM 1
+#define CFG_DOC_SHORT_TIMEOUT 1
+#define CONFIG_COMMANDS (CONFIG_CMD_DFL | \
+ CFG_CMD_DATE | \
+ CFG_CMD_DOC | \
+ CFG_CMD_ELF | \
+ 0 )
+#if 0
+#define CONFIG_COMMANDS (CONFIG_CMD_DFL | CFG_CMD_DHCP | \
+ CFG_CMD_PCI | CFG_CMD_DOC | CFG_CMD_DATE)
+
+#define CONFIG_PCI 1
+#define CONFIG_PCI_PNP 1 /* PCI plug-and-play */
+#endif
+
+/* This must be included AFTER the definition of CONFIG_COMMANDS (if any)
+ */
+#include <cmd_confdefs.h>
+
+
+/*
+ * Miscellaneous configurable options
+ */
+#define CFG_LONGHELP /* undef to save memory */
+#define CFG_PROMPT "=>" /* Monitor Command Prompt */
+#define CFG_CBSIZE 256 /* Console I/O Buffer Size */
+
+/* Print Buffer Size
+ */
+#define CFG_PBSIZE (CFG_CBSIZE + sizeof(CFG_PROMPT) + 16)
+
+#define CFG_MAXARGS 8 /* Max number of command args */
+#define CFG_BARGSIZE CFG_CBSIZE /* Boot Argument Buffer Size */
+#define CFG_LOAD_ADDR 0x00100000 /* Default load address */
+
+/*-----------------------------------------------------------------------
+ * Start addresses for the final memory configuration
+ * (Set up by the startup code)
+ * Please note that CFG_SDRAM_BASE _must_ start at 0
+ */
+#define CFG_SDRAM_BASE 0x00000000
+
+#define CFG_FLASH_BASE0_PRELIM 0xFFF00000 /* FLASH bank on RCS#0 */
+#define CFG_FLASH_BASE1_PRELIM 0xFF800000 /* FLASH bank on RCS#1 */
+#define CFG_FLASH_BASE CFG_MONITOR_BASE
+#define CFG_FLASH_BANKS { CFG_FLASH_BASE0_PRELIM , CFG_FLASH_BASE1_PRELIM }
+
+/* even though FLASHP_BASE is FF800000, with 4MB is RCS0, the
+ * reset vector is actually located at FFB00100, but the 8245
+ * takes care of us.
+ */
+#define CFG_RESET_ADDRESS 0xFFF00100
+
+#define CFG_EUMB_ADDR 0xFC000000
+
+#define CFG_MONITOR_BASE TEXT_BASE
+
+#define CFG_MONITOR_LEN (256 << 10) /* Reserve 256 kB for Monitor */
+#define CFG_MALLOC_LEN (2048 << 10) /* Reserve 2MB for malloc() */
+
+#define CFG_MEMTEST_START 0x00004000 /* memtest works on */
+#define CFG_MEMTEST_END 0x04000000 /* 0 ... 32 MB in DRAM */
+
+ /* Maximum amount of RAM.
+ */
+#define CFG_MAX_RAM_SIZE 0x04000000 /* 0 .. 64 MB of (S)DRAM */
+
+
+#if CFG_MONITOR_BASE >= CFG_FLASH_BASE
+#undef CFG_RAMBOOT
+#else
+#define CFG_RAMBOOT
+#endif
+
+
+/*-----------------------------------------------------------------------
+ * Definitions for initial stack pointer and data area
+ */
+#define CFG_INIT_RAM_ADDR CFG_SDRAM_BASE + CFG_MONITOR_LEN
+#define CFG_INIT_RAM_END 0x2F00 /* End of used area in DPRAM */
+#define CFG_GBL_DATA_SIZE 128 /* size in bytes reserved for initial data */
+#define CFG_GBL_DATA_OFFSET (CFG_INIT_RAM_END - CFG_GBL_DATA_SIZE)
+#define CFG_INIT_SP_OFFSET CFG_GBL_DATA_OFFSET
+
+/*
+ * Low Level Configuration Settings
+ * (address mappings, register initial values, etc.)
+ * You should know what you are doing if you make changes here.
+ * For the detail description refer to the MPC8240 user's manual.
+ */
+
+#define CONFIG_SYS_CLK_FREQ 33000000 /* external frequency to pll */
+#define CFG_HZ 1000
+
+#define CFG_ETH_DEV_FN 0x7800
+#define CFG_ETH_IOBASE 0x00104000
+
+ /* Bit-field values for MCCR1.
+ */
+#define CFG_ROMNAL 0xf
+#define CFG_ROMFAL 0x1f
+#define CFG_DBUS_SIZE 0x3
+
+ /* Bit-field values for MCCR2.
+ */
+#define CFG_TSWAIT 0x5 /* Transaction Start Wait States timer */
+#define CFG_REFINT 0x400 /* Refresh interval FIXME: was 0t430 */
+
+ /* Burst To Precharge. Bits of this value go to MCCR3 and MCCR4.
+ */
+#define CFG_BSTOPRE 0 /* FIXME: was 192 */
+
+ /* Bit-field values for MCCR3.
+ */
+#define CFG_REFREC 2 /* Refresh to activate interval */
+
+ /* Bit-field values for MCCR4.
+ */
+#define CFG_PRETOACT 2 /* Precharge to activate interval FIXME: was 2 */
+#define CFG_ACTTOPRE 5 /* Activate to Precharge interval FIXME: was 5 */
+#define CFG_SDMODE_CAS_LAT 3 /* SDMODE CAS latancy */
+#define CFG_SDMODE_WRAP 0 /* SDMODE wrap type */
+#define CFG_SDMODE_BURSTLEN 3 /* SDMODE Burst length */
+#define CFG_ACTORW 0xa /* FIXME was 2 */
+#define CFG_REGISTERD_TYPE_BUFFER 1
+
+#define CFG_PGMAX 0x0 /* how long the 8240 reatins the currently accessed page in memory FIXME: was 0x32*/
+
+#define CFG_SDRAM_DSCD 0x20 /* SDRAM data in sample clock delay - note bottom 3 bits MUST be 0 */
+
+/* Memory bank settings.
+ * Only bits 20-29 are actually used from these vales to set the
+ * start/end addresses. The upper two bits will always be 0, and the lower
+ * 20 bits will be 0x00000 for a start address, or 0xfffff for an end
+ * address. Refer to the MPC8240 book.
+ */
+
+#define CFG_BANK0_START 0x00000000
+#define CFG_BANK0_END (CFG_MAX_RAM_SIZE - 1)
+#define CFG_BANK0_ENABLE 1
+#define CFG_BANK1_START 0x3ff00000
+#define CFG_BANK1_END 0x3fffffff
+#define CFG_BANK1_ENABLE 0
+#define CFG_BANK2_START 0x3ff00000
+#define CFG_BANK2_END 0x3fffffff
+#define CFG_BANK2_ENABLE 0
+#define CFG_BANK3_START 0x3ff00000
+#define CFG_BANK3_END 0x3fffffff
+#define CFG_BANK3_ENABLE 0
+#define CFG_BANK4_START 0x3ff00000
+#define CFG_BANK4_END 0x3fffffff
+#define CFG_BANK4_ENABLE 0
+#define CFG_BANK5_START 0x3ff00000
+#define CFG_BANK5_END 0x3fffffff
+#define CFG_BANK5_ENABLE 0
+#define CFG_BANK6_START 0x3ff00000
+#define CFG_BANK6_END 0x3fffffff
+#define CFG_BANK6_ENABLE 0
+#define CFG_BANK7_START 0x3ff00000
+#define CFG_BANK7_END 0x3fffffff
+#define CFG_BANK7_ENABLE 0
+
+#define CFG_ODCR 0xff
+
+#define CONFIG_PCI 1 /* Include PCI support */
+#undef CONFIG_PCI_PNP
+
+/* PCI Memory space(s) */
+#define PCI_MEM_SPACE1_START 0x80000000
+#define PCI_MEM_SPACE2_START 0xfd000000
+
+/* ROM Spaces */
+#include "../board/bmw/bmw.h"
+
+/* BAT configuration */
+#define CFG_IBAT0L (CFG_SDRAM_BASE | BATL_PP_10 | BATL_MEMCOHERENCE)
+#define CFG_IBAT0U (CFG_SDRAM_BASE | BATU_BL_256M | BATU_VS | BATU_VP)
+
+#define CFG_IBAT1L (0x70000000 | BATL_PP_10 | BATL_CACHEINHIBIT)
+#define CFG_IBAT1U (0x70000000 | BATU_BL_256M | BATU_VS | BATU_VP)
+
+#define CFG_IBAT2L (0x80000000 | BATL_PP_10 | BATL_CACHEINHIBIT)
+#define CFG_IBAT2U (0x80000000 | BATU_BL_256M | BATU_VS | BATU_VP)
+
+#define CFG_IBAT3L (0xF0000000 | BATL_PP_10 | BATL_CACHEINHIBIT)
+#define CFG_IBAT3U (0xF0000000 | BATU_BL_256M | BATU_VS | BATU_VP)
+
+#define CFG_DBAT0L CFG_IBAT0L
+#define CFG_DBAT0U CFG_IBAT0U
+#define CFG_DBAT1L CFG_IBAT1L
+#define CFG_DBAT1U CFG_IBAT1U
+#define CFG_DBAT2L CFG_IBAT2L
+#define CFG_DBAT2U CFG_IBAT2U
+#define CFG_DBAT3L CFG_IBAT3L
+#define CFG_DBAT3U CFG_IBAT3U
+
+/*
+ * For booting Linux, the board info and command line data
+ * have to be in the first 8 MB of memory, since this is
+ * the maximum mapped by the Linux kernel during initialization.
+ */
+#define CFG_BOOTMAPSZ (8 << 20) /* Initial Memory map for Linux */
+
+/*
+ * FLASH organization
+ */
+#define CFG_MAX_FLASH_BANKS 0 /* Max number of flash banks */
+#define CFG_MAX_FLASH_SECT 64 /* Max number of sectors per flash */
+
+#define CFG_FLASH_ERASE_TOUT 120000 /* Timeout for Flash Erase (in ms) */
+#define CFG_FLASH_WRITE_TOUT 500 /* Timeout for Flash Write (in ms) */
+
+/*
+ * Warining: environment is not EMBEDDED in the U-Boot code.
+ * It's stored in flash separately.
+ */
+#define CFG_ENV_IS_IN_NVRAM 1
+#define CONFIG_ENV_OVERWRITE 1
+#define CFG_NVRAM_ACCESS_ROUTINE 1
+#define CFG_ENV_ADDR 0x7c004000 /* right at the start of NVRAM */
+#define CFG_ENV_SIZE 0x1ff0 /* Size of the Environment - 8K */
+#define CFG_ENV_OFFSET 0 /* starting right at the beginning */
+
+/*
+ * Cache Configuration
+ */
+#define CFG_CACHELINE_SIZE 32
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+# define CFG_CACHELINE_SHIFT 5 /* log base 2 of the above value */
+#endif
+
+/*
+ * Internal Definitions
+ *
+ * Boot Flags
+ */
+#define BOOTFLAG_COLD 0x01 /* Normal Power-On: Boot from FLASH */
+#define BOOTFLAG_WARM 0x02 /* Software reboot */
+
+
+#endif /* __CONFIG_H */
--- /dev/null
+/*
+ * (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
+ */
+
+/*
+ * configuration options, board specific, for Siemens Card Controller Module
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+#undef CCM_80MHz /* define for 80 MHz CPU only */
+
+/*
+ * High Level Configuration Options
+ * (easy to change)
+ */
+
+#define CONFIG_MPC860 1 /* This is a MPC860 CPU ... */
+#define CONFIG_CCM 1 /* on a Card Controller Module */
+
+#define CONFIG_8xx_CONS_SMC1 1 /* Console is on SMC1 */
+#undef CONFIG_8xx_CONS_SMC2
+#undef CONFIG_8xx_CONS_NONE
+
+/* ENVIRONMENT */
+
+#define CONFIG_BAUDRATE 19200 /* console baudrate in bps */
+#define CONFIG_BOOTDELAY 2 /* autoboot after 2 seconds */
+#define CONFIG_CLOCKS_IN_MHZ 1 /* clocks passsed to Linux in MHz */
+
+#define CONFIG_IPADDR 192.168.0.42
+#define CONFIG_NETMASK 255.255.255.0
+#define CONFIG_GATEWAYIP 0.0.0.0
+#define CONFIG_SERVERIP 192.168.0.254
+
+#define CONFIG_HOSTNAME CCM
+
+#define CONFIG_LOADADDR 40180000
+
+#undef CONFIG_BOOTARGS
+
+#define CONFIG_BOOTCOMMAND "setenv bootargs " \
+ "mem=$(mem) " \
+ "root=/dev/ram rw ip=$(ipaddr):$(serverip):$(gatewayip):$(netmask):$(hostname)::off " \
+ "wt_8xx=timeout:3600; " \
+ "bootm"
+
+#define CONFIG_LOADS_ECHO 1 /* echo on for serial download */
+#undef CFG_LOADS_BAUD_CHANGE /* don't allow baudrate change */
+
+#define CONFIG_WATCHDOG 1 /* watchdog enabled */
+
+#undef CONFIG_STATUS_LED /* Status LED disabled */
+
+#define CONFIG_PRAM 512 /* reserve 512kB "protected RAM"*/
+
+#define CONFIG_RTC_MPC8xx /* use internal RTC of MPC8xx */
+
+#define CONFIG_SPI /* enable SPI driver */
+#define CONFIG_SPI_X /* 16 bit EEPROM addressing */
+
+/* ----------------------------------------------------------------
+ * Offset to initial SPI buffers in DPRAM (used if the environment
+ * is in the SPI EEPROM): We need a 520 byte scratch DPRAM area to
+ * use at an early stage. It is used between the two initialization
+ * calls (spi_init_f() and spi_init_r()). The value 0xB00 makes it
+ * far enough from the start of the data area (as well as from the
+ * stack pointer).
+ * ---------------------------------------------------------------- */
+#define CFG_SPI_INIT_OFFSET 0xB00
+
+#define CFG_EEPROM_PAGE_WRITE_BITS 5 /* 32-byte page size */
+
+
+#define CONFIG_MAC_PARTITION /* nod used yet */
+#define CONFIG_DOS_PARTITION
+
+#define CONFIG_BOOTP_MASK (CONFIG_BOOTP_DEFAULT | CONFIG_BOOTP_BOOTFILESIZE)
+
+#define CONFIG_COMMANDS ( CONFIG_CMD_DFL | \
+ CFG_CMD_DHCP | \
+ CFG_CMD_DATE | \
+ CFG_CMD_EEPROM | \
+ CFG_CMD_BSP )
+
+/* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */
+#include <cmd_confdefs.h>
+
+/*----------------------------------------------------------------------*/
+
+/*
+ * Miscellaneous configurable options
+ */
+#define CFG_LONGHELP /* undef to save memory */
+#define CFG_PROMPT "=> " /* Monitor Command Prompt */
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+#define CFG_CBSIZE 1024 /* Console I/O Buffer Size */
+#else
+#define CFG_CBSIZE 256 /* Console I/O Buffer Size */
+#endif
+#define CFG_PBSIZE (CFG_CBSIZE+sizeof(CFG_PROMPT)+16) /* Print Buffer Size */
+#define CFG_MAXARGS 16 /* max number of command args */
+#define CFG_BARGSIZE CFG_CBSIZE /* Boot Argument Buffer Size */
+
+#define CFG_MEMTEST_START 0x00100000 /* memtest works on */
+#define CFG_MEMTEST_END 0x00F00000 /* 1 ... 15MB in DRAM */
+
+#define CFG_LOAD_ADDR 0x00100000 /* default load address */
+
+/* Ethernet hardware configuration done using port pins */
+#define CFG_PA_ETH_RESET 0x0200 /* PA 6 */
+#define CFG_PA_ETH_MDDIS 0x4000 /* PA 1 */
+#define CFG_PB_ETH_POWERDOWN 0x00000800 /* PB 20 */
+#define CFG_PB_ETH_CFG1 0x00000400 /* PB 21 */
+#define CFG_PB_ETH_CFG2 0x00000200 /* PB 22 */
+#define CFG_PB_ETH_CFG3 0x00000100 /* PB 23 */
+
+/* Ethernet settings:
+ * MDIO not disabled, autonegotiation, 10/100Mbps, half/full duplex
+ */
+#define CFG_ETH_MDDIS_VALUE 0
+#define CFG_ETH_CFG1_VALUE 1
+#define CFG_ETH_CFG2_VALUE 1
+#define CFG_ETH_CFG3_VALUE 1
+
+/* PUMA configuration */
+#define CFG_PC_PUMA_PROG 0x0200 /* PC 6 */
+#define CFG_PC_PUMA_DONE 0x0008 /* PC 12 */
+#define CFG_PC_PUMA_INIT 0x0004 /* PC 13 */
+
+#define CFG_HZ 1000 /* decrementer freq: 1 ms ticks */
+
+#define CFG_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 }
+
+/*
+ * Low Level Configuration Settings
+ * (address mappings, register initial values, etc.)
+ * You should know what you are doing if you make changes here.
+ */
+/*-----------------------------------------------------------------------
+ * Internal Memory Mapped Register
+ */
+#define CFG_IMMR 0xF0000000
+
+/*-----------------------------------------------------------------------
+ * Definitions for initial stack pointer and data area (in DPRAM)
+ */
+#define CFG_INIT_RAM_ADDR CFG_IMMR
+#define CFG_INIT_RAM_END 0x2F00 /* End of used area in DPRAM */
+#define CFG_GBL_DATA_SIZE 64 /* size in bytes reserved for initial data */
+#define CFG_GBL_DATA_OFFSET (CFG_INIT_RAM_END - CFG_GBL_DATA_SIZE)
+#define CFG_INIT_SP_OFFSET CFG_GBL_DATA_OFFSET
+
+/*-----------------------------------------------------------------------
+ * Address accessed to reset the board - must not be mapped/assigned
+ */
+#define CFG_RESET_ADDRESS 0xFEFFFFFF
+
+/*-----------------------------------------------------------------------
+ * Start addresses for the final memory configuration
+ * (Set up by the startup code)
+ * Please note that CFG_SDRAM_BASE _must_ start at 0
+ */
+#define CFG_SDRAM_BASE 0x00000000
+#define CFG_FLASH_BASE 0x40000000
+#if defined(DEBUG)
+#define CFG_MONITOR_LEN (256 << 10) /* Reserve 256 kB for Monitor */
+#else
+#define CFG_MONITOR_LEN (192 << 10) /* Reserve 192 kB for Monitor */
+#endif
+#define CFG_MONITOR_BASE CFG_FLASH_BASE
+#define CFG_MALLOC_LEN (128 << 10) /* Reserve 128 kB for malloc() */
+
+/*
+ * For booting Linux, the board info and command line data
+ * have to be in the first 8 MB of memory, since this is
+ * the maximum mapped by the Linux kernel during initialization.
+ */
+#define CFG_BOOTMAPSZ (8 << 20) /* Initial Memory map for Linux */
+
+/*-----------------------------------------------------------------------
+ * FLASH organization
+ */
+#define CFG_MAX_FLASH_BANKS 2 /* max number of memory banks */
+#define CFG_MAX_FLASH_SECT 67 /* max number of sectors on one chip */
+
+#define CFG_FLASH_ERASE_TOUT 120000 /* Timeout for Flash Erase (in ms) */
+#define CFG_FLASH_WRITE_TOUT 500 /* Timeout for Flash Write (in ms) */
+
+#if 1
+/* Start port with environment in flash; switch to SPI EEPROM later */
+#define CFG_ENV_IS_IN_FLASH 1
+#define CFG_ENV_OFFSET 0x8000 /* Offset of Environment Sector */
+#define CFG_ENV_SIZE 0x4000 /* Total Size of Environment Sector */
+#else
+/* Final version: environment in EEPROM */
+#define CFG_ENV_IS_IN_EEPROM 1
+#define CFG_ENV_OFFSET 2048
+#define CFG_ENV_SIZE 2048
+#endif
+
+/*-----------------------------------------------------------------------
+ * Hardware Information Block
+ */
+#define CFG_HWINFO_OFFSET 0x0003FFC0 /* offset of HW Info block */
+#define CFG_HWINFO_SIZE 0x00000040 /* size of HW Info block */
+#define CFG_HWINFO_MAGIC 0x54514D38 /* 'TQM8' */
+
+/*-----------------------------------------------------------------------
+ * Cache Configuration
+ */
+#define CFG_CACHELINE_SIZE 16 /* For all MPC8xx CPUs */
+#define CFG_CACHELINE_SHIFT 4 /* log base 2 of the above value */
+
+/*-----------------------------------------------------------------------
+ * SYPCR - System Protection Control 11-9
+ * SYPCR can only be written once after reset!
+ *-----------------------------------------------------------------------
+ * Software & Bus Monitor Timer max, Bus Monitor enable, SW Watchdog freeze
+ */
+#if defined(CONFIG_WATCHDOG)
+#define CFG_SYPCR (SYPCR_SWTC | SYPCR_BMT | SYPCR_BME | SYPCR_SWF | \
+ SYPCR_SWE | SYPCR_SWRI| SYPCR_SWP)
+#else
+#define CFG_SYPCR (SYPCR_SWTC | SYPCR_BMT | SYPCR_BME | SYPCR_SWF | SYPCR_SWP)
+#endif
+
+/*-----------------------------------------------------------------------
+ * SIUMCR - SIU Module Configuration 11-6
+ *-----------------------------------------------------------------------
+ * we must activate GPL5 in the SIUMCR for CAN
+ */
+#define CFG_SIUMCR (SIUMCR_DBGC11 | SIUMCR_DBPC00 | SIUMCR_MLRC01)
+
+/*-----------------------------------------------------------------------
+ * TBSCR - Time Base Status and Control 11-26
+ *-----------------------------------------------------------------------
+ * Clear Reference Interrupt Status, Timebase freezing enabled
+ */
+#define CFG_TBSCR (TBSCR_REFA | TBSCR_REFB | TBSCR_TBF)
+
+/*-----------------------------------------------------------------------
+ * RTCSC - Real-Time Clock Status and Control Register 11-27
+ *-----------------------------------------------------------------------
+ */
+#define CFG_RTCSC (RTCSC_SEC | RTCSC_ALR | RTCSC_RTF| RTCSC_RTE)
+
+/*-----------------------------------------------------------------------
+ * PISCR - Periodic Interrupt Status and Control 11-31
+ *-----------------------------------------------------------------------
+ * Clear Periodic Interrupt Status, Interrupt Timer freezing enabled
+ */
+#define CFG_PISCR (PISCR_PS | PISCR_PITF)
+
+/*-----------------------------------------------------------------------
+ * PLPRCR - PLL, Low-Power, and Reset Control Register 15-30
+ *-----------------------------------------------------------------------
+ * Reset PLL lock status sticky bit, timer expired status bit and timer
+ * interrupt status bit
+ *
+ * If this is a 80 MHz CPU, set PLL multiplication factor to 5 (5*16=80)!
+ */
+#ifdef CCM_80MHz /* for 80 MHz, we use a 16 MHz clock * 5 */
+#define CFG_PLPRCR \
+ ( (5-1)<<PLPRCR_MF_SHIFT | PLPRCR_TEXPS | PLPRCR_TMIST )
+#else /* up to 50 MHz we use a 1:1 clock */
+#define CFG_PLPRCR (PLPRCR_SPLSS | PLPRCR_TEXPS | PLPRCR_TMIST)
+#endif /* CCM_80MHz */
+
+/*-----------------------------------------------------------------------
+ * SCCR - System Clock and reset Control Register 15-27
+ *-----------------------------------------------------------------------
+ * Set clock output, timebase and RTC source and divider,
+ * power management and some other internal clocks
+ */
+#define SCCR_MASK SCCR_EBDF11
+#ifdef CCM_80MHz /* for 80 MHz, we use a 16 MHz clock * 5 */
+#define CFG_SCCR (/* SCCR_TBS | */ \
+ SCCR_COM00 | SCCR_DFSYNC00 | SCCR_DFBRG00 | \
+ SCCR_DFNL000 | SCCR_DFNH000 | SCCR_DFLCD000 | \
+ SCCR_DFALCD00)
+#else /* up to 50 MHz we use a 1:1 clock */
+#define CFG_SCCR (SCCR_TBS | \
+ SCCR_COM00 | SCCR_DFSYNC00 | SCCR_DFBRG00 | \
+ SCCR_DFNL000 | SCCR_DFNH000 | SCCR_DFLCD000 | \
+ SCCR_DFALCD00)
+#endif /* CCM_80MHz */
+
+/*-----------------------------------------------------------------------
+ *
+ * Interrupt Levels
+ *-----------------------------------------------------------------------
+ */
+#define CFG_CPM_INTERRUPT 13 /* SIU_LEVEL6 */
+
+/*-----------------------------------------------------------------------
+ *
+ *-----------------------------------------------------------------------
+ *
+ */
+#define CFG_DER 0
+
+/*
+ * Init Memory Controller:
+ *
+ * BR0/1 and OR0/1 (FLASH)
+ */
+
+#define FLASH_BASE0_PRELIM 0x40000000 /* FLASH bank #0 */
+#define FLASH_BASE1_PRELIM 0x60000000 /* FLASH bank #0 */
+
+/* used to re-map FLASH both when starting from SRAM or FLASH:
+ * restrict access enough to keep SRAM working (if any)
+ * but not too much to meddle with FLASH accesses
+ */
+#define CFG_REMAP_OR_AM 0x80000000 /* OR addr mask */
+#define CFG_PRELIM_OR_AM 0xE0000000 /* OR addr mask */
+
+/* FLASH timing: ACS = 11, TRLX = 0, CSNT = 1, SCY = 5, EHTR = 1 */
+#define CFG_OR_TIMING_FLASH (OR_CSNT_SAM | OR_ACS_DIV2 | OR_BI | \
+ OR_SCY_5_CLK | OR_EHTR)
+
+#define CFG_OR0_REMAP (CFG_REMAP_OR_AM | CFG_OR_TIMING_FLASH)
+#define CFG_OR0_PRELIM (CFG_PRELIM_OR_AM | CFG_OR_TIMING_FLASH)
+#define CFG_BR0_PRELIM ((FLASH_BASE0_PRELIM & BR_BA_MSK) | BR_V )
+
+#define CFG_OR1_REMAP CFG_OR0_REMAP
+#define CFG_OR1_PRELIM CFG_OR0_PRELIM
+#define CFG_BR1_PRELIM ((FLASH_BASE1_PRELIM & BR_BA_MSK) | BR_V )
+
+/*
+ * BR2 and OR2 (SDRAM)
+ *
+ */
+#define SDRAM_BASE2_PRELIM 0x00000000 /* SDRAM bank #0 */
+#define SDRAM_BASE3_PRELIM 0x20000000 /* SDRAM bank #1 */
+#define SDRAM_MAX_SIZE 0x04000000 /* max 64 MB per bank */
+
+/* SDRAM timing: Multiplexed addresses, GPL5 output to GPL5_A (don't care) */
+#define CFG_OR_TIMING_SDRAM 0x00000A00
+
+#define CFG_OR2_PRELIM (CFG_PRELIM_OR_AM | CFG_OR_TIMING_SDRAM )
+#define CFG_BR2_PRELIM ((SDRAM_BASE2_PRELIM & BR_BA_MSK) | BR_MS_UPMA | BR_V )
+
+/*
+ * BR3 and OR3 (CAN Controller)
+ */
+#define CFG_CAN_BASE 0xC0000000 /* CAN mapped at 0xC0000000 */
+#define CFG_CAN_OR_AM 0xFFFF8000 /* 32 kB address mask */
+#define CFG_OR3_CAN (CFG_CAN_OR_AM | OR_G5LA | OR_BI)
+#define CFG_BR3_CAN ((CFG_CAN_BASE & BR_BA_MSK) | \
+ BR_PS_8 | BR_MS_UPMB | BR_V )
+
+/*
+ * BR4/OR4: PUMA Config
+ *
+ * Memory controller will be used in 2 modes:
+ *
+ * - "read" mode:
+ * BR4: 0x10100801 OR4: 0xffff8520
+ * - "load" mode (chip select on UPM B):
+ * BR4: 0x101004c1 OR4: 0xffff8600
+ *
+ * Default initialization is in "read" mode
+ */
+#define PUMA_CONF_BASE 0x10100000 /* PUMA Config */
+#define PUMA_CONF_OR_AM 0xFFFF8000 /* 32 kB */
+#define PUMA_CONF_LOAD_TIMING (OR_ACS_DIV2 | OR_SCY_2_CLK)
+#define PUMA_CONF_READ_TIMING (OR_G5LA | OR_BI | OR_SCY_2_CLK)
+
+#define PUMA_CONF_BR_LOAD ((PUMA_CONF_BASE & BR_BA_MSK) | \
+ BR_PS_8 | BR_MS_UPMB | BR_V)
+#define PUMA_CONF_OR_LOAD (PUMA_CONF_OR_AM | PUMA_CONF_LOAD_TIMING)
+
+#define PUMA_CONF_BR_READ ((PUMA_CONF_BASE & BR_BA_MSK) | BR_PS_16 | BR_V)
+#define PUMA_CONF_OR_READ (PUMA_CONF_OR_AM | PUMA_CONF_READ_TIMING)
+
+#define CFG_BR4_PRELIM PUMA_CONF_BR_READ
+#define CFG_OR4_PRELIM PUMA_CONF_OR_READ
+
+/*
+ * BR5/OR5: PUMA: SMA Bus 8 Bit
+ * BR5: 0x10200401 OR5: 0xffe0010a
+ */
+#define PUMA_SMA8_BASE 0x10200000 /* PUMA SMA Bus 8 Bit */
+#define PUMA_SMA8_OR_AM 0xFFE00000 /* 2 MB */
+#define PUMA_SMA8_TIMING (OR_BI | OR_SCY_0_CLK | OR_EHTR)
+
+#define CFG_BR5_PRELIM ((PUMA_SMA8_BASE & BR_BA_MSK) | BR_PS_8 | BR_V)
+#define CFG_OR5_PRELIM (PUMA_SMA8_OR_AM | PUMA_SMA8_TIMING | OR_SETA)
+
+/*
+ * BR6/OR6: PUMA: SMA Bus 16 Bit
+ * BR6: 0x10600801 OR6: 0xffe0010a
+ */
+#define PUMA_SMA16_BASE 0x10600000 /* PUMA SMA Bus 16 Bit */
+#define PUMA_SMA16_OR_AM 0xFFE00000 /* 2 MB */
+#define PUMA_SMA16_TIMING (OR_BI | OR_SCY_0_CLK | OR_EHTR)
+
+#define CFG_BR6_PRELIM ((PUMA_SMA16_BASE & BR_BA_MSK) | BR_PS_16 | BR_V)
+#define CFG_OR6_PRELIM (PUMA_SMA16_OR_AM | PUMA_SMA16_TIMING | OR_SETA)
+
+/*
+ * BR7/OR7: PUMA: external Flash
+ * BR7: 0x10a00801 OR7: 0xfe00010a
+ */
+#define PUMA_FLASH_BASE 0x10A00000 /* PUMA external Flash */
+#define PUMA_FLASH_OR_AM 0xFE000000 /* 32 MB */
+#define PUMA_FLASH_TIMING (OR_BI | OR_SCY_0_CLK | OR_EHTR)
+
+#define CFG_BR7_PRELIM ((PUMA_FLASH_BASE & BR_BA_MSK) | BR_PS_16 | BR_V)
+#define CFG_OR7_PRELIM (PUMA_FLASH_OR_AM | PUMA_FLASH_TIMING | OR_SETA)
+
+
+/*
+ * Memory Periodic Timer Prescaler
+ */
+
+/* periodic timer for refresh */
+#define CFG_MAMR_PTA 97 /* start with divider for 100 MHz */
+
+/* refresh rate 15.6 us (= 64 ms / 4K = 62.4 / quad bursts) for <= 128 MBit */
+#define CFG_MPTPR_2BK_4K MPTPR_PTP_DIV16 /* setting for 2 banks */
+#define CFG_MPTPR_1BK_4K MPTPR_PTP_DIV32 /* setting for 1 bank */
+
+/* refresh rate 7.8 us (= 64 ms / 8K = 31.2 / quad bursts) for 256 MBit */
+#define CFG_MPTPR_2BK_8K MPTPR_PTP_DIV8 /* setting for 2 banks */
+#define CFG_MPTPR_1BK_8K MPTPR_PTP_DIV16 /* setting for 1 bank */
+
+/*
+ * MAMR settings for SDRAM
+ */
+
+/* 8 column SDRAM */
+#define CFG_MAMR_8COL ((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)
+/* 9 column SDRAM */
+#define CFG_MAMR_9COL ((CFG_MAMR_PTA << MAMR_PTA_SHIFT) | MAMR_PTAE | \
+ MAMR_AMA_TYPE_1 | MAMR_DSA_1_CYCL | MAMR_G0CLA_A10 | \
+ MAMR_RLFA_1X | MAMR_WLFA_1X | MAMR_TLFA_4X)
+
+
+/*
+ * Internal Definitions
+ *
+ * Boot Flags
+ */
+#define BOOTFLAG_COLD 0x01 /* Normal Power-On: Boot from FLASH */
+#define BOOTFLAG_WARM 0x02 /* Software reboot */
+
+#endif /* __CONFIG_H */
--- /dev/null
+/*
+ * (C) Copyright 2001
+ * Stefan Roese, esd gmbh germany, stefan.roese@esd-electronics.com
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/*
+ * board/config.h - configuration options, board specific
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+/*
+ * High Level Configuration Options
+ * (easy to change)
+ */
+
+#define CONFIG_405GP 1 /* This is a PPC405 CPU */
+#define CONFIG_4xx 1 /* ...member of PPC4xx family */
+#define CONFIG_CPCI405 1 /* ...on a CPCI405 board */
+
+#define CONFIG_BOARD_PRE_INIT 1 /* call board_pre_init() */
+
+#define CONFIG_SYS_CLK_FREQ 33000000 /* external frequency to pll */
+
+#define CONFIG_BAUDRATE 9600
+#define CONFIG_BOOTDELAY 3 /* autoboot after 3 seconds */
+
+#if 0
+#define CONFIG_PREBOOT \
+ "crc32 f0207004 ffc 0;" \
+ "if cmp 0 f0207000 1;" \
+ "then;echo Old CRC is correct;crc32 f0207004 ff4 f0207000;" \
+ "else;echo Old CRC is bad;fi"
+#endif
+
+#undef CONFIG_BOOTARGS
+#define CONFIG_RAMBOOTCOMMAND \
+ "setenv bootargs root=/dev/ram rw nfsroot=$(serverip):$(rootpath) " \
+ "ip=$(ipaddr):$(serverip):$(gatewayip):$(netmask):$(hostname)::off;" \
+ "bootm ffc00000 ffca0000"
+#define CONFIG_NFSBOOTCOMMAND \
+ "setenv bootargs root=/dev/nfs rw nfsroot=$(serverip):$(rootpath) " \
+ "ip=$(ipaddr):$(serverip):$(gatewayip):$(netmask):$(hostname)::off;" \
+ "bootm ffc00000"
+#define CONFIG_BOOTCOMMAND CONFIG_RAMBOOTCOMMAND
+
+#define CONFIG_LOADS_ECHO 1 /* echo on for serial download */
+#define CFG_LOADS_BAUD_CHANGE 1 /* allow baudrate change */
+
+#define CONFIG_MII 1 /* MII PHY management */
+#define CONFIG_PHY_ADDR 0 /* PHY address */
+
+#define CONFIG_COMMANDS ( CONFIG_CMD_DFL | \
+ CFG_CMD_PCI | \
+ CFG_CMD_IRQ | \
+ CFG_CMD_IDE | \
+ CFG_CMD_ELF | \
+ CFG_CMD_EEPROM )
+
+#define CONFIG_MAC_PARTITION
+#define CONFIG_DOS_PARTITION
+
+/* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */
+#include <cmd_confdefs.h>
+
+#undef CONFIG_WATCHDOG /* watchdog disabled */
+
+#define CONFIG_SDRAM_BANK0 1 /* init onboard SDRAM bank 0 */
+
+/*
+ * Miscellaneous configurable options
+ */
+#define CFG_LONGHELP /* undef to save memory */
+#define CFG_PROMPT "=> " /* Monitor Command Prompt */
+
+#undef CFG_HUSH_PARSER /* use "hush" command parser */
+#ifdef CFG_HUSH_PARSER
+#define CFG_PROMPT_HUSH_PS2 "> "
+#endif
+
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+#define CFG_CBSIZE 1024 /* Console I/O Buffer Size */
+#else
+#define CFG_CBSIZE 256 /* Console I/O Buffer Size */
+#endif
+#define CFG_PBSIZE (CFG_CBSIZE+sizeof(CFG_PROMPT)+16) /* Print Buffer Size */
+#define CFG_MAXARGS 16 /* max number of command args */
+#define CFG_BARGSIZE CFG_CBSIZE /* Boot Argument Buffer Size */
+
+#define CFG_DEVICE_NULLDEV 1 /* include nulldev device */
+
+#define CFG_CONSOLE_INFO_QUIET 1 /* don't print console @ startup*/
+
+#define CFG_MEMTEST_START 0x0400000 /* memtest works on */
+#define CFG_MEMTEST_END 0x0C00000 /* 4 ... 12 MB in DRAM */
+
+#undef CFG_EXT_SERIAL_CLOCK /* no external serial clock used */
+#define CFG_IGNORE_405_UART_ERRATA_59 /* ignore ppc405gp errata #59 */
+#define CFG_BASE_BAUD 691200
+
+/* The following table includes the supported baudrates */
+#define CFG_BAUDRATE_TABLE \
+ { 300, 600, 1200, 2400, 4800, 9600, 19200, 38400, \
+ 57600, 115200, 230400, 460800, 921600 }
+
+#define CFG_LOAD_ADDR 0x100000 /* default load address */
+#define CFG_EXTBDINFO 1 /* To use extended board_into (bd_t) */
+
+#define CFG_HZ 1000 /* decrementer freq: 1 ms ticks */
+
+#define CONFIG_ZERO_BOOTDELAY_CHECK /* check for keypress on bootdelay==0 */
+
+/*-----------------------------------------------------------------------
+ * PCI stuff
+ *-----------------------------------------------------------------------
+ */
+#define PCI_HOST_ADAPTER 0 /* configure as pci adapter */
+#define PCI_HOST_FORCE 1 /* configure as pci host */
+#define PCI_HOST_AUTO 2 /* detected via arbiter enable */
+
+#define CONFIG_PCI /* include pci support */
+#define CONFIG_PCI_HOST PCI_HOST_AUTO /* select pci host function */
+#define CONFIG_PCI_PNP /* do pci plug-and-play */
+ /* resource configuration */
+
+#define CONFIG_PCI_SCAN_SHOW /* print pci devices @ startup */
+
+#define CFG_PCI_SUBSYS_VENDORID 0x12FE /* PCI Vendor ID: esd gmbh */
+#define CFG_PCI_SUBSYS_DEVICEID 0x0405 /* PCI Device ID: CPCI-405 */
+#define CFG_PCI_SUBSYS_DEVICEID2 0x0406 /* PCI Device ID: CPCI-405-A */
+#define CFG_PCI_CLASSCODE 0x0b20 /* PCI Class Code: Processor/PPC*/
+#define CFG_PCI_PTM1LA 0x00000000 /* point to sdram */
+#define CFG_PCI_PTM1MS 0xfc000001 /* 64MB, enable hard-wired to 1 */
+#define CFG_PCI_PTM1PCI 0x00000000 /* Host: use this pci address */
+#define CFG_PCI_PTM2LA 0xffc00000 /* point to flash */
+#define CFG_PCI_PTM2MS 0xffc00001 /* 4MB, enable */
+#define CFG_PCI_PTM2PCI 0x04000000 /* Host: use this pci address */
+
+/*-----------------------------------------------------------------------
+ * IDE/ATA stuff
+ *-----------------------------------------------------------------------
+ */
+#undef CONFIG_IDE_8xx_DIRECT /* no pcmcia interface required */
+#undef CONFIG_IDE_LED /* no led for ide supported */
+#undef CONFIG_IDE_RESET /* no reset for ide supported */
+
+#define CFG_IDE_MAXBUS 1 /* max. 1 IDE busses */
+#define CFG_IDE_MAXDEVICE (CFG_IDE_MAXBUS*1) /* max. 1 drives per IDE bus */
+
+#define CFG_ATA_BASE_ADDR 0xF0100000
+#define CFG_ATA_IDE0_OFFSET 0x0000
+
+#define CFG_ATA_DATA_OFFSET 0x0000 /* Offset for data I/O */
+#define CFG_ATA_REG_OFFSET 0x0000 /* Offset for normal register accesses */
+#define CFG_ATA_ALT_OFFSET 0x0000 /* Offset for alternate registers */
+
+/*-----------------------------------------------------------------------
+ * Start addresses for the final memory configuration
+ * (Set up by the startup code)
+ * Please note that CFG_SDRAM_BASE _must_ start at 0
+ */
+#define CFG_SDRAM_BASE 0x00000000
+#define CFG_FLASH_BASE 0xFFFD0000
+#define CFG_MONITOR_BASE CFG_FLASH_BASE
+#define CFG_MONITOR_LEN (192 * 1024) /* Reserve 196 kB for Monitor */
+#define CFG_MALLOC_LEN (128 * 1024) /* Reserve 128 kB for malloc() */
+
+/*
+ * For booting Linux, the board info and command line data
+ * have to be in the first 8 MB of memory, since this is
+ * the maximum mapped by the Linux kernel during initialization.
+ */
+#define CFG_BOOTMAPSZ (8 << 20) /* Initial Memory map for Linux */
+/*-----------------------------------------------------------------------
+ * FLASH organization
+ */
+#define CFG_MAX_FLASH_BANKS 2 /* max number of memory banks */
+#define CFG_MAX_FLASH_SECT 256 /* max number of sectors on one chip */
+
+#define CFG_FLASH_ERASE_TOUT 120000 /* Timeout for Flash Erase (in ms) */
+#define CFG_FLASH_WRITE_TOUT 500 /* Timeout for Flash Write (in ms) */
+
+#define CFG_FLASH_WORD_SIZE unsigned short /* flash word size (width) */
+#define CFG_FLASH_ADDR0 0x5555 /* 1st address for flash config cycles */
+#define CFG_FLASH_ADDR1 0x2AAA /* 2nd address for flash config cycles */
+/*
+ * The following defines are added for buggy IOP480 byte interface.
+ * All other boards should use the standard values (CPCI405 etc.)
+ */
+#define CFG_FLASH_READ0 0x0000 /* 0 is standard */
+#define CFG_FLASH_READ1 0x0001 /* 1 is standard */
+#define CFG_FLASH_READ2 0x0002 /* 2 is standard */
+
+#define CFG_FLASH_EMPTY_INFO /* print 'E' for empty sector on flinfo */
+
+#if 1 /* Use NVRAM for environment variables */
+/*-----------------------------------------------------------------------
+ * NVRAM organization
+ */
+#define CFG_ENV_IS_IN_NVRAM 1 /* use NVRAM for environment vars */
+#define CFG_NVRAM_BASE_ADDR 0xf0200000 /* NVRAM base address */
+#define CFG_NVRAM_SIZE (32*1024) /* NVRAM size */
+#define CFG_ENV_SIZE 0x1000 /* Size of Environment vars */
+#define CFG_ENV_ADDR \
+ (CFG_NVRAM_BASE_ADDR+CFG_NVRAM_SIZE-CFG_ENV_SIZE) /* Env */
+#define CFG_NVRAM_VXWORKS_OFFS 0x6900 /* Offset for VxWorks eth-addr */
+
+#else /* Use EEPROM for environment variables */
+
+#define CFG_ENV_IS_IN_EEPROM 1 /* use EEPROM for environment vars */
+#define CFG_ENV_OFFSET 0x000 /* environment starts at the beginning of the EEPROM */
+#define CFG_ENV_SIZE 0x200 /* 512 bytes may be used for env vars */
+ /* total size of a CAT24WC08 is 1024 bytes */
+#endif
+
+/*-----------------------------------------------------------------------
+ * I2C EEPROM (CAT24WC08) for environment
+ */
+#define CONFIG_HARD_I2C /* I2c with hardware support */
+#define CFG_I2C_SPEED 400000 /* I2C speed and slave address */
+#define CFG_I2C_SLAVE 0x7F
+
+#define CFG_I2C_EEPROM_ADDR 0x50 /* EEPROM CAT28WC08 */
+#define CFG_I2C_EEPROM_ADDR_LEN 1 /* Bytes of address */
+/* mask of address bits that overflow into the "EEPROM chip address" */
+#define CFG_I2C_EEPROM_ADDR_OVERFLOW 0x07
+#define CFG_EEPROM_PAGE_WRITE_BITS 4 /* The Catalyst CAT24WC08 has */
+ /* 16 byte page write mode using*/
+ /* last 4 bits of the address */
+#define CFG_EEPROM_PAGE_WRITE_DELAY_MS 10 /* and takes up to 10 msec */
+#define CFG_EEPROM_PAGE_WRITE_ENABLE
+
+/*-----------------------------------------------------------------------
+ * Cache Configuration
+ */
+#define CFG_DCACHE_SIZE 8192 /* For IBM 405 CPUs */
+#define CFG_CACHELINE_SIZE 32 /* ... */
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+#define CFG_CACHELINE_SHIFT 5 /* log base 2 of the above value */
+#endif
+
+/*
+ * Init Memory Controller:
+ *
+ * BR0/1 and OR0/1 (FLASH)
+ */
+
+#define FLASH_BASE0_PRELIM 0xFF800000 /* FLASH bank #0 */
+#define FLASH_BASE1_PRELIM 0xFFC00000 /* FLASH bank #1 */
+
+/*-----------------------------------------------------------------------
+ * External Bus Controller (EBC) Setup
+ */
+
+/* Memory Bank 0 (Flash Bank 0) initialization */
+#define CFG_EBC_PB0AP 0x92015480
+#define CFG_EBC_PB0CR 0xFFC5A000 /* BAS=0xFFC,BS=4MB,BU=R/W,BW=16bit */
+
+/* Memory Bank 1 (Flash Bank 1) initialization */
+#define CFG_EBC_PB1AP 0x92015480
+#define CFG_EBC_PB1CR 0xFF85A000 /* BAS=0xFF8,BS=4MB,BU=R/W,BW=16bit */
+
+/* Memory Bank 2 (CAN0, 1, 2, Codeswitch) initialization */
+#define CFG_EBC_PB2AP 0x010053C0 /* BWT=2,WBN=1,WBF=1,TH=1,RE=1,SOR=1,BEM=1 */
+#define CFG_EBC_PB2CR 0xF0018000 /* BAS=0xF00,BS=1MB,BU=R/W,BW=8bit */
+
+/* Memory Bank 3 (CompactFlash IDE) initialization */
+#define CFG_EBC_PB3AP 0x010053C0 /* BWT=2,WBN=1,WBF=1,TH=1,RE=1,SOR=1,BEM=1 */
+#define CFG_EBC_PB3CR 0xF011A000 /* BAS=0xF01,BS=1MB,BU=R/W,BW=16bit */
+
+/* Memory Bank 4 (NVRAM) initialization */
+#define CFG_EBC_PB4AP 0x01005280 /* TWT=2,WBN=1,WBF=1,TH=1,SOR=1 */
+#define CFG_EBC_PB4CR 0xF0218000 /* BAS=0xF02,BS=1MB,BU=R/W,BW=8bit */
+
+/* Memory Bank 5 (Quart) initialization */
+#define CFG_EBC_PB5AP 0x04005B80 /* TWT=8,WBN=1,WBF=1,TH=5,RE=1,SOR=1*/
+#define CFG_EBC_PB5CR 0xF0318000 /* BAS=0xF03,BS=1MB,BU=R/W,BW=8bit */
+
+/*-----------------------------------------------------------------------
+ * FPGA stuff
+ */
+
+/* FPGA program pin configuration */
+#define CFG_FPGA_PRG 0x04000000 /* FPGA program pin (ppc output) */
+#define CFG_FPGA_CLK 0x02000000 /* FPGA clk pin (ppc output) */
+#define CFG_FPGA_DATA 0x01000000 /* FPGA data pin (ppc output) */
+#define CFG_FPGA_INIT 0x00400000 /* FPGA init pin (ppc input) */
+#define CFG_FPGA_DONE 0x00800000 /* FPGA done pin (ppc input) */
+
+/*-----------------------------------------------------------------------
+ * Definitions for initial stack pointer and data area (in data cache)
+ */
+#if 1 /* test-only */
+#define CFG_INIT_DCACHE_CS 7 /* use cs # 7 for data cache memory */
+
+#define CFG_INIT_RAM_ADDR 0x40000000 /* use data cache */
+#else
+#define CFG_INIT_RAM_ADDR 0x00df0000 /* inside of SDRAM */
+#endif
+#define CFG_INIT_RAM_END 0x2000 /* End of used area in RAM */
+#define CFG_GBL_DATA_SIZE 128 /* size in bytes reserved for initial data */
+#define CFG_GBL_DATA_OFFSET (CFG_INIT_RAM_END - CFG_GBL_DATA_SIZE)
+#define CFG_INIT_SP_OFFSET CFG_GBL_DATA_OFFSET
+
+
+/*
+ * Internal Definitions
+ *
+ * Boot Flags
+ */
+#define BOOTFLAG_COLD 0x01 /* Normal Power-On: Boot from FLASH */
+#define BOOTFLAG_WARM 0x02 /* Software reboot */
+
+#endif /* __CONFIG_H */
--- /dev/null
+/*
+ * (C) Copyright 2001
+ * Stefan Roese, esd gmbh germany, stefan.roese@esd-electronics.com
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/*
+ * board/config.h - configuration options, board specific
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+/*
+ * High Level Configuration Options
+ * (easy to change)
+ */
+
+#define CONFIG_405GP 1 /* This is a PPC405 CPU */
+#define CONFIG_4xx 1 /* ...member of PPC4xx family */
+#define CONFIG_CPCI405 1 /* ...on a CPCI405 board */
+#define CONFIG_CPCI405_VER2 1 /* ...version 2 */
+
+#define CONFIG_BOARD_PRE_INIT 1 /* call board_pre_init() */
+
+#define CONFIG_SYS_CLK_FREQ 33333333 /* external frequency to pll */
+
+#define CONFIG_BAUDRATE 9600
+#define CONFIG_BOOTDELAY 3 /* autoboot after 3 seconds */
+
+#if 0
+#define CONFIG_PREBOOT \
+ "crc32 f0207004 ffc 0;" \
+ "if cmp 0 f0207000 1;" \
+ "then;echo Old CRC is correct;crc32 f0207004 ff4 f0207000;" \
+ "else;echo Old CRC is bad;fi"
+#endif
+
+#undef CONFIG_BOOTARGS
+#define CONFIG_RAMBOOTCOMMAND \
+ "setenv bootargs root=/dev/ram rw nfsroot=$(serverip):$(rootpath) " \
+ "ip=$(ipaddr):$(serverip):$(gatewayip):$(netmask):$(hostname)::off;" \
+ "bootm ffc00000 ffca0000"
+#define CONFIG_NFSBOOTCOMMAND \
+ "setenv bootargs root=/dev/nfs rw nfsroot=$(serverip):$(rootpath) " \
+ "ip=$(ipaddr):$(serverip):$(gatewayip):$(netmask):$(hostname)::off;" \
+ "bootm ffc00000"
+#define CONFIG_BOOTCOMMAND CONFIG_RAMBOOTCOMMAND
+
+#define CONFIG_LOADS_ECHO 1 /* echo on for serial download */
+#define CFG_LOADS_BAUD_CHANGE 1 /* allow baudrate change */
+
+#define CONFIG_MII 1 /* MII PHY management */
+#define CONFIG_PHY_ADDR 0 /* PHY address */
+
+#define CONFIG_RTC_M48T35A 1 /* ST Electronics M48 timekeeper */
+
+#define CONFIG_COMMANDS ( CONFIG_CMD_DFL | \
+ CFG_CMD_PCI | \
+ CFG_CMD_IRQ | \
+ CFG_CMD_IDE | \
+ CFG_CMD_ELF | \
+ CFG_CMD_DATE | \
+ CFG_CMD_JFFS2 | \
+ CFG_CMD_I2C | \
+ CFG_CMD_EEPROM )
+
+#define CONFIG_MAC_PARTITION
+#define CONFIG_DOS_PARTITION
+
+/* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */
+#include <cmd_confdefs.h>
+
+#undef CONFIG_WATCHDOG /* watchdog disabled */
+
+#define CONFIG_SDRAM_BANK0 1 /* init onboard SDRAM bank 0 */
+
+/*
+ * Miscellaneous configurable options
+ */
+#define CFG_LONGHELP /* undef to save memory */
+#define CFG_PROMPT "=> " /* Monitor Command Prompt */
+
+#undef CFG_HUSH_PARSER /* use "hush" command parser */
+#ifdef CFG_HUSH_PARSER
+#define CFG_PROMPT_HUSH_PS2 "> "
+#endif
+
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+#define CFG_CBSIZE 1024 /* Console I/O Buffer Size */
+#else
+#define CFG_CBSIZE 256 /* Console I/O Buffer Size */
+#endif
+#define CFG_PBSIZE (CFG_CBSIZE+sizeof(CFG_PROMPT)+16) /* Print Buffer Size */
+#define CFG_MAXARGS 16 /* max number of command args */
+#define CFG_BARGSIZE CFG_CBSIZE /* Boot Argument Buffer Size */
+
+#define CFG_DEVICE_NULLDEV 1 /* include nulldev device */
+
+#define CFG_CONSOLE_INFO_QUIET 1 /* don't print console @ startup*/
+
+#define CFG_MEMTEST_START 0x0400000 /* memtest works on */
+#define CFG_MEMTEST_END 0x0C00000 /* 4 ... 12 MB in DRAM */
+
+#undef CFG_EXT_SERIAL_CLOCK /* no external serial clock used */
+#define CFG_IGNORE_405_UART_ERRATA_59 /* ignore ppc405gp errata #59 */
+#define CFG_BASE_BAUD 691200
+
+/* The following table includes the supported baudrates */
+#define CFG_BAUDRATE_TABLE \
+ { 300, 600, 1200, 2400, 4800, 9600, 19200, 38400, \
+ 57600, 115200, 230400, 460800, 921600 }
+
+#define CFG_LOAD_ADDR 0x100000 /* default load address */
+#define CFG_EXTBDINFO 1 /* To use extended board_into (bd_t) */
+
+#define CFG_HZ 1000 /* decrementer freq: 1 ms ticks */
+
+#define CONFIG_ZERO_BOOTDELAY_CHECK /* check for keypress on bootdelay==0 */
+
+/*-----------------------------------------------------------------------
+ * PCI stuff
+ *-----------------------------------------------------------------------
+ */
+#define PCI_HOST_ADAPTER 0 /* configure as pci adapter */
+#define PCI_HOST_FORCE 1 /* configure as pci host */
+#define PCI_HOST_AUTO 2 /* detected via arbiter enable */
+
+#define CONFIG_PCI /* include pci support */
+#define CONFIG_PCI_HOST PCI_HOST_AUTO /* select pci host function */
+#define CONFIG_PCI_PNP /* do pci plug-and-play */
+ /* resource configuration */
+
+#define CONFIG_PCI_SCAN_SHOW /* print pci devices @ startup */
+
+#define CFG_PCI_SUBSYS_VENDORID 0x12FE /* PCI Vendor ID: esd gmbh */
+#define CFG_PCI_SUBSYS_DEVICEID 0x0405 /* PCI Device ID: CPCI-405 */
+#define CFG_PCI_SUBSYS_DEVICEID2 0x0406 /* PCI Device ID: CPCI-405-A */
+#define CFG_PCI_CLASSCODE 0x0b20 /* PCI Class Code: Processor/PPC*/
+#define CFG_PCI_PTM1LA 0x00000000 /* point to sdram */
+#define CFG_PCI_PTM1MS 0xfc000001 /* 64MB, enable hard-wired to 1 */
+#define CFG_PCI_PTM1PCI 0x00000000 /* Host: use this pci address */
+#define CFG_PCI_PTM2LA 0xffc00000 /* point to flash */
+#define CFG_PCI_PTM2MS 0xffc00001 /* 4MB, enable */
+#define CFG_PCI_PTM2PCI 0x04000000 /* Host: use this pci address */
+
+/*-----------------------------------------------------------------------
+ * IDE/ATA stuff
+ *-----------------------------------------------------------------------
+ */
+#undef CONFIG_IDE_8xx_DIRECT /* no pcmcia interface required */
+#undef CONFIG_IDE_LED /* no led for ide supported */
+#define CONFIG_IDE_RESET 1 /* reset for ide supported */
+
+#define CFG_IDE_MAXBUS 1 /* max. 1 IDE busses */
+#define CFG_IDE_MAXDEVICE (CFG_IDE_MAXBUS*1) /* max. 1 drives per IDE bus */
+
+#define CFG_ATA_BASE_ADDR 0xF0100000
+#define CFG_ATA_IDE0_OFFSET 0x0000
+
+#define CFG_ATA_DATA_OFFSET 0x0000 /* Offset for data I/O */
+#define CFG_ATA_REG_OFFSET 0x0000 /* Offset for normal register accesses */
+#define CFG_ATA_ALT_OFFSET 0x0000 /* Offset for alternate registers */
+
+/*-----------------------------------------------------------------------
+ * Start addresses for the final memory configuration
+ * (Set up by the startup code)
+ * Please note that CFG_SDRAM_BASE _must_ start at 0
+ */
+#define CFG_SDRAM_BASE 0x00000000
+#define CFG_FLASH_BASE 0xFFFC0000
+#define CFG_MONITOR_BASE CFG_FLASH_BASE
+#define CFG_MONITOR_LEN (256 * 1024) /* Reserve 256 kB for Monitor */
+#define CFG_MALLOC_LEN (128 * 1024) /* Reserve 128 kB for malloc() */
+
+/*
+ * For booting Linux, the board info and command line data
+ * have to be in the first 8 MB of memory, since this is
+ * the maximum mapped by the Linux kernel during initialization.
+ */
+#define CFG_BOOTMAPSZ (8 << 20) /* Initial Memory map for Linux */
+/*-----------------------------------------------------------------------
+ * FLASH organization
+ */
+#define CFG_MAX_FLASH_BANKS 2 /* max number of memory banks */
+#define CFG_MAX_FLASH_SECT 256 /* max number of sectors on one chip */
+
+#define CFG_FLASH_ERASE_TOUT 120000 /* Timeout for Flash Erase (in ms) */
+#define CFG_FLASH_WRITE_TOUT 500 /* Timeout for Flash Write (in ms) */
+
+#define CFG_FLASH_WORD_SIZE unsigned short /* flash word size (width) */
+#define CFG_FLASH_ADDR0 0x5555 /* 1st address for flash config cycles */
+#define CFG_FLASH_ADDR1 0x2AAA /* 2nd address for flash config cycles */
+/*
+ * The following defines are added for buggy IOP480 byte interface.
+ * All other boards should use the standard values (CPCI405 etc.)
+ */
+#define CFG_FLASH_READ0 0x0000 /* 0 is standard */
+#define CFG_FLASH_READ1 0x0001 /* 1 is standard */
+#define CFG_FLASH_READ2 0x0002 /* 2 is standard */
+
+#define CFG_FLASH_EMPTY_INFO /* print 'E' for empty sector on flinfo */
+
+#define CFG_JFFS2_FIRST_BANK 0 /* use for JFFS2 */
+#define CFG_JFFS2_NUM_BANKS 1 /* ! second bank contains U-Boot */
+
+#if 0 /* Use NVRAM for environment variables */
+/*-----------------------------------------------------------------------
+ * NVRAM organization
+ */
+#define CFG_ENV_IS_IN_NVRAM 1 /* use NVRAM for environment vars */
+#define CFG_ENV_SIZE 0x0ff8 /* Size of Environment vars */
+#define CFG_ENV_ADDR \
+ (CFG_NVRAM_BASE_ADDR+CFG_NVRAM_SIZE-(CFG_ENV_SIZE+8)) /* Env */
+
+#else /* Use EEPROM for environment variables */
+
+#define CFG_ENV_IS_IN_EEPROM 1 /* use EEPROM for environment vars */
+#define CFG_ENV_OFFSET 0x000 /* environment starts at the beginning of the EEPROM */
+#define CFG_ENV_SIZE 0x800 /* 2048 bytes may be used for env vars*/
+ /* total size of a CAT24WC16 is 2048 bytes */
+#endif
+
+#define CFG_NVRAM_BASE_ADDR 0xf0200000 /* NVRAM base address */
+#define CFG_NVRAM_SIZE (32*1024) /* NVRAM size */
+#define CFG_NVRAM_VXWORKS_OFFS 0x6900 /* Offset for VxWorks eth-addr */
+
+/*-----------------------------------------------------------------------
+ * I2C EEPROM (CAT24WC16) for environment
+ */
+#define CONFIG_HARD_I2C /* I2c with hardware support */
+#define CFG_I2C_SPEED 400000 /* I2C speed and slave address */
+#define CFG_I2C_SLAVE 0x7F
+
+#define CFG_I2C_EEPROM_ADDR 0x50 /* EEPROM CAT28WC08 */
+#define CFG_I2C_EEPROM_ADDR_LEN 1 /* Bytes of address */
+/* mask of address bits that overflow into the "EEPROM chip address" */
+#define CFG_I2C_EEPROM_ADDR_OVERFLOW 0x07
+#define CFG_EEPROM_PAGE_WRITE_BITS 4 /* The Catalyst CAT24WC08 has */
+ /* 16 byte page write mode using*/
+ /* last 4 bits of the address */
+#define CFG_EEPROM_PAGE_WRITE_DELAY_MS 10 /* and takes up to 10 msec */
+#define CFG_EEPROM_PAGE_WRITE_ENABLE
+
+/*-----------------------------------------------------------------------
+ * Cache Configuration
+ */
+#define CFG_DCACHE_SIZE 16384 /* For IBM 405 CPUs, older 405 ppc's */
+ /* have only 8kB, 16kB is save here */
+#define CFG_CACHELINE_SIZE 32 /* ... */
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+#define CFG_CACHELINE_SHIFT 5 /* log base 2 of the above value */
+#endif
+
+/*
+ * Init Memory Controller:
+ *
+ * BR0/1 and OR0/1 (FLASH)
+ */
+
+#define FLASH_BASE0_PRELIM 0xFF800000 /* FLASH bank #0 */
+#define FLASH_BASE1_PRELIM 0xFFC00000 /* FLASH bank #1 */
+
+/*-----------------------------------------------------------------------
+ * External Bus Controller (EBC) Setup
+ */
+
+/* Memory Bank 0 (Flash Bank 0) initialization */
+#define CFG_EBC_PB0AP 0x92015480
+#define CFG_EBC_PB0CR 0xFFC5A000 /* BAS=0xFFC,BS=4MB,BU=R/W,BW=16bit */
+
+/* Memory Bank 1 (Flash Bank 1) initialization */
+#define CFG_EBC_PB1AP 0x92015480
+#define CFG_EBC_PB1CR 0xFF85A000 /* BAS=0xFF8,BS=4MB,BU=R/W,BW=16bit */
+
+/* Memory Bank 2 (CAN0, 1) initialization */
+#define CFG_EBC_PB2AP 0x010053C0 /* BWT=2,WBN=1,WBF=1,TH=1,RE=1,SOR=1,BEM=1 */
+#define CFG_EBC_PB2CR 0xF0018000 /* BAS=0xF00,BS=1MB,BU=R/W,BW=8bit */
+
+/* Memory Bank 3 (CompactFlash IDE) initialization */
+#define CFG_EBC_PB3AP 0x010053C0 /* BWT=2,WBN=1,WBF=1,TH=1,RE=1,SOR=1,BEM=1 */
+#define CFG_EBC_PB3CR 0xF011A000 /* BAS=0xF01,BS=1MB,BU=R/W,BW=16bit */
+
+/* Memory Bank 4 (NVRAM/RTC) initialization */
+#define CFG_EBC_PB4AP 0x01005280 /* TWT=2,WBN=1,WBF=1,TH=1,SOR=1 */
+#define CFG_EBC_PB4CR 0xF0218000 /* BAS=0xF02,BS=1MB,BU=R/W,BW=8bit */
+
+/* Memory Bank 5 (optional Quart) initialization */
+#define CFG_EBC_PB5AP 0x04005B80 /* TWT=8,WBN=1,WBF=1,TH=5,RE=1,SOR=1*/
+#define CFG_EBC_PB5CR 0xF0318000 /* BAS=0xF03,BS=1MB,BU=R/W,BW=8bit */
+
+/* Memory Bank 6 (FPGA internal) initialization */
+#define CFG_EBC_PB6AP 0x010053C0 /* BWT=2,WBN=1,WBF=1,TH=1,RE=1,SOR=1,BEM=1 */
+#define CFG_EBC_PB6CR 0xF041A000 /* BAS=0xF01,BS=1MB,BU=R/W,BW=16bit */
+#define CFG_FPGA_BASE_ADDR 0xF0400000
+
+/*-----------------------------------------------------------------------
+ * FPGA stuff
+ */
+/* FPGA internal regs */
+#define CFG_FPGA_MODE 0x00
+#define CFG_FPGA_STATUS 0x02
+#define CFG_FPGA_TS 0x04
+#define CFG_FPGA_TS_LOW 0x06
+#define CFG_FPGA_TS_CAP0 0x10
+#define CFG_FPGA_TS_CAP0_LOW 0x12
+#define CFG_FPGA_TS_CAP1 0x14
+#define CFG_FPGA_TS_CAP1_LOW 0x16
+#define CFG_FPGA_TS_CAP2 0x18
+#define CFG_FPGA_TS_CAP2_LOW 0x1a
+#define CFG_FPGA_TS_CAP3 0x1c
+#define CFG_FPGA_TS_CAP3_LOW 0x1e
+
+/* FPGA Mode Reg */
+#define CFG_FPGA_MODE_CF_RESET 0x0001
+#define CFG_FPGA_MODE_TS_IRQ_ENABLE 0x0100
+#define CFG_FPGA_MODE_TS_IRQ_CLEAR 0x1000
+#define CFG_FPGA_MODE_TS_CLEAR 0x2000
+
+/* FPGA Status Reg */
+#define CFG_FPGA_STATUS_DIP0 0x0001
+#define CFG_FPGA_STATUS_DIP1 0x0002
+#define CFG_FPGA_STATUS_DIP2 0x0004
+#define CFG_FPGA_STATUS_FLASH 0x0008
+#define CFG_FPGA_STATUS_TS_IRQ 0x1000
+
+#define CFG_FPGA_SPARTAN2 1 /* using Xilinx Spartan 2 now */
+#define CFG_FPGA_MAX_SIZE 32*1024 /* 32kByte is enough for XC2S15 */
+
+/* FPGA program pin configuration */
+#define CFG_FPGA_PRG 0x04000000 /* FPGA program pin (ppc output) */
+#define CFG_FPGA_CLK 0x02000000 /* FPGA clk pin (ppc output) */
+#define CFG_FPGA_DATA 0x01000000 /* FPGA data pin (ppc output) */
+#define CFG_FPGA_INIT 0x00010000 /* FPGA init pin (ppc input) */
+#define CFG_FPGA_DONE 0x00008000 /* FPGA done pin (ppc input) */
+
+/*-----------------------------------------------------------------------
+ * Definitions for initial stack pointer and data area (in data cache)
+ */
+#if 1 /* test-only */
+#define CFG_INIT_DCACHE_CS 7 /* use cs # 7 for data cache memory */
+
+#define CFG_INIT_RAM_ADDR 0x40000000 /* use data cache */
+#else
+#define CFG_INIT_RAM_ADDR 0x00df0000 /* inside of SDRAM */
+#endif
+#define CFG_INIT_RAM_END 0x2000 /* End of used area in RAM */
+#define CFG_GBL_DATA_SIZE 128 /* size in bytes reserved for initial data */
+#define CFG_GBL_DATA_OFFSET (CFG_INIT_RAM_END - CFG_GBL_DATA_SIZE)
+#define CFG_INIT_SP_OFFSET CFG_GBL_DATA_OFFSET
+
+
+/*
+ * Internal Definitions
+ *
+ * Boot Flags
+ */
+#define BOOTFLAG_COLD 0x01 /* Normal Power-On: Boot from FLASH */
+#define BOOTFLAG_WARM 0x02 /* Software reboot */
+
+#endif /* __CONFIG_H */
--- /dev/null
+/*
+ * (C) Copyright 2001
+ * Stefan Roese, esd gmbh germany, stefan.roese@esd-electronics.com
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/*
+ * board/config.h - configuration options, board specific
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+/*
+ * High Level Configuration Options
+ * (easy to change)
+ */
+
+#define CONFIG_405GP 1 /* This is a PPC405 CPU */
+#define CONFIG_4xx 1 /* ...member of PPC4xx family */
+#define CONFIG_CPCIISER4 1 /* ...on a CPCIISER4 board */
+
+#define CONFIG_BOARD_PRE_INIT 1 /* call board_pre_init() */
+
+#define CONFIG_SYS_CLK_FREQ 25000000 /* external frequency to pll */
+
+#define CONFIG_BAUDRATE 9600
+#define CONFIG_BOOTDELAY 3 /* autoboot after 3 seconds */
+
+#undef CONFIG_BOOTARGS
+#define CONFIG_BOOTCOMMAND "bootm fff00000"
+
+#define CONFIG_LOADS_ECHO 1 /* echo on for serial download */
+#define CFG_LOADS_BAUD_CHANGE 1 /* allow baudrate change */
+
+#define CONFIG_MII 1 /* MII PHY management */
+#define CONFIG_PHY_ADDR 0 /* PHY address */
+
+#define CONFIG_COMMANDS ( CONFIG_CMD_DFL | \
+ CFG_CMD_PCI | \
+ CFG_CMD_IRQ | \
+ CFG_CMD_ELF | \
+ CFG_CMD_EEPROM )
+
+/* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */
+#include <cmd_confdefs.h>
+
+#undef CONFIG_WATCHDOG /* watchdog disabled */
+
+#define CONFIG_SDRAM_BANK0 1 /* init onboard SDRAM bank 0 */
+
+/*
+ * Miscellaneous configurable options
+ */
+#define CFG_LONGHELP /* undef to save memory */
+#define CFG_PROMPT "=> " /* Monitor Command Prompt */
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+#define CFG_CBSIZE 1024 /* Console I/O Buffer Size */
+#else
+#define CFG_CBSIZE 256 /* Console I/O Buffer Size */
+#endif
+#define CFG_PBSIZE (CFG_CBSIZE+sizeof(CFG_PROMPT)+16) /* Print Buffer Size */
+#define CFG_MAXARGS 16 /* max number of command args */
+#define CFG_BARGSIZE CFG_CBSIZE /* Boot Argument Buffer Size */
+
+#define CFG_CONSOLE_INFO_QUIET 1 /* don't print console @ startup*/
+
+#define CFG_MEMTEST_START 0x0400000 /* memtest works on */
+#define CFG_MEMTEST_END 0x0C00000 /* 4 ... 12 MB in DRAM */
+
+#define CFG_EXT_SERIAL_CLOCK 1843200 /* use external serial clock */
+
+/* The following table includes the supported baudrates */
+#define CFG_BAUDRATE_TABLE \
+ { 300, 600, 1200, 2400, 4800, 9600, 19200, 38400, \
+ 57600, 115200, 230400, 460800, 921600 }
+
+#define CFG_LOAD_ADDR 0x100000 /* default load address */
+#define CFG_EXTBDINFO 1 /* To use extended board_into (bd_t) */
+
+#define CFG_HZ 1000 /* decrementer freq: 1 ms ticks */
+
+#define CONFIG_ZERO_BOOTDELAY_CHECK /* check for keypress on bootdelay==0 */
+
+/*-----------------------------------------------------------------------
+ * PCI stuff
+ *-----------------------------------------------------------------------
+ */
+#define PCI_HOST_ADAPTER 0 /* configure ar pci adapter */
+#define PCI_HOST_FORCE 1 /* configure as pci host */
+#define PCI_HOST_AUTO 2 /* detected via arbiter enable */
+
+#define CONFIG_PCI /* include pci support */
+#define CONFIG_PCI_HOST PCI_HOST_AUTO /* select pci host function */
+#define CONFIG_PCI_PNP /* do pci plug-and-play */
+ /* resource configuration */
+
+#define CFG_PCI_SUBSYS_VENDORID 0x12FE /* PCI Vendor ID: esd gmbh */
+#define CFG_PCI_SUBSYS_DEVICEID 0x0404 /* PCI Device ID: CPCI-ISER4 */
+#define CFG_PCI_PTM1LA 0x00000000 /* point to sdram */
+#define CFG_PCI_PTM1MS 0xff000001 /* 16MB, enable hard-wired to 1 */
+#define CFG_PCI_PTM1PCI 0x00000000 /* Host: use this pci address */
+#define CFG_PCI_PTM2LA 0xffe00000 /* point to flash */
+#define CFG_PCI_PTM2MS 0xffe00001 /* 2MB, enable */
+#define CFG_PCI_PTM2PCI 0x04000000 /* Host: use this pci address */
+
+/*-----------------------------------------------------------------------
+ * Start addresses for the final memory configuration
+ * (Set up by the startup code)
+ * Please note that CFG_SDRAM_BASE _must_ start at 0
+ */
+#define CFG_SDRAM_BASE 0x00000000
+#define CFG_FLASH_BASE 0xFFFC0000
+#define CFG_MONITOR_BASE CFG_FLASH_BASE
+#define CFG_MONITOR_LEN (256 * 1024) /* Reserve 256 kB for Monitor */
+#define CFG_MALLOC_LEN (128 * 1024) /* Reserve 128 kB for malloc() */
+
+/*
+ * For booting Linux, the board info and command line data
+ * have to be in the first 8 MB of memory, since this is
+ * the maximum mapped by the Linux kernel during initialization.
+ */
+#define CFG_BOOTMAPSZ (8 << 20) /* Initial Memory map for Linux */
+/*-----------------------------------------------------------------------
+ * FLASH organization
+ */
+#define CFG_MAX_FLASH_BANKS 1 /* max number of memory banks */
+#define CFG_MAX_FLASH_SECT 256 /* max number of sectors on one chip */
+
+#define CFG_FLASH_ERASE_TOUT 120000 /* Timeout for Flash Erase (in ms) */
+#define CFG_FLASH_WRITE_TOUT 500 /* Timeout for Flash Write (in ms) */
+
+#define CFG_FLASH_WORD_SIZE unsigned short /* flash word size (width) */
+#define CFG_FLASH_ADDR0 0x5555 /* 1st address for flash config cycles */
+#define CFG_FLASH_ADDR1 0x2AAA /* 2nd address for flash config cycles */
+/*
+ * The following defines are added for buggy IOP480 byte interface.
+ * All other boards should use the standard values (CPCI405 etc.)
+ */
+#define CFG_FLASH_READ0 0x0000 /* 0 is standard */
+#define CFG_FLASH_READ1 0x0001 /* 1 is standard */
+#define CFG_FLASH_READ2 0x0002 /* 2 is standard */
+
+#define CFG_FLASH_EMPTY_INFO /* print 'E' for empty sector on flinfo */
+
+/*-----------------------------------------------------------------------
+ * I2C EEPROM (CAT24WC08) for environment
+ */
+#define CONFIG_HARD_I2C /* I2C with hardware support */
+#define CFG_I2C_SPEED 400000 /* I2C speed and slave address */
+#define CFG_I2C_SLAVE 0x7F
+
+#define CFG_I2C_EEPROM_ADDR 0x50 /* EEPROM CAT28WC08 */
+#define CFG_I2C_EEPROM_ADDR_LEN 1 /* Bytes of address */
+/* mask of address bits that overflow into the "EEPROM chip address" */
+#define CFG_I2C_EEPROM_ADDR_OVERFLOW 0x07
+#define CFG_EEPROM_PAGE_WRITE_BITS 4 /* The Catalyst CAT24WC08 has */
+ /* 16 byte page write mode using*/
+ /* last 4 bits of the address */
+#define CFG_EEPROM_PAGE_WRITE_DELAY_MS 10 /* and takes up to 10 msec */
+#define CFG_EEPROM_PAGE_WRITE_ENABLE
+
+#define CFG_ENV_IS_IN_EEPROM 1 /* use EEPROM for environment vars */
+#define CFG_ENV_OFFSET 0x000 /* environment starts at the beginning of the EEPROM */
+#define CFG_ENV_SIZE 0x300 /* 768 bytes may be used for env vars */
+ /* total size of a CAT24WC08 is 1024 bytes */
+
+/*-----------------------------------------------------------------------
+ * Cache Configuration
+ */
+#define CFG_DCACHE_SIZE 8192 /* For IBM 405 CPUs */
+#define CFG_CACHELINE_SIZE 32 /* ... */
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+#define CFG_CACHELINE_SHIFT 5 /* log base 2 of the above value */
+#endif
+
+/*
+ * Init Memory Controller:
+ *
+ * BR0/1 and OR0/1 (FLASH)
+ */
+
+#define FLASH_BASE0_PRELIM 0xFFF00000 /* FLASH bank #0 */
+#define FLASH_BASE1_PRELIM 0 /* FLASH bank #1 */
+
+/*-----------------------------------------------------------------------
+ * External Bus Controller (EBC) Setup
+ */
+
+/* Memory Bank 0 (Flash Bank 0) initialization */
+#define CFG_EBC_PB0AP 0x92015480
+#define CFG_EBC_PB0CR 0xFFC5A000 /* BAS=0xFFC,BS=4MB,BU=R/W,BW=16bit */
+
+/* Memory Bank 1 (Uart 8bit) initialization */
+#define CFG_EBC_PB1AP 0x01000480 /* TWT=2,TH=2,no Ready,BEM=0,SOR=1 */
+#define CFG_EBC_PB1CR 0xF0018000 /* BAS=0xF00,BS=1MB,BU=R/W,BW=8bit */
+
+/* Memory Bank 2 (Uart 32bit) initialization */
+#define CFG_EBC_PB2AP 0x000004c0 /* no Ready, BEM=1 */
+#define CFG_EBC_PB2CR 0xF011C000 /* BAS=0xF01,BS=1MB,BU=R/W,BW=32bit */
+
+/* Memory Bank 3 (FPGA Reset) initialization */
+#define CFG_EBC_PB3AP 0x010004C0 /* no Ready, BEM=1 */
+#define CFG_EBC_PB3CR 0xF021A000 /* BAS=0xF02,BS=1MB,BU=R/W,BW=16bit */
+
+/*-----------------------------------------------------------------------
+ * Definitions for initial stack pointer and data area (in DPRAM)
+ */
+#define CFG_INIT_RAM_ADDR 0x00df0000 /* inside of SDRAM */
+#define CFG_INIT_RAM_END 0x0f00 /* End of used area in RAM */
+#define CFG_GBL_DATA_SIZE 64 /* size in bytes reserved for initial data */
+#define CFG_GBL_DATA_OFFSET (CFG_INIT_RAM_END - CFG_GBL_DATA_SIZE)
+#define CFG_INIT_SP_OFFSET CFG_GBL_DATA_OFFSET
+
+
+/*
+ * Internal Definitions
+ *
+ * Boot Flags
+ */
+#define BOOTFLAG_COLD 0x01 /* Normal Power-On: Boot from FLASH */
+#define BOOTFLAG_WARM 0x02 /* Software reboot */
+
+#endif /* __CONFIG_H */
--- /dev/null
+/*
+ * (C) Copyright 2000, 2001
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ * David Updegraff, Cray, Inc. dave@cray.com: our 405 is walnut-lite..
+ *
+ * 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
+ */
+/*
+ * board/config.h - configuration options, board specific
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+#define CONFIG_CRAYL1
+/*
+ * High Level Configuration Options
+ * (easy to change)
+ */
+
+#define CONFIG_405GP 1 /* This is a PPC405 CPU */
+#define CONFIG_4xx 1 /* ...member of PPC405 family */
+#define CONFIG_SYS_CLK_FREQ 25000000
+#define CONFIG_BAUDRATE 9600
+#define CONFIG_BOOTDELAY 5 /* autoboot after 5 seconds */
+#define CONFIG_MII 1 /* MII PHY management */
+#define CONFIG_PHY_ADDR 1 /* PHY address; handling of ENET */
+#define CONFIG_BOARD_PRE_INIT 1 /* setup for 405gp */
+#define CONFIG_MISC_INIT_R 1 /* so that a misc_init_r() is called */
+
+/* set PRAM to keep U-Boot out, mem= to keep linux out, and initrd_hi to
+ * keep possible initrd ramdisk decompression out. This is in k (1024 bytes)
+ #define CONFIG_PRAM 16
+ */
+#define CONFIG_LOADADDR 0x100000
+#undef CONFIG_BOOTARGS
+
+/* the logic is that booting is driven by what env vars get set from DHCP.
+ * Normal DHCP sets things like serverip, rootpath, etc.
+ * if printenv
+ */
+#define CFG_AUTOLOAD "yes"
+#define CONFIG_BOOTCOMMAND "dhcp;"\
+ "setenv bootargs devfs=mount;"\
+ "setenv bootargs ip=$ipaddr:$serverip:$gatewayip:$netmask:::off $bootargs;"\
+ "if printenv initrd;"\
+ "then;" \
+ "setenv initrd_hi $mem;"\
+ "tftp 1000000 $initrd;"\
+ "setenv bootargs root=/dev/ram0 rw cwsroot=$serverip:$rootpath $bootargs;"\
+ "bootm 100000 1000000;"\
+ "else;"\
+ "setenv bootargs root=/dev/nfs ro nfsroot=$serverip:$rootpath $bootargs;"\
+ "bootm 100000;"\
+ "fi;"
+
+#define CONFIG_EXTRA_ENV_SETTINGS ""
+
+/*
+ * ..during experiments..
+ #define CONFIG_SERVERIP 10.0.0.1
+ #define CONFIG_ETHADDR 00:40:a6:80:14:5
+ */
+#define CONFIG_HARD_I2C 1 /* hardware support for i2c */
+#define CFG_I2C_SPEED 400000 /* I2C speed and slave address */
+#define CFG_I2C_SLAVE 0x7F
+#define CFG_I2C_EEPROM_ADDR 0x57
+#define CFG_I2C_EEPROM_ADDR_LEN 1
+#define CONFIG_IDENT_STRING "Cray L1"
+#define CONFIG_ENV_OVERWRITE 1
+#define CFG_HZ 1000 /* decrementer freq: 1 ms ticks */
+#define CFG_HUSH_PARSER 1
+#define CFG_PROMPT_HUSH_PS2 "> "
+
+
+#define CONFIG_COMMANDS (\
+ CFG_CMD_BDI|\
+ CFG_CMD_IMI|\
+ CFG_CMD_FLASH|\
+ CFG_CMD_MEMORY|\
+ CFG_CMD_NET|\
+ CFG_CMD_ENV|\
+ CFG_CMD_CONSOLE|\
+ CFG_CMD_ASKENV|\
+ CFG_CMD_ECHO|\
+ CFG_CMD_IMMAP|\
+ CFG_CMD_REGINFO|\
+ CFG_CMD_DHCP|\
+ CFG_CMD_DATE|\
+ CFG_CMD_RUN|\
+ CFG_CMD_I2C|\
+ CFG_CMD_EEPROM|\
+ CFG_CMD_SETGETDCR)
+
+/*
+ * optional BOOTP / DHCP fields
+ */
+#define CONFIG_BOOTP_MASK (\
+ CONFIG_BOOTP_VENDOREX|\
+ CONFIG_BOOTP_SUBNETMASK|\
+ CONFIG_BOOTP_GATEWAY|\
+ CONFIG_BOOTP_DNS|\
+ CONFIG_BOOTP_HOSTNAME|\
+ CONFIG_BOOTP_BOOTFILESIZE|\
+ CONFIG_BOOTP_BOOTPATH)
+
+/*
+ * bauds. Just to make it compile; in our case, I read the base_baud
+ * from the DCR anyway, so its kinda-tied to the above ref. clock which in turn
+ * drives the system clock.
+ */
+#define CFG_BASE_BAUD 403225
+#define CFG_BAUDRATE_TABLE \
+ {300, 600, 1200, 2400, 4800, 9600, 19200, 38400, 57600, 115200, 230400}
+
+/* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */
+#include <cmd_confdefs.h>
+
+/*
+ * Miscellaneous configurable options
+ */
+#define CFG_PROMPT "=> " /* Monitor Command Prompt */
+#define CFG_CBSIZE 256 /* Console I/O Buffer Size */
+#define CFG_BARGSIZE CFG_CBSIZE /* Boot Argument Buffer Size */
+#define CFG_PBSIZE (CFG_CBSIZE+sizeof(CFG_PROMPT)+16) /* Print Buffer Size */
+#define CFG_MAXARGS 16 /* max number of command args */
+
+
+#define CFG_LOAD_ADDR 0x100000/* where to load what we get from TFTP */
+#define CFG_TFTP_LOADADDR CFG_LOAD_ADDR
+#define CFG_EXTBDINFO 1 /* To use extended board_into (bd_t) */
+
+/*-----------------------------------------------------------------------
+ * Start addresses for the final memory configuration
+ * (Set up by the startup code)
+ * Please note that CFG_SDRAM_BASE _must_ start at 0
+ */
+#define CFG_SDRAM_BASE 0x00000000
+#define CFG_FLASH_BASE 0xFFC00000
+#define CFG_MONITOR_BASE TEXT_BASE
+
+#ifndef CFG_HUSH_PARSER
+#define CFG_MONITOR_LEN (128 * 1024) /* Reserve 128 kB for Monitor */
+#define CFG_ENV_OFFSET 0x3D0000
+#else
+#define CFG_MONITOR_LEN (192 * 1024) /* Reserve 192 kB for Monitor */
+#define CFG_ENV_OFFSET 0x3FE000
+#endif
+
+#define CFG_MALLOC_LEN (128 * 1024) /* Reserve 128 kB for malloc() */
+
+/*
+ * For booting Linux, the board info and command line data
+ * have to be in the first 8 MB of memory, since this is
+ * the maximum mapped by the Linux kernel during initialization.
+ */
+#define CFG_BOOTMAPSZ (8 << 20) /* Initial Memory map for Linux */
+/*-----------------------------------------------------------------------
+ * FLASH organization
+ */
+#define CFG_MAX_FLASH_BANKS 1 /* max number of memory banks */
+#define CFG_MAX_FLASH_SECT 64 /* max number of sectors on one chip */
+#define CFG_FLASH_ERASE_TOUT 120000 /* Timeout for Flash Erase (in ms) */
+#define CFG_FLASH_WRITE_TOUT 500 /* Timeout for Flash Write (in ms) */
+
+/* BEG ENVIRONNEMENT FLASH: needs to be a whole FlashSector */
+#define CFG_ENV_IS_IN_FLASH 1 /* use FLASH for environment vars */
+#define CFG_ENV_SIZE 0x1000 /* Total Size of Environment Sector */
+#define CFG_ENV_SECT_SIZE 0x10000 /* see README - env sector total size */
+
+/* Memory tests: U-Boot relocates itself to the top of Ram, so its at
+ * 32meg-(128k+some_malloc_space+copy-of-ENV sector)..
+ */
+#define CFG_SDRAM_SIZE 32 /* megs of ram */
+#define CFG_MEMTEST_START 0x2000 /* memtest works from the end of */
+ /* the exception vector table */
+ /* to the end of the DRAM */
+ /* less monitor and malloc area */
+#define CFG_STACK_USAGE 0x10000 /* Reserve 64k for the stack usage */
+#define CFG_MEM_END_USAGE ( CFG_MONITOR_LEN \
+ + CFG_MALLOC_LEN \
+ + CFG_ENV_SECT_SIZE \
+ + CFG_STACK_USAGE )
+
+#define CFG_MEMTEST_END (CFG_SDRAM_SIZE * 1024 * 1024 - CFG_MEM_END_USAGE)
+/* END ENVIRONNEMENT FLASH */
+
+/*-----------------------------------------------------------------------
+ * Cache Configuration. Only used to ..?? clear it, I guess..
+ */
+#define CFG_DCACHE_SIZE 16384
+#define CFG_CACHELINE_SIZE 32
+
+/*
+ * Init Memory Controller:
+ *
+ * BR0/1 and OR0/1 (FLASH)
+ */
+
+#define FLASH_BASE0_PRELIM CFG_FLASH_BASE /* FLASH bank #0 */
+
+
+/*-----------------------------------------------------------------------
+ * Definitions for initial stack pointer and data area (in OnChipMem )
+ */
+#if 0
+#define CFG_INIT_RAM_ADDR 0x40000000 /* use data cache */
+#define CFG_INIT_RAM_END 0x2000 /* End of used area in RAM */
+#else
+#define CFG_TEMP_STACK_OCM 1
+#define CFG_OCM_DATA_ADDR 0xF0000000
+#define CFG_OCM_DATA_SIZE 0x1000
+#define CFG_INIT_RAM_ADDR CFG_OCM_DATA_ADDR /* inside of On Chip SRAM */
+#define CFG_INIT_RAM_END CFG_OCM_DATA_SIZE /* End of On Chip SRAM */
+#endif
+
+#define CFG_GBL_DATA_SIZE 64 /* size in bytes reserved for initial data */
+#define CFG_GBL_DATA_OFFSET (CFG_INIT_RAM_END - CFG_GBL_DATA_SIZE)
+#define CFG_INIT_SP_OFFSET CFG_GBL_DATA_OFFSET
+
+/*-----------------------------------------------------------------------
+ * Definitions for Serial Presence Detect EEPROM address
+ */
+#define EEPROM_WRITE_ADDRESS 0xA0
+#define EEPROM_READ_ADDRESS 0xA1
+
+/*
+ * Internal Definitions
+ *
+ * Boot Flags
+ */
+#define BOOTFLAG_COLD 0x01 /* Normal Power-On: Boot from FLASH */
+#define BOOTFLAG_WARM 0x02 /* Software reboot */
+
+#endif /* __CONFIG_H */
--- /dev/null
+/*
+ * (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
+ */
+
+/*
+ *
+ * Configuration settings for the CU824 board.
+ *
+ */
+
+/* ------------------------------------------------------------------------- */
+
+/*
+ * board/config.h - configuration options, board specific
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+/*
+ * High Level Configuration Options
+ * (easy to change)
+ */
+
+#define CONFIG_MPC824X 1
+#define CONFIG_MPC8240 1
+#define CONFIG_CU824 1
+
+
+#define CONFIG_CONS_INDEX 1
+#define CONFIG_BAUDRATE 9600
+#define CFG_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 }
+
+#define CONFIG_CLOCKS_IN_MHZ 1 /* clocks passsed to Linux in MHz */
+
+#define CONFIG_PREBOOT "echo;echo Type \"run flash_nfs\" to mount root filesystem over NFS;echo"
+
+#define CONFIG_BOOTCOMMAND "bootm FE020000" /* autoboot command */
+#define CONFIG_BOOTDELAY 5
+
+#define CONFIG_BOOTP_MASK (CONFIG_BOOTP_DEFAULT | CONFIG_BOOTP_BOOTFILESIZE)
+
+#define CONFIG_COMMANDS ( CONFIG_CMD_DFL | \
+ CFG_CMD_DHCP | \
+ CFG_CMD_PCI | \
+ 0/* CFG_CMD_DATE */ )
+
+/* This must be included AFTER the definition of CONFIG_COMMANDS (if any)
+ */
+#include <cmd_confdefs.h>
+
+
+/*
+ * Miscellaneous configurable options
+ */
+#define CFG_LONGHELP /* undef to save memory */
+#define CFG_PROMPT "=> " /* Monitor Command Prompt */
+#define CFG_CBSIZE 256 /* Console I/O Buffer Size */
+
+#if 1
+#define CFG_HUSH_PARSER 1 /* use "hush" command parser */
+#endif
+#ifdef CFG_HUSH_PARSER
+#define CFG_PROMPT_HUSH_PS2 "> "
+#endif
+
+/* Print Buffer Size
+ */
+#define CFG_PBSIZE (CFG_CBSIZE + sizeof(CFG_PROMPT) + 16)
+
+#define CFG_MAXARGS 16 /* max number of command args */
+#define CFG_BARGSIZE CFG_CBSIZE /* Boot Argument Buffer Size */
+#define CFG_LOAD_ADDR 0x00100000 /* Default load address */
+
+/*-----------------------------------------------------------------------
+ * Start addresses for the final memory configuration
+ * (Set up by the startup code)
+ * Please note that CFG_SDRAM_BASE _must_ start at 0
+ */
+#define CFG_SDRAM_BASE 0x00000000
+#define CFG_FLASH_BASE 0xFF000000
+
+#define CFG_RESET_ADDRESS 0xFFF00100
+
+#define CFG_EUMB_ADDR 0xFCE00000
+
+#define CFG_MONITOR_BASE TEXT_BASE
+
+#define CFG_MONITOR_LEN (256 << 10) /* Reserve 256 kB for Monitor */
+#define CFG_MALLOC_LEN (128 << 10) /* Reserve 128 kB for malloc() */
+
+#define CFG_MEMTEST_START 0x00004000 /* memtest works on */
+#define CFG_MEMTEST_END 0x02000000 /* 0 ... 32 MB in DRAM */
+
+ /* Maximum amount of RAM.
+ */
+#define CFG_MAX_RAM_SIZE 0x10000000
+
+
+#if CFG_MONITOR_BASE >= CFG_FLASH_BASE
+#undef CFG_RAMBOOT
+#else
+#define CFG_RAMBOOT
+#endif
+
+
+/*-----------------------------------------------------------------------
+ * Definitions for initial stack pointer and data area
+ */
+
+ /* Size in bytes reserved for initial data
+ */
+#define CFG_GBL_DATA_SIZE 128
+
+#define CFG_INIT_RAM_ADDR 0x40000000
+#define CFG_INIT_RAM_END 0x1000
+#define CFG_GBL_DATA_OFFSET (CFG_INIT_RAM_END - CFG_GBL_DATA_SIZE)
+
+/*
+ * NS16550 Configuration
+ */
+#define CFG_NS16550
+#define CFG_NS16550_SERIAL
+
+#define CFG_NS16550_REG_SIZE 4
+
+#define CFG_NS16550_CLK (14745600 / 2)
+
+#define CFG_NS16550_COM1 0xFE800080
+#define CFG_NS16550_COM2 0xFE8000C0
+
+/*
+ * Low Level Configuration Settings
+ * (address mappings, register initial values, etc.)
+ * You should know what you are doing if you make changes here.
+ * For the detail description refer to the MPC8240 user's manual.
+ */
+
+#define CONFIG_SYS_CLK_FREQ 33000000
+#define CFG_HZ 1000
+
+ /* Bit-field values for MCCR1.
+ */
+#define CFG_ROMNAL 0
+#define CFG_ROMFAL 7
+
+ /* Bit-field values for MCCR2.
+ */
+#define CFG_REFINT 430 /* Refresh interval */
+
+ /* Burst To Precharge. Bits of this value go to MCCR3 and MCCR4.
+ */
+#define CFG_BSTOPRE 192
+
+ /* Bit-field values for MCCR3.
+ */
+#define CFG_REFREC 2 /* Refresh to activate interval */
+#define CFG_RDLAT 3 /* Data latancy from read command */
+
+ /* Bit-field values for MCCR4.
+ */
+#define CFG_PRETOACT 2 /* Precharge to activate interval */
+#define CFG_ACTTOPRE 5 /* Activate to Precharge interval */
+#define CFG_SDMODE_CAS_LAT 2 /* SDMODE CAS latancy */
+#define CFG_SDMODE_WRAP 0 /* SDMODE wrap type */
+#define CFG_SDMODE_BURSTLEN 2 /* SDMODE Burst length */
+#define CFG_ACTORW 2
+#define CFG_REGISTERD_TYPE_BUFFER 1
+
+/* Memory bank settings.
+ * Only bits 20-29 are actually used from these vales to set the
+ * start/end addresses. The upper two bits will always be 0, and the lower
+ * 20 bits will be 0x00000 for a start address, or 0xfffff for an end
+ * address. Refer to the MPC8240 book.
+ */
+
+#define CFG_BANK0_START 0x00000000
+#define CFG_BANK0_END (CFG_MAX_RAM_SIZE - 1)
+#define CFG_BANK0_ENABLE 1
+#define CFG_BANK1_START 0x3ff00000
+#define CFG_BANK1_END 0x3fffffff
+#define CFG_BANK1_ENABLE 0
+#define CFG_BANK2_START 0x3ff00000
+#define CFG_BANK2_END 0x3fffffff
+#define CFG_BANK2_ENABLE 0
+#define CFG_BANK3_START 0x3ff00000
+#define CFG_BANK3_END 0x3fffffff
+#define CFG_BANK3_ENABLE 0
+#define CFG_BANK4_START 0x3ff00000
+#define CFG_BANK4_END 0x3fffffff
+#define CFG_BANK4_ENABLE 0
+#define CFG_BANK5_START 0x3ff00000
+#define CFG_BANK5_END 0x3fffffff
+#define CFG_BANK5_ENABLE 0
+#define CFG_BANK6_START 0x3ff00000
+#define CFG_BANK6_END 0x3fffffff
+#define CFG_BANK6_ENABLE 0
+#define CFG_BANK7_START 0x3ff00000
+#define CFG_BANK7_END 0x3fffffff
+#define CFG_BANK7_ENABLE 0
+
+#define CFG_ODCR 0xff
+
+#define CFG_IBAT0L (CFG_SDRAM_BASE | BATL_PP_10 | BATL_MEMCOHERENCE)
+#define CFG_IBAT0U (CFG_SDRAM_BASE | BATU_BL_256M | BATU_VS | BATU_VP)
+
+#define CFG_IBAT1L (CFG_INIT_RAM_ADDR | BATL_PP_10 | BATL_MEMCOHERENCE)
+#define CFG_IBAT1U (CFG_INIT_RAM_ADDR | BATU_BL_128K | BATU_VS | BATU_VP)
+
+#define CFG_IBAT2L (0x80000000 | BATL_PP_10 | BATL_CACHEINHIBIT)
+#define CFG_IBAT2U (0x80000000 | BATU_BL_256M | BATU_VS | BATU_VP)
+
+#define CFG_IBAT3L (0xFC000000 | BATL_PP_10 | BATL_CACHEINHIBIT)
+#define CFG_IBAT3U (0xFC000000 | BATU_BL_64M | BATU_VS | BATU_VP)
+
+#define CFG_DBAT0L CFG_IBAT0L
+#define CFG_DBAT0U CFG_IBAT0U
+#define CFG_DBAT1L CFG_IBAT1L
+#define CFG_DBAT1U CFG_IBAT1U
+#define CFG_DBAT2L CFG_IBAT2L
+#define CFG_DBAT2U CFG_IBAT2U
+#define CFG_DBAT3L CFG_IBAT3L
+#define CFG_DBAT3U CFG_IBAT3U
+
+/*
+ * For booting Linux, the board info and command line data
+ * have to be in the first 8 MB of memory, since this is
+ * the maximum mapped by the Linux kernel during initialization.
+ */
+#define CFG_BOOTMAPSZ (8 << 20) /* Initial Memory map for Linux */
+
+/*-----------------------------------------------------------------------
+ * FLASH organization
+ */
+#define CFG_MAX_FLASH_BANKS 2 /* Max number of flash banks */
+#define CFG_MAX_FLASH_SECT 39 /* Max number of sectors in one bank */
+
+#define CFG_FLASH_ERASE_TOUT 120000 /* Timeout for Flash Erase (in ms) */
+#define CFG_FLASH_WRITE_TOUT 500 /* Timeout for Flash Write (in ms) */
+
+ /* Warining: environment is not EMBEDDED in the U-Boot code.
+ * It's stored in flash separately.
+ */
+#define CFG_ENV_IS_IN_FLASH 1
+#if 0
+#define CFG_ENV_ADDR 0xFF008000
+#define CFG_ENV_SIZE 0x8000 /* Size of the Environment Sector */
+#else
+#define CFG_ENV_ADDR 0xFFFC0000
+#define CFG_ENV_SIZE 0x4000 /* Size of the Environment */
+#define CFG_ENV_OFFSET 0 /* starting right at the beginning */
+#define CFG_ENV_SECT_SIZE 0x40000 /* Size of the Environment Sector */
+#endif
+
+/*-----------------------------------------------------------------------
+ * Cache Configuration
+ */
+#define CFG_CACHELINE_SIZE 32
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+# define CFG_CACHELINE_SHIFT 5 /* log base 2 of the above value */
+#endif
+
+/*
+ * Internal Definitions
+ *
+ * Boot Flags
+ */
+#define BOOTFLAG_COLD 0x01 /* Normal Power-On: Boot from FLASH */
+#define BOOTFLAG_WARM 0x02 /* Software reboot */
+
+/*-----------------------------------------------------------------------
+ * PCI stuff
+ *-----------------------------------------------------------------------
+ */
+#define CONFIG_PCI /* include pci support */
+#undef CONFIG_PCI_PNP
+
+#define CONFIG_NET_MULTI /* Multi ethernet cards support */
+
+#define CONFIG_TULIP
+#define CONFIG_TULIP_USE_IO
+
+#define CFG_ETH_DEV_FN 0x7800
+#define CFG_ETH_IOBASE 0x00104000
+
+#endif /* __CONFIG_H */
--- /dev/null
+/*
+ * (C) Copyright 2001
+ * Stefan Roese, esd gmbh germany, stefan.roese@esd-electronics.com
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/*
+ * board/config.h - configuration options, board specific
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+/*
+ * High Level Configuration Options
+ * (easy to change)
+ */
+
+#define CONFIG_405GP 1 /* This is a PPC405 CPU */
+#define CONFIG_4xx 1 /* ...member of PPC4xx family */
+#define CONFIG_DU405 1 /* ...on a DU405 board */
+
+#define CONFIG_BOARD_PRE_INIT 1 /* call board_pre_init() */
+
+#define CONFIG_SYS_CLK_FREQ 25000000 /* external frequency to pll */
+
+#define CONFIG_BAUDRATE 9600
+#define CONFIG_BOOTDELAY 3 /* autoboot after 3 seconds */
+
+#undef CONFIG_BOOTARGS
+#define CONFIG_BOOTCOMMAND "bootm fff00000"
+
+#define CONFIG_LOADS_ECHO 1 /* echo on for serial download */
+#define CFG_LOADS_BAUD_CHANGE 1 /* allow baudrate change */
+
+#define CONFIG_MII 1 /* MII PHY management */
+#define CONFIG_PHY_ADDR 0 /* PHY address */
+
+#define CONFIG_COMMANDS ( CONFIG_CMD_DFL | \
+ CFG_CMD_PCI | \
+ CFG_CMD_IRQ | \
+ CFG_CMD_IDE | \
+ CFG_CMD_ELF | \
+ CFG_CMD_DATE | \
+ CFG_CMD_EEPROM )
+
+#define CONFIG_MAC_PARTITION
+#define CONFIG_DOS_PARTITION
+
+/* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */
+#include <cmd_confdefs.h>
+
+#undef CONFIG_WATCHDOG /* watchdog disabled */
+
+#define CONFIG_RTC_MC146818 /* BQ3285 is MC146818 compatible*/
+#define CFG_RTC_REG_BASE_ADDR 0xF0000080 /* RTC Base Address */
+
+#define CONFIG_SDRAM_BANK0 1 /* init onboard SDRAM bank 0 */
+
+/*
+ * Miscellaneous configurable options
+ */
+#define CFG_LONGHELP /* undef to save memory */
+#define CFG_PROMPT "=> " /* Monitor Command Prompt */
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+#define CFG_CBSIZE 1024 /* Console I/O Buffer Size */
+#else
+#define CFG_CBSIZE 256 /* Console I/O Buffer Size */
+#endif
+#define CFG_PBSIZE (CFG_CBSIZE+sizeof(CFG_PROMPT)+16) /* Print Buffer Size */
+#define CFG_MAXARGS 16 /* max number of command args */
+#define CFG_BARGSIZE CFG_CBSIZE /* Boot Argument Buffer Size */
+
+#define CFG_CONSOLE_INFO_QUIET 1 /* don't print console @ startup*/
+
+#define CFG_MEMTEST_START 0x0400000 /* memtest works on */
+#define CFG_MEMTEST_END 0x0C00000 /* 4 ... 12 MB in DRAM */
+
+#define CFG_EXT_SERIAL_CLOCK 11059200 /* use external serial clock */
+
+/* The following table includes the supported baudrates */
+#define CFG_BAUDRATE_TABLE \
+ { 300, 600, 1200, 2400, 4800, 9600, 19200, 38400, \
+ 57600, 115200, 230400, 460800, 921600 }
+
+#define CFG_LOAD_ADDR 0x100000 /* default load address */
+#define CFG_EXTBDINFO 1 /* To use extended board_into (bd_t) */
+
+#define CFG_HZ 1000 /* decrementer freq: 1 ms ticks */
+
+#define CONFIG_ZERO_BOOTDELAY_CHECK /* check for keypress on bootdelay==0 */
+
+/*-----------------------------------------------------------------------
+ * PCI stuff
+ *-----------------------------------------------------------------------
+ */
+#define PCI_HOST_ADAPTER 0 /* configure ar pci adapter */
+#define PCI_HOST_FORCE 1 /* configure as pci host */
+#define PCI_HOST_AUTO 2 /* detected via arbiter enable */
+
+#define CONFIG_PCI /* include pci support */
+#define CONFIG_PCI_HOST PCI_HOST_AUTO /* select pci host function */
+#define CONFIG_PCI_PNP /* do pci plug-and-play */
+ /* resource configuration */
+
+#define CFG_PCI_SUBSYS_VENDORID 0x12FE /* PCI Vendor ID: esd gmbh */
+#define CFG_PCI_SUBSYS_DEVICEID 0x0404 /* PCI Device ID: CPCI-ISER4 */
+#define CFG_PCI_PTM1LA 0x00000000 /* point to sdram */
+#define CFG_PCI_PTM1MS 0xff000001 /* 16MB, enable hard-wired to 1 */
+#define CFG_PCI_PTM1PCI 0x00000000 /* Host: use this pci address */
+#define CFG_PCI_PTM2LA 0xffe00000 /* point to flash */
+#define CFG_PCI_PTM2MS 0xffe00001 /* 2MB, enable */
+#define CFG_PCI_PTM2PCI 0x04000000 /* Host: use this pci address */
+
+/*-----------------------------------------------------------------------
+ * IDE/ATA stuff
+ *-----------------------------------------------------------------------
+ */
+#undef CONFIG_IDE_8xx_DIRECT /* no pcmcia interface required */
+#undef CONFIG_IDE_LED /* no led for ide supported */
+#undef CONFIG_IDE_RESET /* no reset for ide supported */
+
+#define CFG_IDE_MAXBUS 1 /* max. 1 IDE busses */
+#define CFG_IDE_MAXDEVICE (CFG_IDE_MAXBUS*1) /* max. 1 drives per IDE bus */
+
+#define CFG_ATA_BASE_ADDR 0xF0100000
+#define CFG_ATA_IDE0_OFFSET 0x0000
+
+#define CFG_ATA_DATA_OFFSET 0x0000 /* Offset for data I/O */
+#define CFG_ATA_REG_OFFSET 0x0000 /* Offset for normal register accesses */
+#define CFG_ATA_ALT_OFFSET 0x0000 /* Offset for alternate registers */
+
+/*-----------------------------------------------------------------------
+ * Start addresses for the final memory configuration
+ * (Set up by the startup code)
+ * Please note that CFG_SDRAM_BASE _must_ start at 0
+ */
+#define CFG_SDRAM_BASE 0x00000000
+#define CFG_FLASH_BASE 0xFFFD0000
+#define CFG_MONITOR_BASE CFG_FLASH_BASE
+#define CFG_MONITOR_LEN (192 * 1024) /* Reserve 192 kB for Monitor */
+#define CFG_MALLOC_LEN (128 * 1024) /* Reserve 128 kB for malloc() */
+
+/*
+ * For booting Linux, the board info and command line data
+ * have to be in the first 8 MB of memory, since this is
+ * the maximum mapped by the Linux kernel during initialization.
+ */
+#define CFG_BOOTMAPSZ (8 << 20) /* Initial Memory map for Linux */
+/*-----------------------------------------------------------------------
+ * FLASH organization
+ */
+#define CFG_MAX_FLASH_BANKS 2 /* max number of memory banks */
+#define CFG_MAX_FLASH_SECT 256 /* max number of sectors on one chip */
+
+#define CFG_FLASH_ERASE_TOUT 120000 /* Timeout for Flash Erase (in ms) */
+#define CFG_FLASH_WRITE_TOUT 500 /* Timeout for Flash Write (in ms) */
+
+#define CFG_FLASH_WORD_SIZE unsigned short /* flash word size (width) */
+#define CFG_FLASH_ADDR0 0x5555 /* 1st address for flash config cycles */
+#define CFG_FLASH_ADDR1 0x2AAA /* 2nd address for flash config cycles */
+/*
+ * The following defines are added for buggy IOP480 byte interface.
+ * All other boards should use the standard values (CPCI405 etc.)
+ */
+#define CFG_FLASH_READ0 0x0000 /* 0 is standard */
+#define CFG_FLASH_READ1 0x0001 /* 1 is standard */
+#define CFG_FLASH_READ2 0x0002 /* 2 is standard */
+
+#define CFG_FLASH_EMPTY_INFO /* print 'E' for empty sector on flinfo */
+
+/*-----------------------------------------------------------------------
+ * I2C EEPROM (CAT24WC08) for environment
+ */
+#define CONFIG_HARD_I2C /* I2c with hardware support */
+#define CFG_I2C_SPEED 400000 /* I2C speed and slave address */
+#define CFG_I2C_SLAVE 0x7F
+
+#define CFG_I2C_EEPROM_ADDR 0x50 /* EEPROM CAT28WC08 */
+#define CFG_I2C_EEPROM_ADDR_LEN 1 /* Bytes of address */
+/* mask of address bits that overflow into the "EEPROM chip address" */
+#define CFG_I2C_EEPROM_ADDR_OVERFLOW 0x07
+#define CFG_EEPROM_PAGE_WRITE_BITS 4 /* The Catalyst CAT24WC08 has */
+ /* 16 byte page write mode using*/
+ /* last 4 bits of the address */
+#define CFG_EEPROM_PAGE_WRITE_DELAY_MS 10 /* and takes up to 10 msec */
+#define CFG_EEPROM_PAGE_WRITE_ENABLE
+
+#define CFG_ENV_IS_IN_EEPROM 1 /* use EEPROM for environment vars */
+#define CFG_ENV_OFFSET 0x000 /* environment starts at the beginning of the EEPROM */
+#define CFG_ENV_SIZE 0x400 /* 1024 bytes may be used for env vars */
+ /* total size of a CAT24WC08 is 1024 bytes */
+
+/*-----------------------------------------------------------------------
+ * Cache Configuration
+ */
+#define CFG_DCACHE_SIZE 8192 /* For IBM 405 CPUs */
+#define CFG_CACHELINE_SIZE 32 /* ... */
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+#define CFG_CACHELINE_SHIFT 5 /* log base 2 of the above value */
+#endif
+
+/*
+ * Init Memory Controller:
+ *
+ * BR0/1 and OR0/1 (FLASH)
+ */
+
+#define FLASH_BASE0_PRELIM 0xFF800000 /* FLASH bank #0 */
+#define FLASH_BASE1_PRELIM 0xFFC00000 /* FLASH bank #1 */
+
+/*-----------------------------------------------------------------------
+ * External Bus Controller (EBC) Setup
+ */
+
+#define FLASH0_BA 0xFFC00000 /* FLASH 0 Base Address */
+#define FLASH1_BA 0xFF800000 /* FLASH 1 Base Address */
+#define CAN_BA 0xF0000000 /* CAN Base Address */
+#define DUART_BA 0xF0300000 /* DUART Base Address */
+#define CF_BA 0xF0100000 /* CompactFlash Base Address */
+#define SRAM_BA 0xF0200000 /* SRAM Base Address */
+#define DURAG_IO_BA 0xF0400000 /* DURAG Bus IO Base Address */
+#define DURAG_MEM_BA 0xF0500000 /* DURAG Bus Mem Base Address */
+
+#define FPGA_MODE_REG (DUART_BA+0x80) /* FPGA Mode Register */
+
+/* Memory Bank 0 (Flash Bank 0) initialization */
+#define CFG_EBC_PB0AP 0x92015480
+#define CFG_EBC_PB0CR FLASH0_BA | 0x5A000 /* BAS=0xFFC,BS=4MB,BU=R/W,BW=16bit */
+
+/* Memory Bank 1 (Flash Bank 1) initialization */
+#define CFG_EBC_PB1AP 0x92015480
+#define CFG_EBC_PB1CR FLASH1_BA | 0x5A000 /* BAS=0xFF8,BS=4MB,BU=R/W,BW=16bit */
+
+/* Memory Bank 2 (CAN0) initialization */
+#define CFG_EBC_PB2AP 0x010053C0 /* BWT=2,WBN=1,WBF=1,TH=1,RE=1,SOR=1,BEM=1 */
+#define CFG_EBC_PB2CR CAN_BA | 0x18000 /* BAS=0xF00,BS=1MB,BU=R/W,BW=8bit */
+
+/* Memory Bank 3 (DUART) initialization */
+#define CFG_EBC_PB3AP 0x010053C0 /* BWT=2,WBN=1,WBF=1,TH=1,RE=1,SOR=1,BEM=1 */
+#define CFG_EBC_PB3CR DUART_BA | 0x18000 /* BAS=0xF03,BS=1MB,BU=R/W,BW=8bit */
+
+/* Memory Bank 4 (CompactFlash IDE) initialization */
+#define CFG_EBC_PB4AP 0x010053C0 /* BWT=2,WBN=1,WBF=1,TH=1,RE=1,SOR=1,BEM=1 */
+#define CFG_EBC_PB4CR CF_BA | 0x1A000 /* BAS=0xF01,BS=1MB,BU=R/W,BW=16bit */
+
+/* Memory Bank 5 (SRAM) initialization */
+#define CFG_EBC_PB5AP 0x010053C0 /* BWT=2,WBN=1,WBF=1,TH=1,RE=1,SOR=1,BEM=1 */
+#define CFG_EBC_PB5CR SRAM_BA | 0x1A000 /* BAS=0xF02,BS=1MB,BU=R/W,BW=16bit */
+
+/* Memory Bank 6 (DURAG Bus IO Space) initialization */
+#define CFG_EBC_PB6AP 0x010053C0 /* BWT=2,WBN=1,WBF=1,TH=1,RE=1,SOR=1,BEM=1 */
+#define CFG_EBC_PB6CR DURAG_IO_BA | 0x18000 /* BAS=0xF04,BS=1MB,BU=R/W,BW=8bit*/
+
+/* Memory Bank 7 (DURAG Bus Mem Space) initialization */
+#define CFG_EBC_PB7AP 0x010053C0 /* BWT=2,WBN=1,WBF=1,TH=1,RE=1,SOR=1,BEM=1 */
+#define CFG_EBC_PB7CR DURAG_MEM_BA | 0x18000 /* BAS=0xF05,BS=1MB,BU=R/W,BW=8bit */
+
+
+/*-----------------------------------------------------------------------
+ * Definitions for initial stack pointer and data area (in DPRAM)
+ */
+
+/* use on chip memory ( OCM ) for temperary stack until sdram is tested */
+#define CFG_TEMP_STACK_OCM 1
+
+/* On Chip Memory location */
+#define CFG_OCM_DATA_ADDR 0xF8000000
+#define CFG_OCM_DATA_SIZE 0x1000
+
+#define CFG_INIT_RAM_ADDR CFG_OCM_DATA_ADDR /* inside of SDRAM */
+#define CFG_INIT_RAM_END CFG_OCM_DATA_SIZE /* End of used area in RAM */
+#define CFG_GBL_DATA_SIZE 128 /* size in bytes reserved for initial data */
+#define CFG_GBL_DATA_OFFSET (CFG_INIT_RAM_END - CFG_GBL_DATA_SIZE)
+#define CFG_INIT_SP_OFFSET CFG_GBL_DATA_OFFSET
+
+
+/*
+ * Internal Definitions
+ *
+ * Boot Flags
+ */
+#define BOOTFLAG_COLD 0x01 /* Normal Power-On: Boot from FLASH */
+#define BOOTFLAG_WARM 0x02 /* Software reboot */
+
+#endif /* __CONFIG_H */
--- /dev/null
+/*
+ * (C) Copyright 2001
+ * Josh Huber <huber@mclx.com>, Mission Critical Linux, 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
+ */
+
+/*
+ * board/config.h - configuration options, board specific
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+#include <asm/processor.h>
+
+#ifndef __ASSEMBLY__
+#include <galileo/core.h>
+#endif
+
+#include "../board/evb64260/local.h"
+
+/*
+ * High Level Configuration Options
+ * (easy to change)
+ */
+
+#define CONFIG_EVB64260 1 /* this is an EVB64260 board */
+#define CFG_GT_6426x GT_64260 /* with a 64260 system controller */
+
+#define CONFIG_BAUDRATE 38400 /* console baudrate = 38400 */
+
+#undef CONFIG_ECC /* enable ECC support */
+/* #define CONFIG_EVB64260_750CX 1 */ /* Support the EVB-64260-750CX Board */
+
+/* which initialization functions to call for this board */
+#define CONFIG_MISC_INIT_R 1
+#define CONFIG_BOARD_PRE_INIT 1
+
+#ifndef CONFIG_EVB64260_750CX
+#define CFG_BOARD_NAME "EVB64260"
+#else
+#define CFG_BOARD_NAME "EVB64260-750CX"
+#endif
+
+#define CFG_HUSH_PARSER
+#define CFG_PROMPT_HUSH_PS2 "> "
+
+/*
+ * The following defines let you select what serial you want to use
+ * for your console driver.
+ *
+ * what to do:
+ * to use the DUART, undef CONFIG_MPSC. If you have hacked a serial
+ * cable onto the second DUART channel, change the CFG_DUART port from 1
+ * to 0 below.
+ *
+ * to use the MPSC, #define CONFIG_MPSC. If you have wired up another
+ * mpsc channel, change CONFIG_MPSC_PORT to the desired value.
+ */
+#define CONFIG_MPSC
+#define CONFIG_MPSC_PORT 0
+
+#define CONFIG_NET_MULTI /* attempt all available adapters */
+
+/* define this if you want to enable GT MAC filtering */
+#define CONFIG_GT_USE_MAC_HASH_TABLE
+
+#undef CONFIG_ETHER_PORT_MII /* use RMII */
+
+#if 1
+#define CONFIG_BOOTDELAY -1 /* autoboot disabled */
+#else
+#define CONFIG_BOOTDELAY 5 /* autoboot after 5 seconds */
+#endif
+#define CONFIG_ZERO_BOOTDELAY_CHECK
+
+#undef CONFIG_BOOTARGS
+#define CONFIG_BOOTCOMMAND \
+ "bootp && " \
+ "setenv bootargs root=/dev/nfs rw nfsroot=$serverip:$rootpath " \
+ "ip=$ipaddr:$serverip:$gatewayip:" \
+ "$netmask:$hostname:eth0:none; && " \
+ "bootm"
+
+#define CONFIG_LOADS_ECHO 0 /* echo off for serial download */
+#define CFG_LOADS_BAUD_CHANGE /* allow baudrate changes */
+
+#undef CONFIG_WATCHDOG /* watchdog disabled */
+#undef CONFIG_ALTIVEC /* undef to disable */
+
+#define CONFIG_BOOTP_MASK (CONFIG_BOOTP_DEFAULT | \
+ CONFIG_BOOTP_BOOTFILESIZE)
+
+
+#define CONFIG_COMMANDS (CONFIG_CMD_DFL | CFG_CMD_ASKENV)
+
+/* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */
+#include <cmd_confdefs.h>
+
+/*
+ * Miscellaneous configurable options
+ */
+#define CFG_LONGHELP /* undef to save memory */
+#define CFG_PROMPT "=> " /* Monitor Command Prompt */
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+#define CFG_CBSIZE 1024 /* Console I/O Buffer Size */
+#else
+#define CFG_CBSIZE 256 /* Console I/O Buffer Size */
+#endif
+#define CFG_PBSIZE (CFG_CBSIZE+sizeof(CFG_PROMPT)+16) /* Print Buffer Size */
+#define CFG_MAXARGS 16 /* max number of command args */
+#define CFG_BARGSIZE CFG_CBSIZE /* Boot Argument Buffer Size */
+
+#define CFG_MEMTEST_START 0x00400000 /* memtest works on */
+#define CFG_MEMTEST_END 0x00C00000 /* 4 ... 12 MB in DRAM */
+
+#define CFG_LOAD_ADDR 0x00300000 /* default load address */
+
+#define CFG_HZ 1000 /* decr freq: 1ms ticks */
+#define CFG_BUS_HZ 100000000 /* 100 MHz */
+#define CFG_BUS_CLK CFG_BUS_HZ
+
+#define CFG_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200, 230400 }
+
+#ifdef CONFIG_EVB64260_750CX
+#define CONFIG_750CX
+#define CFG_BROKEN_CL2
+#endif
+
+/*
+ * Low Level Configuration Settings
+ * (address mappings, register initial values, etc.)
+ * You should know what you are doing if you make changes here.
+ */
+
+/*-----------------------------------------------------------------------
+ * Definitions for initial stack pointer and data area
+ */
+#define CFG_INIT_RAM_ADDR 0x40000000
+#define CFG_INIT_RAM_END 0x1000
+#define CFG_GBL_DATA_SIZE 128 /* size in bytes reserved for init data */
+#define CFG_GBL_DATA_OFFSET (CFG_INIT_RAM_END - CFG_GBL_DATA_SIZE)
+#define CFG_INIT_RAM_LOCK
+
+
+/*-----------------------------------------------------------------------
+ * Start addresses for the final memory configuration
+ * (Set up by the startup code)
+ * Please note that CFG_SDRAM_BASE _must_ start at 0
+ */
+#define CFG_SDRAM_BASE 0x00000000
+#define CFG_FLASH_BASE 0xfff00000
+#define CFG_RESET_ADDRESS 0xfff00100
+#define CFG_MONITOR_LEN (256 << 10) /* Reserve 256 kB for Monitor */
+#define CFG_MONITOR_BASE CFG_FLASH_BASE
+#define CFG_MALLOC_LEN (256 << 10) /* Reserve 256 kB for malloc */
+
+/* areas to map different things with the GT in physical space */
+#define CFG_DRAM_BANKS 4
+#define CFG_DFL_GT_REGS 0x14000000 /* boot time GT_REGS */
+
+/* What to put in the bats. */
+#define CFG_MISC_REGION_BASE 0xf0000000
+
+/* Peripheral Device section */
+#define CFG_GT_REGS 0xf8000000
+#define CFG_DEV_BASE 0xfc000000
+
+#define CFG_DEV0_SPACE CFG_DEV_BASE
+#define CFG_DEV1_SPACE (CFG_DEV0_SPACE + CFG_DEV0_SIZE)
+#define CFG_DEV2_SPACE (CFG_DEV1_SPACE + CFG_DEV1_SIZE)
+#define CFG_DEV3_SPACE (CFG_DEV2_SPACE + CFG_DEV2_SIZE)
+
+#define CFG_DEV0_SIZE _8M /* evb64260 sram @ 0xfc00.0000 */
+#define CFG_DEV1_SIZE _8M /* evb64260 rtc @ 0xfc80.0000 */
+#define CFG_DEV2_SIZE _16M /* evb64260 duart @ 0xfd00.0000 */
+#define CFG_DEV3_SIZE _16M /* evb64260 flash @ 0xfe00.0000 */
+
+#define CFG_DEV0_PAR 0x20205093
+#define CFG_DEV1_PAR 0xcfcfffff
+#define CFG_DEV2_PAR 0xc0059bd4
+#define CFG_8BIT_BOOT_PAR 0xc00b5e7c
+#define CFG_32BIT_BOOT_PAR 0xc4a8241c
+ /* c 4 a 8 2 4 1 c */
+ /* 33 22|2222|22 22|111 1|11 11|1 1 | | */
+ /* 10 98|7654|32 10|987 6|54 32|1 098|7 654|3 210 */
+ /* 11|00|0100|10 10|100|0 00|10 0|100 0|001 1|100 */
+ /* 3| 0|.... ..| 2| 4 | 0 | 4 | 8 | 3 | 4 */
+
+#if 0 /* Wrong?? NTL */
+#define CFG_MPP_CONTROL_0 0x53541717 /* InitAct EOT[4] DBurst TCEn[1] */
+ /* DMAAck[1:0] GNT0[1:0] */
+#else
+#define CFG_MPP_CONTROL_0 0x53547777 /* InitAct EOT[4] DBurst TCEn[1] */
+ /* REQ0[1:0] GNT0[1:0] */
+#endif
+#define CFG_MPP_CONTROL_1 0x44009911 /* TCEn[4] TCTcnt[4] GPP[13:12] */
+ /* DMAReq[4] DMAAck[4] WDNMI WDE */
+#if 0 /* Wrong?? NTL */
+#define CFG_MPP_CONTROL_2 0x40091818 /* TCTcnt[0] GPP[22:21] BClkIn */
+ /* DMAAck[1:0] GNT1[1:0] */
+#else
+#define CFG_MPP_CONTROL_2 0x40098888 /* TCTcnt[0] */
+ /* GPP[22] (RS232IntB or PCI1Int) */
+ /* GPP[21] (RS323IntA) */
+ /* BClkIn */
+ /* REQ1[1:0] GNT1[1:0] */
+#endif
+
+#if 0 /* Wrong?? NTL */
+# define CFG_MPP_CONTROL_3 0x00090066 /* GPP[31:29] BClkOut0 */
+ /* GPP[27:26] Int[1:0] */
+#else
+# define CFG_MPP_CONTROL_3 0x22090066 /* MREQ MGNT */
+ /* GPP[29] (PCI1Int) */
+ /* BClkOut0 */
+ /* GPP[27] (PCI0Int) */
+ /* GPP[26] (RtcInt or PCI1Int) */
+ /* CPUInt[25:24] */
+#endif
+
+# define CFG_SERIAL_PORT_MUX 0x00000102 /* 0=hiZ 1=MPSC0 2=ETH 0 and 2 RMII */
+
+#if 0 /* Wrong?? - NTL */
+# define CFG_GPP_LEVEL_CONTROL 0x000002c6
+#else
+# define CFG_GPP_LEVEL_CONTROL 0x2c600000 /* 0010 1100 0110 0000 */
+ /* gpp[29] */
+ /* gpp[27:26] */
+ /* gpp[22:21] */
+
+# define CFG_SDRAM_CONFIG 0xd8e18200 /* 0x448 */
+ /* idmas use buffer 1,1
+ comm use buffer 0
+ pci use buffer 1,1
+ cpu use buffer 0
+ normal load (see also ifdef HVL)
+ standard SDRAM (see also ifdef REG)
+ non staggered refresh */
+ /* 31:26 25 23 20 19 18 16 */
+ /* 110110 00 111 0 0 00 1 */
+ /* refresh_count=0x200
+ phisical interleaving disable
+ virtual interleaving enable */
+ /* 15 14 13:0 */
+ /* 1 0 0x200 */
+#endif
+
+#define CFG_DUART_IO CFG_DEV2_SPACE
+#define CFG_DUART_CHAN 1 /* channel to use for console */
+#define CFG_INIT_CHAN1
+#define CFG_INIT_CHAN2
+
+#define SRAM_BASE CFG_DEV0_SPACE
+#define SRAM_SIZE 0x00100000 /* 1 MB of sram */
+
+
+/*-----------------------------------------------------------------------
+ * PCI stuff
+ *-----------------------------------------------------------------------
+ */
+
+#define PCI_HOST_ADAPTER 0 /* configure ar pci adapter */
+#define PCI_HOST_FORCE 1 /* configure as pci host */
+#define PCI_HOST_AUTO 2 /* detected via arbiter enable */
+
+#define CONFIG_PCI /* include pci support */
+#define CONFIG_PCI_HOST PCI_HOST_FORCE /* select pci host function */
+#define CONFIG_PCI_PNP /* do pci plug-and-play */
+
+/* PCI MEMORY MAP section */
+#define CFG_PCI0_MEM_BASE 0x80000000
+#define CFG_PCI0_MEM_SIZE _128M
+#define CFG_PCI1_MEM_BASE 0x88000000
+#define CFG_PCI1_MEM_SIZE _128M
+
+#define CFG_PCI0_0_MEM_SPACE (CFG_PCI0_MEM_BASE)
+#define CFG_PCI1_0_MEM_SPACE (CFG_PCI1_MEM_BASE)
+
+
+
+/* PCI I/O MAP section */
+#define CFG_PCI0_IO_BASE 0xfa000000
+#define CFG_PCI0_IO_SIZE _16M
+#define CFG_PCI1_IO_BASE 0xfb000000
+#define CFG_PCI1_IO_SIZE _16M
+
+#define CFG_PCI0_IO_SPACE (CFG_PCI0_IO_BASE)
+#define CFG_PCI0_IO_SPACE_PCI 0x00000000
+#define CFG_PCI1_IO_SPACE (CFG_PCI1_IO_BASE)
+#define CFG_PCI1_IO_SPACE_PCI 0x00000000
+
+/*
+ * NS16550 Configuration
+ */
+#define CFG_NS16550
+
+#define CFG_NS16550_REG_SIZE -4
+
+#define CFG_NS16550_CLK 3686400
+
+#define CFG_NS16550_COM1 (CFG_DUART_IO + 0)
+#define CFG_NS16550_COM2 (CFG_DUART_IO + 0x20)
+
+/*----------------------------------------------------------------------
+ * Initial BAT mappings
+ */
+
+/* NOTES:
+ * 1) GUARDED and WRITE_THRU not allowed in IBATS
+ * 2) CACHEINHIBIT and WRITETHROUGH not allowed together in same BAT
+ */
+
+/* SDRAM */
+#define CFG_IBAT0L (CFG_SDRAM_BASE | BATL_PP_RW | BATL_CACHEINHIBIT)
+#define CFG_IBAT0U (CFG_SDRAM_BASE | BATU_BL_256M | BATU_VS | BATU_VP)
+#define CFG_DBAT0L (CFG_SDRAM_BASE | BATL_PP_RW | BATL_CACHEINHIBIT | BATL_GUARDEDSTORAGE)
+#define CFG_DBAT0U CFG_IBAT0U
+
+/* init ram */
+#define CFG_IBAT1L (CFG_INIT_RAM_ADDR | BATL_PP_RW | BATL_MEMCOHERENCE)
+#define CFG_IBAT1U (CFG_INIT_RAM_ADDR | BATU_BL_128K | BATU_VS | BATU_VP)
+#define CFG_DBAT1L CFG_IBAT1L
+#define CFG_DBAT1U CFG_IBAT1U
+
+/* PCI0, PCI1 in one BAT */
+#define CFG_IBAT2L BATL_NO_ACCESS
+#define CFG_IBAT2U CFG_DBAT2U
+#define CFG_DBAT2L (CFG_PCI0_MEM_BASE | BATL_CACHEINHIBIT | BATL_PP_RW | BATL_GUARDEDSTORAGE)
+#define CFG_DBAT2U (CFG_PCI0_MEM_BASE | BATU_BL_256M | BATU_VS | BATU_VP)
+
+/* GT regs, bootrom, all the devices, PCI I/O */
+#define CFG_IBAT3L (CFG_MISC_REGION_BASE | BATL_CACHEINHIBIT | BATL_PP_RW)
+#define CFG_IBAT3U (CFG_MISC_REGION_BASE | BATU_VS | BATU_VP | BATU_BL_256M)
+#define CFG_DBAT3L (CFG_MISC_REGION_BASE | BATL_CACHEINHIBIT | BATL_PP_RW | BATL_GUARDEDSTORAGE)
+#define CFG_DBAT3U CFG_IBAT3U
+
+/* I2C speed and slave address (for compatability) defaults */
+#define CFG_I2C_SPEED 400000
+#define CFG_I2C_SLAVE 0x7F
+
+/* I2C addresses for the two DIMM SPD chips */
+#ifndef CONFIG_EVB64260_750CX
+#define DIMM0_I2C_ADDR 0x56
+#define DIMM1_I2C_ADDR 0x54
+#else /* CONFIG_EVB64260_750CX - only has 1 DIMM */
+#define DIMM0_I2C_ADDR 0x54
+#define DIMM1_I2C_ADDR 0x54
+#endif
+
+/*
+ * For booting Linux, the board info and command line data
+ * have to be in the first 8 MB of memory, since this is
+ * the maximum mapped by the Linux kernel during initialization.
+ */
+#define CFG_BOOTMAPSZ (8<<20) /* Initial Memory map for Linux */
+
+/*-----------------------------------------------------------------------
+ * FLASH organization
+ */
+#define CFG_MAX_FLASH_BANKS 2 /* max number of memory banks */
+#define CFG_MAX_FLASH_SECT 67 /* max number of sectors on one chip */
+
+#define CFG_EXTRA_FLASH_DEVICE DEVICE3 /* extra flash at device 3 */
+#define CFG_EXTRA_FLASH_WIDTH 4 /* 32 bit */
+
+#define CFG_FLASH_ERASE_TOUT 120000 /* Timeout for Flash Erase (in ms) */
+#define CFG_FLASH_WRITE_TOUT 500 /* Timeout for Flash Write (in ms) */
+#define CFG_FLASH_CFI 1
+
+#define CFG_ENV_IS_IN_FLASH 1
+#define CFG_ENV_SIZE 0x1000 /* Total Size of Environment Sector */
+#define CFG_ENV_SECT_SIZE 0x10000
+#define CFG_ENV_ADDR (CFG_FLASH_BASE+CFG_MONITOR_LEN-CFG_ENV_SECT_SIZE)
+
+/*-----------------------------------------------------------------------
+ * Cache Configuration
+ */
+#define CFG_CACHELINE_SIZE 32 /* For all MPC74xx CPUs */
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+#define CFG_CACHELINE_SHIFT 5 /* log base 2 of the above value */
+#endif
+
+/*-----------------------------------------------------------------------
+ * L2CR setup -- make sure this is right for your board!
+ * look in include/mpc74xx.h for the defines used here
+ */
+
+#define CFG_L2
+
+#ifdef CONFIG_750CX
+#define L2_INIT 0
+#else
+#define L2_INIT (L2CR_L2SIZ_2M | L2CR_L2CLK_3 | L2CR_L2RAM_BURST | \
+ L2CR_L2OH_5 | L2CR_L2CTL | L2CR_L2WT)
+#endif
+
+#define L2_ENABLE (L2_INIT | L2CR_L2E)
+
+/*
+ * Internal Definitions
+ *
+ * Boot Flags
+ */
+#define BOOTFLAG_COLD 0x01 /* Normal Power-On: Boot from FLASH */
+#define BOOTFLAG_WARM 0x02 /* Software reboot */
+
+#define CFG_BOARD_ASM_INIT 1
+
+
+#endif /* __CONFIG_H */
--- /dev/null
+/*
+ * (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
+ */
+
+/*
+ *
+ * Configuration settings for the MUSENKI board.
+ *
+ */
+
+/* ------------------------------------------------------------------------- */
+
+/*
+ * board/config.h - configuration options, board specific
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+/*
+ * High Level Configuration Options
+ * (easy to change)
+ */
+
+#define CONFIG_MPC824X 1
+#define CONFIG_MPC8245 1
+#define CONFIG_MUSENKI 1
+
+
+#define CONFIG_CONS_INDEX 1
+#define CONFIG_BAUDRATE 9600
+#define CFG_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 }
+
+#define CONFIG_BOOTDELAY 5
+
+#define CONFIG_COMMANDS (CONFIG_CMD_DFL)
+
+/* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */
+
+#include <cmd_confdefs.h>
+
+
+/*
+ * Miscellaneous configurable options
+ */
+#undef CFG_LONGHELP /* undef to save memory */
+#define CFG_PROMPT "=> " /* Monitor Command Prompt */
+#define CFG_CBSIZE 256 /* Console I/O Buffer Size */
+
+/* Print Buffer Size
+ */
+#define CFG_PBSIZE (CFG_CBSIZE + sizeof(CFG_PROMPT) + 16)
+#define CFG_MAXARGS 8 /* Max number of command args */
+#define CFG_BARGSIZE CFG_CBSIZE /* Boot Argument Buffer Size */
+#define CFG_LOAD_ADDR 0x00100000 /* Default load address */
+
+/*-----------------------------------------------------------------------
+ * PCI stuff
+ *-----------------------------------------------------------------------
+ */
+#define CONFIG_PCI /* include pci support */
+#undef CONFIG_PCI_PNP
+
+#define CONFIG_NET_MULTI /* Multi ethernet cards support */
+
+#define CONFIG_TULIP
+
+#define PCI_ENET0_IOADDR 0x80000000
+#define PCI_ENET0_MEMADDR 0x80000000
+#define PCI_ENET1_IOADDR 0x81000000
+#define PCI_ENET1_MEMADDR 0x81000000
+
+
+/*-----------------------------------------------------------------------
+ * Start addresses for the final memory configuration
+ * (Set up by the startup code)
+ * Please note that CFG_SDRAM_BASE _must_ start at 0
+ */
+#define CFG_SDRAM_BASE 0x00000000
+
+#define CFG_FLASH_BASE0_PRELIM 0xFF800000 /* FLASH bank on RCS#0 */
+#define CFG_FLASH_BASE1_PRELIM 0xFF000000 /* FLASH bank on RCS#1 */
+#define CFG_FLASH_BASE CFG_FLASH_BASE0_PRELIM
+
+/* even though FLASHP_BASE is FF800000, with 4MB is RCS0, the
+ * reset vector is actually located at FFB00100, but the 8245
+ * takes care of us.
+ */
+#define CFG_RESET_ADDRESS 0xFFF00100
+
+#define CFG_EUMB_ADDR 0xFC000000
+
+#define CFG_MONITOR_BASE TEXT_BASE
+#define CFG_MONITOR_LEN (256 << 10) /* Reserve 256 kB for Monitor */
+#define CFG_MALLOC_LEN (128 << 10) /* Reserve 128 kB for malloc() */
+
+#define CFG_MEMTEST_START 0x00004000 /* memtest works on */
+#define CFG_MEMTEST_END 0x02000000 /* 0 ... 32 MB in DRAM */
+
+ /* Maximum amount of RAM.
+ */
+#define CFG_MAX_RAM_SIZE 0x08000000 /* 0 .. 128 MB of (S)DRAM */
+
+
+#if CFG_MONITOR_BASE >= CFG_FLASH_BASE
+#undef CFG_RAMBOOT
+#else
+#define CFG_RAMBOOT
+#endif
+
+/*
+ * NS16550 Configuration
+ */
+#define CFG_NS16550
+#define CFG_NS16550_SERIAL
+
+#define CFG_NS16550_REG_SIZE 1
+
+#define CFG_NS16550_CLK get_bus_freq(0)
+
+#define CFG_NS16550_COM1 (CFG_EUMB_ADDR + 0x4500)
+#define CFG_NS16550_COM2 (CFG_EUMB_ADDR + 0x4600)
+
+/*-----------------------------------------------------------------------
+ * Definitions for initial stack pointer and data area
+ */
+
+/* #define CFG_MONITOR_BASE TEXT_BASE */
+/*#define CFG_GBL_DATA_SIZE 256*/
+#define CFG_GBL_DATA_SIZE 128
+#define CFG_INIT_RAM_ADDR 0x40000000
+#define CFG_INIT_RAM_END 0x1000
+#define CFG_GBL_DATA_OFFSET (CFG_INIT_RAM_END - CFG_GBL_DATA_SIZE)
+
+
+/*
+ * Low Level Configuration Settings
+ * (address mappings, register initial values, etc.)
+ * You should know what you are doing if you make changes here.
+ * For the detail description refer to the MPC8240 user's manual.
+ */
+
+#define CONFIG_SYS_CLK_FREQ 33333333 /* external frequency to pll */
+#define CFG_HZ 1000
+
+ /* Bit-field values for MCCR1.
+ */
+#define CFG_ROMNAL 7
+#define CFG_ROMFAL 11
+#define CFG_DBUS_SIZE 0x3
+
+ /* Bit-field values for MCCR2.
+ */
+#define CFG_TSWAIT 0x5 /* Transaction Start Wait States timer */
+#define CFG_REFINT 0x400 /* Refresh interval FIXME: was 0t430 */
+
+ /* Burst To Precharge. Bits of this value go to MCCR3 and MCCR4.
+ */
+#define CFG_BSTOPRE 121
+
+ /* Bit-field values for MCCR3.
+ */
+#define CFG_REFREC 8 /* Refresh to activate interval */
+
+ /* Bit-field values for MCCR4.
+ */
+#define CFG_PRETOACT 3 /* Precharge to activate interval FIXME: was 2 */
+#define CFG_ACTTOPRE 5 /* Activate to Precharge interval FIXME: was 5 */
+#define CFG_ACTORW 3 /* FIXME was 2 */
+#define CFG_SDMODE_CAS_LAT 3 /* SDMODE CAS latancy */
+#define CFG_SDMODE_WRAP 0 /* SDMODE wrap type */
+#define CFG_REGISTERD_TYPE_BUFFER 1
+#define CFG_EXTROM 1
+#define CFG_REGDIMM 0
+
+#define CFG_PGMAX 0x32 /* how long the 8240 reatins the currently accessed page in memory FIXME: was 0x32*/
+
+#define CFG_SDRAM_DSCD 0x20 /* SDRAM data in sample clock delay - note bottom 3 bits MUST be 0 */
+
+/* Memory bank settings.
+ * Only bits 20-29 are actually used from these vales to set the
+ * start/end addresses. The upper two bits will always be 0, and the lower
+ * 20 bits will be 0x00000 for a start address, or 0xfffff for an end
+ * address. Refer to the MPC8240 book.
+ */
+
+#define CFG_BANK0_START 0x00000000
+#define CFG_BANK0_END (CFG_MAX_RAM_SIZE - 1)
+#define CFG_BANK0_ENABLE 1
+#define CFG_BANK1_START 0x3ff00000
+#define CFG_BANK1_END 0x3fffffff
+#define CFG_BANK1_ENABLE 0
+#define CFG_BANK2_START 0x3ff00000
+#define CFG_BANK2_END 0x3fffffff
+#define CFG_BANK2_ENABLE 0
+#define CFG_BANK3_START 0x3ff00000
+#define CFG_BANK3_END 0x3fffffff
+#define CFG_BANK3_ENABLE 0
+#define CFG_BANK4_START 0x3ff00000
+#define CFG_BANK4_END 0x3fffffff
+#define CFG_BANK4_ENABLE 0
+#define CFG_BANK5_START 0x3ff00000
+#define CFG_BANK5_END 0x3fffffff
+#define CFG_BANK5_ENABLE 0
+#define CFG_BANK6_START 0x3ff00000
+#define CFG_BANK6_END 0x3fffffff
+#define CFG_BANK6_ENABLE 0
+#define CFG_BANK7_START 0x3ff00000
+#define CFG_BANK7_END 0x3fffffff
+#define CFG_BANK7_ENABLE 0
+
+#define CFG_ODCR 0xff
+
+#define CFG_IBAT0L (CFG_SDRAM_BASE | BATL_PP_10 | BATL_MEMCOHERENCE)
+#define CFG_IBAT0U (CFG_SDRAM_BASE | BATU_BL_256M | BATU_VS | BATU_VP)
+
+#define CFG_IBAT1L (CFG_INIT_RAM_ADDR | BATL_PP_10 | BATL_MEMCOHERENCE)
+#define CFG_IBAT1U (CFG_INIT_RAM_ADDR | BATU_BL_128K | BATU_VS | BATU_VP)
+
+#define CFG_IBAT2L (0x80000000 | BATL_PP_10 | BATL_CACHEINHIBIT)
+#define CFG_IBAT2U (0x80000000 | BATU_BL_256M | BATU_VS | BATU_VP)
+
+#define CFG_IBAT3L (0xF0000000 | BATL_PP_10 | BATL_CACHEINHIBIT)
+#define CFG_IBAT3U (0xF0000000 | BATU_BL_256M | BATU_VS | BATU_VP)
+
+#define CFG_DBAT0L CFG_IBAT0L
+#define CFG_DBAT0U CFG_IBAT0U
+#define CFG_DBAT1L CFG_IBAT1L
+#define CFG_DBAT1U CFG_IBAT1U
+#define CFG_DBAT2L CFG_IBAT2L
+#define CFG_DBAT2U CFG_IBAT2U
+#define CFG_DBAT3L CFG_IBAT3L
+#define CFG_DBAT3U CFG_IBAT3U
+
+/*
+ * For booting Linux, the board info and command line data
+ * have to be in the first 8 MB of memory, since this is
+ * the maximum mapped by the Linux kernel during initialization.
+ */
+#define CFG_BOOTMAPSZ (8 << 20) /* Initial Memory map for Linux */
+
+/*-----------------------------------------------------------------------
+ * FLASH organization
+ */
+#define CFG_MAX_FLASH_BANKS 2 /* Max number of flash banks */
+#define CFG_MAX_FLASH_SECT 64 /* Max number of sectors per flash */
+
+#define CFG_FLASH_ERASE_TOUT 120000 /* Timeout for Flash Erase (in ms) */
+#define CFG_FLASH_WRITE_TOUT 500 /* Timeout for Flash Write (in ms) */
+
+
+ /* Warining: environment is not EMBEDDED in the U-Boot code.
+ * It's stored in flash separately.
+ */
+#define CFG_ENV_IS_IN_FLASH 1
+#define CFG_ENV_ADDR 0xFFFF0000
+#define CFG_ENV_SIZE 0x00010000 /* Size of the Environment */
+#define CFG_ENV_SECT_SIZE 0x20000 /* Size of the Environment Sector */
+
+/*-----------------------------------------------------------------------
+ * Cache Configuration
+ */
+#define CFG_CACHELINE_SIZE 32
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+# define CFG_CACHELINE_SHIFT 5 /* log base 2 of the above value */
+#endif
+
+/*
+ * Internal Definitions
+ *
+ * Boot Flags
+ */
+#define BOOTFLAG_COLD 0x01 /* Normal Power-On: Boot from FLASH */
+#define BOOTFLAG_WARM 0x02 /* Software reboot */
+
+
+
+#endif /* __CONFIG_H */
--- /dev/null
+/*
+ * (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
+ */
+
+/*
+ * board/config.h - configuration options, board specific
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+/*
+ * High Level Configuration Options
+ * (easy to change)
+ */
+
+#define CONFIG_MPC823 1 /* This is a MPC823 CPU */
+#define CONFIG_MVS 1 /* ...on a MVsensor module */
+#define CONFIG_MVS_16BIT_FLASH /* ...with 16-bit flash access */
+#define CONFIG_8xx_GCLK_FREQ 50000000/* ... and a 50 MHz CPU */
+
+#define CONFIG_CLOCKS_IN_MHZ 1 /* clocks passsed to Linux in MHz */
+
+#undef CONFIG_8xx_CONS_SMC1 /* Console is *NOT* on SMC1 */
+#define CONFIG_8xx_CONS_SMC2 1 /* Console is on SMC2 */
+#undef CONFIG_8xx_CONS_NONE
+#define CONFIG_BAUDRATE 115200 /* console baudrate */
+#define CONFIG_BOOTDELAY 5 /* autoboot after this many seconds */
+
+#define CONFIG_PREBOOT "echo;echo To mount root over NFS use \"run bootnet\";echo To mount root from FLASH use \"run bootflash\";echo"
+#define CONFIG_BOOTARGS "root=/dev/mtdblock2 rw"
+#define CONFIG_BOOTCOMMAND \
+ "bootp; " \
+ "setenv bootargs root=/dev/nfs rw nfsroot=$(serverip):$(rootpath) " \
+ "ip=$(ipaddr):$(serverip):$(gatewayip):$(netmask):$(hostname)::off; " \
+ "bootm"
+
+#define CONFIG_LOADS_ECHO 1 /* echo on for serial download */
+#undef CFG_LOADS_BAUD_CHANGE /* don't allow baudrate change */
+
+#define CONFIG_WATCHDOG /* watchdog disabled/enabled */
+
+#undef CONFIG_STATUS_LED /* Status LED disabled/enabled */
+
+#undef CONFIG_CAN_DRIVER /* CAN Driver support disabled */
+
+#define CONFIG_BOOTP_MASK (CONFIG_BOOTP_DEFAULT | CONFIG_BOOTP_VENDOREX )
+
+#undef CONFIG_MAC_PARTITION
+#undef CONFIG_DOS_PARTITION
+
+#define CONFIG_RTC_MPC8xx /* use internal RTC of MPC8xx */
+
+/* MVsensor uses a really minimal U-Boot ! */
+#define CONFIG_COMMANDS (CFG_CMD_LOADS | \
+ CFG_CMD_LOADB | \
+ CFG_CMD_IMI | \
+ CFG_CMD_FLASH | \
+ CFG_CMD_MEMORY | \
+ CFG_CMD_NET | \
+ CFG_CMD_DHCP | \
+ CFG_CMD_ENV | \
+ CFG_CMD_BOOTD | \
+ CFG_CMD_RUN )
+
+/* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */
+#include <cmd_confdefs.h>
+
+/*
+ * Miscellaneous configurable options
+ */
+#undef CFG_LONGHELP /* undef to save memory */
+#define CFG_PROMPT "=> " /* Monitor Command Prompt */
+
+#undef CFG_HUSH_PARSER /* Hush parse for U-Boot ?? */
+#ifdef CFG_HUSH_PARSER
+#define CFG_PROMPT_HUSH_PS2 "> "
+#endif
+
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+#define CFG_CBSIZE 1024 /* Console I/O Buffer Size */
+#else
+#define CFG_CBSIZE 256 /* Console I/O Buffer Size */
+#endif
+#define CFG_PBSIZE (CFG_CBSIZE+sizeof(CFG_PROMPT)+16) /* Print Buffer Size */
+#define CFG_MAXARGS 16 /* max number of command args */
+#define CFG_BARGSIZE CFG_CBSIZE /* Boot Argument Buffer Size */
+
+#define CFG_MEMTEST_START 0x0400000 /* memtest works on */
+#define CFG_MEMTEST_END 0x0C00000 /* 4 ... 12 MB in DRAM */
+
+#define CFG_LOAD_ADDR 0x100000 /* default load address */
+
+#define CFG_HZ 1000 /* decrementer freq: 1 ms ticks */
+
+#define CFG_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 }
+
+/*
+ * Low Level Configuration Settings
+ * (address mappings, register initial values, etc.)
+ * You should know what you are doing if you make changes here.
+ */
+/*-----------------------------------------------------------------------
+ * Internal Memory Mapped Register
+ */
+#define CFG_IMMR 0xFFF00000
+
+/*-----------------------------------------------------------------------
+ * Definitions for initial stack pointer and data area (in DPRAM)
+ */
+#define CFG_INIT_RAM_ADDR CFG_IMMR
+#define CFG_INIT_RAM_END 0x2F00 /* End of used area in DPRAM */
+#define CFG_GBL_DATA_SIZE 64 /* size in bytes reserved for initial data */
+#define CFG_GBL_DATA_OFFSET (CFG_INIT_RAM_END - CFG_GBL_DATA_SIZE)
+#define CFG_INIT_SP_OFFSET CFG_GBL_DATA_OFFSET
+
+/*-----------------------------------------------------------------------
+ * Start addresses for the final memory configuration
+ * (Set up by the startup code)
+ * Please note that CFG_SDRAM_BASE _must_ start at 0
+ */
+#define CFG_SDRAM_BASE 0x00000000
+#define CFG_FLASH_BASE 0x40000000
+
+#define CFG_MONITOR_LEN (128 << 10) /* Reserve 192 kB for Monitor */
+
+#define CFG_MONITOR_BASE CFG_FLASH_BASE
+#define CFG_MALLOC_LEN (128 << 10) /* Reserve 128 kB for malloc() */
+
+/*
+ * For booting Linux, the board info and command line data
+ * have to be in the first 8 MB of memory, since this is
+ * the maximum mapped by the Linux kernel during initialization.
+ */
+#define CFG_BOOTMAPSZ (8 << 20) /* Initial Memory map for Linux */
+
+/*-----------------------------------------------------------------------
+ * FLASH organization
+ */
+#define CFG_MAX_FLASH_BANKS 1 /* max number of memory banks */
+#define CFG_MAX_FLASH_SECT 71 /* max number of sectors on one chip (for AMD320DB chip) */
+
+#define CFG_FLASH_ERASE_TOUT 120000 /* Timeout for Flash Erase (in ms) */
+#define CFG_FLASH_WRITE_TOUT 500 /* Timeout for Flash Write (in ms) */
+
+#define CFG_ENV_IS_IN_FLASH 1
+
+/* 4MB flash - use bottom sectors of a bottom boot sector flash (16 bit access) */
+#define CFG_ENV_OFFSET 0x8000 /* Offset of Environment Sector (bottom boot sector) */
+#define CFG_ENV_SIZE 0x2000 /* Used Size of Environment Sector 8k */
+
+/*-----------------------------------------------------------------------
+ * Cache Configuration
+ */
+#define CFG_CACHELINE_SIZE 16 /* For all MPC8xx CPUs */
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+#define CFG_CACHELINE_SHIFT 4 /* log base 2 of the above value */
+#endif
+
+/*-----------------------------------------------------------------------
+ * SYPCR - System Protection Control 11-9
+ * SYPCR can only be written once after reset!
+ *-----------------------------------------------------------------------
+ * Software & Bus Monitor Timer max, Bus Monitor enable, SW Watchdog freeze
+ */
+#if defined(CONFIG_WATCHDOG)
+#define CFG_SYPCR (SYPCR_SWTC | SYPCR_BMT | SYPCR_BME | SYPCR_SWF | \
+ SYPCR_SWE | SYPCR_SWRI| SYPCR_SWP)
+#else
+#define CFG_SYPCR (SYPCR_SWTC | SYPCR_BMT | SYPCR_BME | SYPCR_SWF | SYPCR_SWP)
+#endif
+
+/*-----------------------------------------------------------------------
+ * SIUMCR - SIU Module Configuration 11-6
+ *-----------------------------------------------------------------------
+ * PCMCIA config., multi-function pin tri-state
+ */
+#define CFG_SIUMCR (SIUMCR_DBGC00 | SIUMCR_DBPC00 | SIUMCR_MLRC01)
+
+/*-----------------------------------------------------------------------
+ * TBSCR - Time Base Status and Control 11-26
+ *-----------------------------------------------------------------------
+ * Clear Reference Interrupt Status, Timebase freezing enabled
+ */
+#define CFG_TBSCR (TBSCR_REFA | TBSCR_REFB | TBSCR_TBF)
+
+/*-----------------------------------------------------------------------
+ * RTCSC - Real-Time Clock Status and Control Register 11-27
+ *-----------------------------------------------------------------------
+ */
+#define CFG_RTCSC (RTCSC_SEC | RTCSC_ALR | RTCSC_RTF| RTCSC_RTE)
+
+/*-----------------------------------------------------------------------
+ * PISCR - Periodic Interrupt Status and Control 11-31
+ *-----------------------------------------------------------------------
+ * Clear Periodic Interrupt Status, Interrupt Timer freezing enabled
+ */
+#define CFG_PISCR (PISCR_PS | PISCR_PITF)
+
+/*-----------------------------------------------------------------------
+ * PLPRCR - PLL, Low-Power, and Reset Control Register 15-30
+ *-----------------------------------------------------------------------
+ * Reset PLL lock status sticky bit, timer expired status bit and timer
+ * interrupt status bit
+ *
+ */
+#define CFG_PLPRCR (PLPRCR_SPLSS | PLPRCR_TEXPS | PLPRCR_TMIST)
+
+/*-----------------------------------------------------------------------
+ * SCCR - System Clock and reset Control Register 15-27
+ *-----------------------------------------------------------------------
+ * Set clock output, timebase and RTC source and divider,
+ * power management and some other internal clocks
+ */
+#define SCCR_MASK SCCR_EBDF11
+#define CFG_SCCR (SCCR_TBS | \
+ SCCR_COM00 | SCCR_DFSYNC00 | SCCR_DFBRG00 | \
+ SCCR_DFNL000 | SCCR_DFNH000 | SCCR_DFLCD000 | \
+ SCCR_DFALCD00)
+
+/*-----------------------------------------------------------------------
+ * PCMCIA stuff
+ *-----------------------------------------------------------------------
+ *
+ */
+#define CFG_PCMCIA_MEM_ADDR (0xE0000000)
+#define CFG_PCMCIA_MEM_SIZE ( 64 << 20 )
+#define CFG_PCMCIA_DMA_ADDR (0xE4000000)
+#define CFG_PCMCIA_DMA_SIZE ( 64 << 20 )
+#define CFG_PCMCIA_ATTRB_ADDR (0xE8000000)
+#define CFG_PCMCIA_ATTRB_SIZE ( 64 << 20 )
+#define CFG_PCMCIA_IO_ADDR (0xEC000000)
+#define CFG_PCMCIA_IO_SIZE ( 64 << 20 )
+
+/*-----------------------------------------------------------------------
+ * IDE/ATA stuff (Supports IDE harddisk on PCMCIA Adapter)
+ *-----------------------------------------------------------------------
+ */
+
+#define CONFIG_IDE_PCCARD 0 /* **DON'T** Use IDE with PC Card Adapter */
+
+#undef CONFIG_IDE_PCMCIA /* Direct IDE not supported */
+#undef CONFIG_IDE_LED /* LED for ide not supported */
+#undef CONFIG_IDE_RESET /* reset for ide not supported */
+
+#define CFG_IDE_MAXBUS 0 /* max. no. of IDE buses */
+#define CFG_IDE_MAXDEVICE 0 /* max. no. of drives per IDE bus */
+
+
+#define CFG_ATA_IDE0_OFFSET 0x0000
+
+#define CFG_ATA_BASE_ADDR CFG_PCMCIA_MEM_ADDR
+
+/* Offset for data I/O */
+#define CFG_ATA_DATA_OFFSET (CFG_PCMCIA_MEM_SIZE + 0x320)
+
+/* Offset for normal register accesses */
+#define CFG_ATA_REG_OFFSET (2 * CFG_PCMCIA_MEM_SIZE + 0x320)
+
+/* Offset for alternate registers */
+#define CFG_ATA_ALT_OFFSET 0x0100
+
+/*-----------------------------------------------------------------------
+ *
+ *-----------------------------------------------------------------------
+ *
+ */
+/*#define CFG_DER 0x2002000F*/
+#define CFG_DER 0
+
+/*
+ * Init Memory Controller:
+ *
+ * BR0/1 and OR0/1 (FLASH)
+ */
+
+#define FLASH_BASE0_PRELIM 0x40000000 /* FLASH bank #0 */
+#undef FLASH_BASE1_PRELIM
+
+/* used to re-map FLASH both when starting from SRAM or FLASH:
+ * restrict access enough to keep SRAM working (if any)
+ * but not too much to meddle with FLASH accesses
+ */
+#define CFG_REMAP_OR_AM 0x80000000 /* OR addr mask */
+#define CFG_PRELIM_OR_AM 0xE0000000 /* OR addr mask */
+
+
+/*
+ * FLASH timing:
+ */
+/* 50 MHz CPU - 50 MHz bus: ACS = 00, TRLX = 1, CSNT = 1, SCY = 2, EHTR = 1 */
+#define CFG_OR_TIMING_FLASH (OR_ACS_DIV1 | OR_TRLX | OR_CSNT_SAM | \
+ OR_SCY_2_CLK | OR_EHTR | OR_BI)
+/* FLASH timing: ACS = 11, TRLX = 0, CSNT = 1, SCY = 5, EHTR = 1 */
+/*
+#define CFG_OR_TIMING_FLASH (OR_CSNT_SAM | OR_ACS_DIV2 | OR_BI | \
+ OR_SCY_5_CLK | OR_EHTR)
+*/
+
+#define CFG_OR0_REMAP (CFG_REMAP_OR_AM | CFG_OR_TIMING_FLASH)
+#define CFG_OR0_PRELIM (CFG_PRELIM_OR_AM | CFG_OR_TIMING_FLASH)
+#ifdef CONFIG_MVS_16BIT_FLASH
+#define CFG_BR0_PRELIM ((FLASH_BASE0_PRELIM & BR_BA_MSK) | BR_PS_16 | BR_V )
+#else
+#define CFG_BR0_PRELIM ((FLASH_BASE0_PRELIM & BR_BA_MSK) | BR_PS_32 | BR_V )
+#endif
+
+#undef CFG_OR1_REMAP
+#undef CFG_OR1_PRELIM
+#undef CFG_BR1_PRELIM
+/*
+ * BR2/3 and OR2/3 (SDRAM)
+ *
+ */
+#define SDRAM_BASE2_PRELIM 0x00000000 /* SDRAM bank #0 */
+#undef SDRAM_BASE3_PRELIM
+#define SDRAM_MAX_SIZE 0x04000000 /* max 64 MB per bank */
+
+/* SDRAM timing: Multiplexed addresses, GPL5 output to GPL5_A (don't care) */
+#define CFG_OR_TIMING_SDRAM 0x00000A00
+
+#define CFG_OR2_PRELIM (CFG_PRELIM_OR_AM | CFG_OR_TIMING_SDRAM )
+#define CFG_BR2_PRELIM ((SDRAM_BASE2_PRELIM & BR_BA_MSK) | BR_MS_UPMA | BR_V )
+
+#undef CFG_OR3_PRELIM
+#undef CFG_BR3_PRELIM
+
+
+/*
+ * Memory Periodic Timer Prescaler
+ *
+ * The Divider for PTA (refresh timer) configuration is based on an
+ * example SDRAM configuration (64 MBit, one bank). The adjustment to
+ * the number of chip selects (NCS) and the actually needed refresh
+ * rate is done by setting MPTPR.
+ *
+ * PTA is calculated from
+ * PTA = (gclk * Trefresh) / ((2 ^ (2 * DFBRG)) * PTP * NCS)
+ *
+ * gclk CPU clock (not bus clock!)
+ * Trefresh Refresh cycle * 4 (four word bursts used)
+ *
+ * 4096 Rows from SDRAM example configuration
+ * 1000 factor s -> ms
+ * 32 PTP (pre-divider from MPTPR) from SDRAM example configuration
+ * 4 Number of refresh cycles per period
+ * 64 Refresh cycle in ms per number of rows
+ * --------------------------------------------
+ * Divider = 4096 * 32 * 1000 / (4 * 64) = 512000
+ *
+ * 50 MHz => 50.000.000 / Divider = 98
+ * 66 Mhz => 66.000.000 / Divider = 129
+ * 80 Mhz => 80.000.000 / Divider = 156
+ */
+#define CFG_MAMR_PTA 98
+
+/* refresh rate 15.6 us (= 64 ms / 4K = 62.4 / quad bursts) for <= 128 MBit */
+#define CFG_MPTPR_2BK_4K MPTPR_PTP_DIV16 /* setting for 2 banks */
+#define CFG_MPTPR_1BK_4K MPTPR_PTP_DIV32 /* setting for 1 bank */
+
+/* refresh rate 7.8 us (= 64 ms / 8K = 31.2 / quad bursts) for 256 MBit */
+#define CFG_MPTPR_2BK_8K MPTPR_PTP_DIV8 /* setting for 2 banks */
+#define CFG_MPTPR_1BK_8K MPTPR_PTP_DIV16 /* setting for 1 bank */
+
+/*
+ * MAMR settings for SDRAM
+ */
+
+/* 8 column SDRAM */
+#define CFG_MAMR_8COL ((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)
+/* 9 column SDRAM */
+#define CFG_MAMR_9COL ((CFG_MAMR_PTA << MAMR_PTA_SHIFT) | MAMR_PTAE | \
+ MAMR_AMA_TYPE_1 | MAMR_DSA_1_CYCL | MAMR_G0CLA_A7 | \
+ MAMR_RLFA_1X | MAMR_WLFA_1X | MAMR_TLFA_4X)
+
+
+/*
+ * Internal Definitions
+ *
+ * Boot Flags
+ */
+#define BOOTFLAG_COLD 0x01 /* Normal Power-On: Boot from FLASH */
+#define BOOTFLAG_WARM 0x02 /* Software reboot */
+
+#endif /* __CONFIG_H */
--- /dev/null
+/*
+ * (C) Copyright 2001
+ * Stefan Roese, esd gmbh germany, stefan.roese@esd-electronics.com
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/*
+ * board/config.h - configuration options, board specific
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+/*
+ * High Level Configuration Options
+ * (easy to change)
+ */
+
+#define CONFIG_405GP 1 /* This is a PPC405 CPU */
+#define CONFIG_4xx 1 /* ...member of PPC4xx family */
+#define CONFIG_OCRTC 1 /* ...on a OCRTC board */
+
+#define CONFIG_BOARD_PRE_INIT 1 /* call board_pre_init() */
+
+#define CONFIG_SYS_CLK_FREQ 33000000 /* external frequency to pll */
+
+#define CONFIG_BAUDRATE 9600
+#define CONFIG_BOOTDELAY 3 /* autoboot after 3 seconds */
+
+#undef CONFIG_BOOTARGS
+#define CONFIG_BOOTCOMMAND "go fff00100"
+
+#define CONFIG_LOADS_ECHO 1 /* echo on for serial download */
+#define CFG_LOADS_BAUD_CHANGE 1 /* allow baudrate change */
+
+#define CONFIG_MII 1 /* MII PHY management */
+#define CONFIG_PHY_ADDR 0 /* PHY address */
+
+#define CONFIG_COMMANDS ( CONFIG_CMD_DFL | \
+ CFG_CMD_PCI | \
+ CFG_CMD_IRQ | \
+ CFG_CMD_ASKENV | \
+ CFG_CMD_ELF | \
+ CFG_CMD_EEPROM )
+
+#define CONFIG_MAC_PARTITION
+#define CONFIG_DOS_PARTITION
+
+/* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */
+#include <cmd_confdefs.h>
+
+#undef CONFIG_WATCHDOG /* watchdog disabled */
+
+#define CONFIG_SDRAM_BANK0 1 /* init onboard SDRAM bank 0 */
+
+/*
+ * Miscellaneous configurable options
+ */
+#define CFG_LONGHELP /* undef to save memory */
+#define CFG_PROMPT "=> " /* Monitor Command Prompt */
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+#define CFG_CBSIZE 1024 /* Console I/O Buffer Size */
+#else
+#define CFG_CBSIZE 256 /* Console I/O Buffer Size */
+#endif
+#define CFG_PBSIZE (CFG_CBSIZE+sizeof(CFG_PROMPT)+16) /* Print Buffer Size */
+#define CFG_MAXARGS 16 /* max number of command args */
+#define CFG_BARGSIZE CFG_CBSIZE /* Boot Argument Buffer Size */
+
+#define CFG_CONSOLE_INFO_QUIET 1 /* don't print console @ startup*/
+
+#define CFG_MEMTEST_START 0x0400000 /* memtest works on */
+#define CFG_MEMTEST_END 0x0C00000 /* 4 ... 12 MB in DRAM */
+
+#undef CFG_EXT_SERIAL_CLOCK /* no external serial clock used */
+#define CFG_IGNORE_405_UART_ERRATA_59 /* ignore ppc405gp errata #59 */
+#define CFG_BASE_BAUD 691200
+
+/* The following table includes the supported baudrates */
+#define CFG_BAUDRATE_TABLE \
+ { 300, 600, 1200, 2400, 4800, 9600, 19200, 38400, \
+ 57600, 115200, 230400, 460800, 921600 }
+
+#define CFG_LOAD_ADDR 0x100000 /* default load address */
+#define CFG_EXTBDINFO 1 /* To use extended board_into (bd_t) */
+
+#define CFG_HZ 1000 /* decrementer freq: 1 ms ticks */
+
+#define CONFIG_ZERO_BOOTDELAY_CHECK /* check for keypress on bootdelay==0 */
+
+/*-----------------------------------------------------------------------
+ * PCI stuff
+ *-----------------------------------------------------------------------
+ */
+#define PCI_HOST_ADAPTER 0 /* configure as pci adapter */
+#define PCI_HOST_FORCE 1 /* configure as pci host */
+#define PCI_HOST_AUTO 2 /* detected via arbiter enable */
+
+#define CONFIG_PCI /* include pci support */
+#define CONFIG_PCI_HOST PCI_HOST_AUTO /* select pci host function */
+#define CONFIG_PCI_PNP /* do pci plug-and-play */
+ /* resource configuration */
+
+#define CONFIG_PCI_SCAN_SHOW /* print pci devices @ startup */
+
+#define CFG_PCI_SUBSYS_VENDORID 0x12FE /* PCI Vendor ID: esd gmbh */
+#define CFG_PCI_SUBSYS_DEVICEID 0x0410 /* PCI Device ID: OCRTC */
+#define CFG_PCI_CLASSCODE 0x0b20 /* PCI Class Code: Processor/PPC*/
+#define CFG_PCI_PTM1LA 0x00000000 /* point to sdram */
+#define CFG_PCI_PTM1MS 0xfc000001 /* 64MB, enable hard-wired to 1 */
+#define CFG_PCI_PTM1PCI 0x00000000 /* Host: use this pci address */
+#define CFG_PCI_PTM2LA 0xffc00000 /* point to flash */
+#define CFG_PCI_PTM2MS 0xffc00001 /* 4MB, enable */
+#define CFG_PCI_PTM2PCI 0x04000000 /* Host: use this pci address */
+
+/*-----------------------------------------------------------------------
+ * Start addresses for the final memory configuration
+ * (Set up by the startup code)
+ * Please note that CFG_SDRAM_BASE _must_ start at 0
+ */
+#define CFG_SDRAM_BASE 0x00000000
+#define CFG_FLASH_BASE 0xFFFD0000
+#define CFG_MONITOR_BASE CFG_FLASH_BASE
+#define CFG_MONITOR_LEN (192 * 1024) /* Reserve 192 kB for Monitor */
+#define CFG_MALLOC_LEN (128 * 1024) /* Reserve 128 kB for malloc() */
+
+/*
+ * For booting Linux, the board info and command line data
+ * have to be in the first 8 MB of memory, since this is
+ * the maximum mapped by the Linux kernel during initialization.
+ */
+#define CFG_BOOTMAPSZ (8 << 20) /* Initial Memory map for Linux */
+/*-----------------------------------------------------------------------
+ * FLASH organization
+ */
+#define CFG_MAX_FLASH_BANKS 2 /* max number of memory banks */
+#define CFG_MAX_FLASH_SECT 256 /* max number of sectors on one chip */
+
+#define CFG_FLASH_ERASE_TOUT 120000 /* Timeout for Flash Erase (in ms) */
+#define CFG_FLASH_WRITE_TOUT 500 /* Timeout for Flash Write (in ms) */
+
+#define CFG_FLASH_WORD_SIZE unsigned short /* flash word size (width) */
+#define CFG_FLASH_ADDR0 0x5555 /* 1st address for flash config cycles */
+#define CFG_FLASH_ADDR1 0x2AAA /* 2nd address for flash config cycles */
+/*
+ * The following defines are added for buggy IOP480 byte interface.
+ * All other boards should use the standard values (CPCI405 etc.)
+ */
+#define CFG_FLASH_READ0 0x0000 /* 0 is standard */
+#define CFG_FLASH_READ1 0x0001 /* 1 is standard */
+#define CFG_FLASH_READ2 0x0002 /* 2 is standard */
+
+#define CFG_FLASH_EMPTY_INFO /* print 'E' for empty sector on flinfo */
+
+#if 0 /* Use NVRAM for environment variables */
+/*-----------------------------------------------------------------------
+ * NVRAM organization
+ */
+#define CFG_ENV_IS_IN_NVRAM 1 /* use NVRAM for environment vars */
+#define CFG_NVRAM_BASE_ADDR 0xf0200000 /* NVRAM base address */
+#define CFG_NVRAM_SIZE (32*1024) /* NVRAM size */
+#define CFG_ENV_SIZE 0x1000 /* Size of Environment vars */
+#define CFG_ENV_ADDR \
+ (CFG_NVRAM_BASE_ADDR+CFG_NVRAM_SIZE-CFG_ENV_SIZE) /* Env */
+#define CFG_NVRAM_VXWORKS_OFFS 0x6900 /* Offset for VxWorks eth-addr */
+
+#else /* Use EEPROM for environment variables */
+
+#define CFG_ENV_IS_IN_EEPROM 1 /* use EEPROM for environment vars */
+#define CFG_ENV_OFFSET 0x000 /* environment starts at the beginning of the EEPROM */
+#define CFG_ENV_SIZE 0x300 /* 768 bytes may be used for env vars */
+ /* total size of a CAT24WC08 is 1024 bytes */
+#endif
+
+/*-----------------------------------------------------------------------
+ * I2C EEPROM (CAT24WC08) for environment
+ */
+#define CONFIG_HARD_I2C /* I2c with hardware support */
+#define CFG_I2C_SPEED 400000 /* I2C speed and slave address */
+#define CFG_I2C_SLAVE 0x7F
+
+#define CFG_I2C_EEPROM_ADDR 0x50 /* EEPROM CAT28WC08 */
+#define CFG_I2C_EEPROM_ADDR_LEN 1 /* Bytes of address */
+/* mask of address bits that overflow into the "EEPROM chip address" */
+#define CFG_I2C_EEPROM_ADDR_OVERFLOW 0x07
+#define CFG_EEPROM_PAGE_WRITE_BITS 4 /* The Catalyst CAT24WC08 has */
+ /* 16 byte page write mode using*/
+ /* last 4 bits of the address */
+#define CFG_EEPROM_PAGE_WRITE_DELAY_MS 10 /* and takes up to 10 msec */
+#define CFG_EEPROM_PAGE_WRITE_ENABLE
+
+/*-----------------------------------------------------------------------
+ * Cache Configuration
+ */
+#define CFG_DCACHE_SIZE 8192 /* For IBM 405 CPUs */
+#define CFG_CACHELINE_SIZE 32 /* ... */
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+#define CFG_CACHELINE_SHIFT 5 /* log base 2 of the above value */
+#endif
+
+/*
+ * Init Memory Controller:
+ *
+ * BR0/1 and OR0/1 (FLASH)
+ */
+
+#define FLASH_BASE0_PRELIM 0xFF800000 /* FLASH bank #0 */
+#define FLASH_BASE1_PRELIM 0xFFC00000 /* FLASH bank #1 */
+
+/*-----------------------------------------------------------------------
+ * External Bus Controller (EBC) Setup
+ */
+
+/* Memory Bank 0 (Flash Bank 0) initialization */
+#define CFG_EBC_PB0AP 0x92015480
+#define CFG_EBC_PB0CR 0xFFC5A000 /* BAS=0xFFC,BS=4MB,BU=R/W,BW=16bit */
+
+/* Memory Bank 1 (Flash Bank 1) initialization */
+#define CFG_EBC_PB1AP 0x92015480
+#define CFG_EBC_PB1CR 0xFF85A000 /* BAS=0xFF8,BS=4MB,BU=R/W,BW=16bit */
+
+/* Memory Bank 2 (PLD - FPGA-boot) initialization */
+#define CFG_EBC_PB2AP 0x02015480 /* BME=0x0,TWT=0x04,CSN=0x0,OEN=0x1 */
+ /* WBN=0x1,WBF=0x1,TH=0x2,RE=0x0,SOR=0x1,BEM=0x0,PEN=0x0*/
+#define CFG_EBC_PB2CR 0xF0018000 /* BAS=0xF00,BS=1MB,BU=R/W,BW=8bit */
+
+/* Memory Bank 3 (PLD - OSL) initialization */
+#define CFG_EBC_PB3AP 0x02015480 /* BME=0x0,TWT=0x04,CSN=0x0,OEN=0x1 */
+ /* WBN=0x1,WBF=0x1,TH=0x2,RE=0x0,SOR=0x1,BEM=0x0,PEN=0x0*/
+#define CFG_EBC_PB3CR 0xF0118000 /* BAS=0xF01,BS=1MB,BU=R/W,BW=8bit */
+
+/* Memory Bank 4 (Spartan2 1) initialization */
+#define CFG_EBC_PB4AP 0x02015580 /* BME=0x0,TWT=0x04,CSN=0x0,OEN=0x1 */
+ /* WBN=0x1,WBF=0x1,TH=0x2,RE=0x1,SOR=0x1,BEM=0x0,PEN=0x0*/
+#define CFG_EBC_PB4CR 0xF209C000 /* BAS=0xF20,BS=16MB,BU=R/W,BW=32bit*/
+
+/* Memory Bank 5 (Spartan2 2) initialization */
+#define CFG_EBC_PB5AP 0x02015580 /* BME=0x0,TWT=0x04,CSN=0x0,OEN=0x1 */
+ /* WBN=0x1,WBF=0x1,TH=0x2,RE=0x1,SOR=0x1,BEM=0x0,PEN=0x0*/
+#define CFG_EBC_PB5CR 0xF309C000 /* BAS=0xF30,BS=16MB,BU=R/W,BW=32bit*/
+
+/* Memory Bank 6 (Virtex 1) initialization */
+#define CFG_EBC_PB6AP 0x02015580 /* BME=0x0,TWT=0x04,CSN=0x0,OEN=0x1 */
+ /* WBN=0x1,WBF=0x1,TH=0x2,RE=0x1,SOR=0x1,BEM=0x0,PEN=0x0*/
+#define CFG_EBC_PB6CR 0xF409A000 /* BAS=0xF40,BS=16MB,BU=R/W,BW=16bit*/
+
+/* Memory Bank 7 (Virtex 2) initialization */
+#define CFG_EBC_PB7AP 0x02015580 /* BME=0x0,TWT=0x04,CSN=0x0,OEN=0x1 */
+ /* WBN=0x1,WBF=0x1,TH=0x2,RE=0x1,SOR=0x1,BEM=0x0,PEN=0x0*/
+#define CFG_EBC_PB7CR 0xF509A000 /* BAS=0xF50,BS=16MB,BU=R/W,BW=16bit*/
+
+
+#define CFG_ETHERNET_MAC_ADDR 0x00000000 /* Pass Ethernet MAC to VxWorks */
+
+/*-----------------------------------------------------------------------
+ * Definitions for initial stack pointer and data area (in DPRAM)
+ */
+
+/* use on chip memory ( OCM ) for temperary stack until sdram is tested */
+#define CFG_TEMP_STACK_OCM 1
+
+/* On Chip Memory location */
+#define CFG_OCM_DATA_ADDR 0xF8000000
+#define CFG_OCM_DATA_SIZE 0x1000
+
+#define CFG_INIT_RAM_ADDR CFG_OCM_DATA_ADDR /* inside of SDRAM */
+#define CFG_INIT_RAM_END CFG_OCM_DATA_SIZE /* End of used area in RAM */
+#define CFG_GBL_DATA_SIZE 128 /* size in bytes reserved for initial data */
+#define CFG_GBL_DATA_OFFSET (CFG_INIT_RAM_END - CFG_GBL_DATA_SIZE)
+#define CFG_INIT_SP_OFFSET CFG_GBL_DATA_OFFSET
+
+
+/*
+ * Internal Definitions
+ *
+ * Boot Flags
+ */
+#define BOOTFLAG_COLD 0x01 /* Normal Power-On: Boot from FLASH */
+#define BOOTFLAG_WARM 0x02 /* Software reboot */
+
+#endif /* __CONFIG_H */
--- /dev/null
+/*
+ * (C) Copyright 2001
+ * Stefan Roese, esd gmbh germany, stefan.roese@esd-electronics.com
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/*
+ * board/config.h - configuration options, board specific
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+/*
+ * High Level Configuration Options
+ * (easy to change)
+ */
+
+#define CONFIG_405GP 1 /* This is a PPC405 CPU */
+#define CONFIG_4xx 1 /* ...member of PPC4xx family */
+#define CONFIG_ORSG 1 /* ...on a ORSG board */
+
+#define CONFIG_BOARD_PRE_INIT 1 /* call board_pre_init() */
+
+#define CONFIG_SYS_CLK_FREQ 33000000 /* external frequency to pll */
+
+#define CONFIG_BAUDRATE 9600
+#define CONFIG_BOOTDELAY 3 /* autoboot after 3 seconds */
+
+#undef CONFIG_BOOTARGS
+#define CONFIG_BOOTCOMMAND "go fff00100"
+
+#define CONFIG_LOADS_ECHO 1 /* echo on for serial download */
+#define CFG_LOADS_BAUD_CHANGE 1 /* allow baudrate change */
+
+#define CONFIG_MII 1 /* MII PHY management */
+#define CONFIG_PHY_ADDR 0 /* PHY address */
+
+#define CONFIG_COMMANDS ( CONFIG_CMD_DFL | \
+ CFG_CMD_PCI | \
+ CFG_CMD_IRQ | \
+ CFG_CMD_ASKENV | \
+ CFG_CMD_ELF | \
+ CFG_CMD_EEPROM )
+
+#define CONFIG_MAC_PARTITION
+#define CONFIG_DOS_PARTITION
+
+/* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */
+#include <cmd_confdefs.h>
+
+#undef CONFIG_WATCHDOG /* watchdog disabled */
+
+#define CONFIG_SDRAM_BANK0 1 /* init onboard SDRAM bank 0 */
+
+/*
+ * Miscellaneous configurable options
+ */
+#define CFG_LONGHELP /* undef to save memory */
+#define CFG_PROMPT "=> " /* Monitor Command Prompt */
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+#define CFG_CBSIZE 1024 /* Console I/O Buffer Size */
+#else
+#define CFG_CBSIZE 256 /* Console I/O Buffer Size */
+#endif
+#define CFG_PBSIZE (CFG_CBSIZE+sizeof(CFG_PROMPT)+16) /* Print Buffer Size */
+#define CFG_MAXARGS 16 /* max number of command args */
+#define CFG_BARGSIZE CFG_CBSIZE /* Boot Argument Buffer Size */
+
+#define CFG_CONSOLE_INFO_QUIET 1 /* don't print console @ startup*/
+
+#define CFG_MEMTEST_START 0x0400000 /* memtest works on */
+#define CFG_MEMTEST_END 0x0C00000 /* 4 ... 12 MB in DRAM */
+
+#undef CFG_EXT_SERIAL_CLOCK /* no external serial clock used */
+#define CFG_IGNORE_405_UART_ERRATA_59 /* ignore ppc405gp errata #59 */
+#define CFG_BASE_BAUD 691200
+
+/* The following table includes the supported baudrates */
+#define CFG_BAUDRATE_TABLE \
+ { 300, 600, 1200, 2400, 4800, 9600, 19200, 38400, \
+ 57600, 115200, 230400, 460800, 921600 }
+
+#define CFG_LOAD_ADDR 0x100000 /* default load address */
+#define CFG_EXTBDINFO 1 /* To use extended board_into (bd_t) */
+
+#define CFG_HZ 1000 /* decrementer freq: 1 ms ticks */
+
+#define CONFIG_ZERO_BOOTDELAY_CHECK /* check for keypress on bootdelay==0 */
+
+/*-----------------------------------------------------------------------
+ * PCI stuff
+ *-----------------------------------------------------------------------
+ */
+#define PCI_HOST_ADAPTER 0 /* configure as pci adapter */
+#define PCI_HOST_FORCE 1 /* configure as pci host */
+#define PCI_HOST_AUTO 2 /* detected via arbiter enable */
+
+#define CONFIG_PCI /* include pci support */
+#define CONFIG_PCI_HOST PCI_HOST_ADAPTER /* select pci adapter */
+#undef CONFIG_PCI_PNP /* no pci plug-and-play */
+ /* resource configuration */
+
+#undef CONFIG_PCI_SCAN_SHOW /* print pci devices @ startup */
+
+#define CFG_PCI_SUBSYS_VENDORID 0x12FE /* PCI Vendor ID: esd gmbh */
+#define CFG_PCI_SUBSYS_DEVICEID 0x0411 /* PCI Device ID: ORSG */
+#define CFG_PCI_CLASSCODE 0x0b20 /* PCI Class Code: Processor/PPC*/
+#define CFG_PCI_PTM1LA 0x00000000 /* point to sdram */
+#define CFG_PCI_PTM1MS 0xfc000001 /* 64MB, enable hard-wired to 1 */
+#define CFG_PCI_PTM1PCI 0x00000000 /* Host: use this pci address */
+#define CFG_PCI_PTM2LA 0xffc00000 /* point to flash */
+#define CFG_PCI_PTM2MS 0xffc00001 /* 4MB, enable */
+#define CFG_PCI_PTM2PCI 0x04000000 /* Host: use this pci address */
+
+/*-----------------------------------------------------------------------
+ * Start addresses for the final memory configuration
+ * (Set up by the startup code)
+ * Please note that CFG_SDRAM_BASE _must_ start at 0
+ */
+#define CFG_SDRAM_BASE 0x00000000
+#define CFG_FLASH_BASE 0xFFFD0000
+#define CFG_MONITOR_BASE CFG_FLASH_BASE
+#define CFG_MONITOR_LEN (192 * 1024) /* Reserve 192 kB for Monitor */
+#define CFG_MALLOC_LEN (128 * 1024) /* Reserve 128 kB for malloc() */
+
+/*
+ * For booting Linux, the board info and command line data
+ * have to be in the first 8 MB of memory, since this is
+ * the maximum mapped by the Linux kernel during initialization.
+ */
+#define CFG_BOOTMAPSZ (8 << 20) /* Initial Memory map for Linux */
+/*-----------------------------------------------------------------------
+ * FLASH organization
+ */
+#define CFG_MAX_FLASH_BANKS 2 /* max number of memory banks */
+#define CFG_MAX_FLASH_SECT 256 /* max number of sectors on one chip */
+
+#define CFG_FLASH_ERASE_TOUT 120000 /* Timeout for Flash Erase (in ms) */
+#define CFG_FLASH_WRITE_TOUT 500 /* Timeout for Flash Write (in ms) */
+
+#define CFG_FLASH_WORD_SIZE unsigned short /* flash word size (width) */
+#define CFG_FLASH_ADDR0 0x5555 /* 1st address for flash config cycles */
+#define CFG_FLASH_ADDR1 0x2AAA /* 2nd address for flash config cycles */
+/*
+ * The following defines are added for buggy IOP480 byte interface.
+ * All other boards should use the standard values (CPCI405 etc.)
+ */
+#define CFG_FLASH_READ0 0x0000 /* 0 is standard */
+#define CFG_FLASH_READ1 0x0001 /* 1 is standard */
+#define CFG_FLASH_READ2 0x0002 /* 2 is standard */
+
+#define CFG_FLASH_EMPTY_INFO /* print 'E' for empty sector on flinfo */
+
+#if 0 /* Use NVRAM for environment variables */
+/*-----------------------------------------------------------------------
+ * NVRAM organization
+ */
+#define CFG_ENV_IS_IN_NVRAM 1 /* use NVRAM for environment vars */
+#define CFG_NVRAM_BASE_ADDR 0xf0200000 /* NVRAM base address */
+#define CFG_NVRAM_SIZE (32*1024) /* NVRAM size */
+#define CFG_ENV_SIZE 0x1000 /* Size of Environment vars */
+#define CFG_ENV_ADDR \
+ (CFG_NVRAM_BASE_ADDR+CFG_NVRAM_SIZE-CFG_ENV_SIZE) /* Env */
+#define CFG_NVRAM_VXWORKS_OFFS 0x6900 /* Offset for VxWorks eth-addr */
+
+#else /* Use EEPROM for environment variables */
+
+#define CFG_ENV_IS_IN_EEPROM 1 /* use EEPROM for environment vars */
+#define CFG_ENV_OFFSET 0x000 /* environment starts at the beginning of the EEPROM */
+#define CFG_ENV_SIZE 0x300 /* 768 bytes may be used for env vars */
+ /* total size of a CAT24WC08 is 1024 bytes */
+#endif
+
+/*-----------------------------------------------------------------------
+ * I2C EEPROM (CAT24WC08) for environment
+ */
+#define CONFIG_HARD_I2C /* I2c with hardware support */
+#define CFG_I2C_SPEED 400000 /* I2C speed and slave address */
+#define CFG_I2C_SLAVE 0x7F
+
+#define CFG_I2C_EEPROM_ADDR 0x50 /* EEPROM CAT28WC08 */
+#define CFG_I2C_EEPROM_ADDR_LEN 1 /* Bytes of address */
+/* mask of address bits that overflow into the "EEPROM chip address" */
+#define CFG_I2C_EEPROM_ADDR_OVERFLOW 0x07
+#define CFG_EEPROM_PAGE_WRITE_BITS 4 /* The Catalyst CAT24WC08 has */
+ /* 16 byte page write mode using*/
+ /* last 4 bits of the address */
+#define CFG_EEPROM_PAGE_WRITE_DELAY_MS 10 /* and takes up to 10 msec */
+#define CFG_EEPROM_PAGE_WRITE_ENABLE
+
+/*-----------------------------------------------------------------------
+ * Cache Configuration
+ */
+#define CFG_DCACHE_SIZE 8192 /* For IBM 405 CPUs */
+#define CFG_CACHELINE_SIZE 32 /* ... */
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+#define CFG_CACHELINE_SHIFT 5 /* log base 2 of the above value */
+#endif
+
+/*
+ * Init Memory Controller:
+ *
+ * BR0/1 and OR0/1 (FLASH)
+ */
+
+#define FLASH_BASE0_PRELIM 0xFF800000 /* FLASH bank #0 */
+#define FLASH_BASE1_PRELIM 0xFFC00000 /* FLASH bank #1 */
+
+/*-----------------------------------------------------------------------
+ * External Bus Controller (EBC) Setup
+ */
+
+/* Memory Bank 0 (Flash Bank 0) initialization */
+#define CFG_EBC_PB0AP 0x92015480
+#define CFG_EBC_PB0CR 0xFFC5A000 /* BAS=0xFFC,BS=4MB,BU=R/W,BW=16bit */
+
+/* Memory Bank 1 (Flash Bank 1) initialization */
+#define CFG_EBC_PB1AP 0x92015480
+#define CFG_EBC_PB1CR 0xFF85A000 /* BAS=0xFF8,BS=4MB,BU=R/W,BW=16bit */
+
+/* Memory Bank 2 (PLD - FPGA-boot) initialization */
+#define CFG_EBC_PB2AP 0x02015480 /* BME=0x0,TWT=0x04,CSN=0x0,OEN=0x1 */
+ /* WBN=0x1,WBF=0x1,TH=0x2,RE=0x0,SOR=0x1,BEM=0x0,PEN=0x0*/
+#define CFG_EBC_PB2CR 0xF0018000 /* BAS=0xF00,BS=1MB,BU=R/W,BW=8bit */
+
+/* Memory Bank 3 (PLD - OSL) initialization */
+#define CFG_EBC_PB3AP 0x02015480 /* BME=0x0,TWT=0x04,CSN=0x0,OEN=0x1 */
+ /* WBN=0x1,WBF=0x1,TH=0x2,RE=0x0,SOR=0x1,BEM=0x0,PEN=0x0*/
+#define CFG_EBC_PB3CR 0xF0118000 /* BAS=0xF01,BS=1MB,BU=R/W,BW=8bit */
+
+/* Memory Bank 4 (Spartan2 1) initialization */
+#define CFG_EBC_PB4AP 0x02015580 /* BME=0x0,TWT=0x04,CSN=0x0,OEN=0x1 */
+ /* WBN=0x1,WBF=0x1,TH=0x2,RE=0x1,SOR=0x1,BEM=0x0,PEN=0x0*/
+#define CFG_EBC_PB4CR 0xF209C000 /* BAS=0xF20,BS=16MB,BU=R/W,BW=32bit*/
+
+/* Memory Bank 5 (Spartan2 2) initialization */
+#define CFG_EBC_PB5AP 0x02015580 /* BME=0x0,TWT=0x04,CSN=0x0,OEN=0x1 */
+ /* WBN=0x1,WBF=0x1,TH=0x2,RE=0x1,SOR=0x1,BEM=0x0,PEN=0x0*/
+#define CFG_EBC_PB5CR 0xF309C000 /* BAS=0xF30,BS=16MB,BU=R/W,BW=32bit*/
+
+/* Memory Bank 6 (Virtex 1) initialization */
+#define CFG_EBC_PB6AP 0x02015580 /* BME=0x0,TWT=0x04,CSN=0x0,OEN=0x1 */
+ /* WBN=0x1,WBF=0x1,TH=0x2,RE=0x1,SOR=0x1,BEM=0x0,PEN=0x0*/
+#define CFG_EBC_PB6CR 0xF409A000 /* BAS=0xF40,BS=16MB,BU=R/W,BW=16bit*/
+
+/* Memory Bank 7 (Virtex 2) initialization */
+#define CFG_EBC_PB7AP 0x02015580 /* BME=0x0,TWT=0x04,CSN=0x0,OEN=0x1 */
+ /* WBN=0x1,WBF=0x1,TH=0x2,RE=0x1,SOR=0x1,BEM=0x0,PEN=0x0*/
+#define CFG_EBC_PB7CR 0xF509A000 /* BAS=0xF50,BS=16MB,BU=R/W,BW=16bit*/
+
+
+#define CFG_ETHERNET_MAC_ADDR 0x00000000 /* Pass Ethernet MAC to VxWorks */
+
+/*-----------------------------------------------------------------------
+ * Definitions for initial stack pointer and data area (in DPRAM)
+ */
+
+/* use on chip memory ( OCM ) for temperary stack until sdram is tested */
+#define CFG_TEMP_STACK_OCM 1
+
+/* On Chip Memory location */
+#define CFG_OCM_DATA_ADDR 0xF8000000
+#define CFG_OCM_DATA_SIZE 0x1000
+
+#define CFG_INIT_RAM_ADDR CFG_OCM_DATA_ADDR /* inside of SDRAM */
+#define CFG_INIT_RAM_END CFG_OCM_DATA_SIZE /* End of used area in RAM */
+#define CFG_GBL_DATA_SIZE 128 /* size in bytes reserved for initial data */
+#define CFG_GBL_DATA_OFFSET (CFG_INIT_RAM_END - CFG_GBL_DATA_SIZE)
+#define CFG_INIT_SP_OFFSET CFG_GBL_DATA_OFFSET
+
+
+/*
+ * Internal Definitions
+ *
+ * Boot Flags
+ */
+#define BOOTFLAG_COLD 0x01 /* Normal Power-On: Boot from FLASH */
+#define BOOTFLAG_WARM 0x02 /* Software reboot */
+
+#endif /* __CONFIG_H */
--- /dev/null
+/*
+ * (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
+ */
+
+/* ------------------------------------------------------------------------- */
+
+/*
+ * board/config.h - configuration options, board specific
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+/*
+ * High Level Configuration Options
+ * (easy to change)
+ */
+
+#define CONFIG_MPC824X 1
+#define CONFIG_MPC8240 1
+#define CONFIG_OXC 1
+
+#define CONFIG_BOARD_PRE_INIT 1 /* Call board_pre_init */
+
+#define CONFIG_IDENT_STRING " [oxc] "
+
+#define CONFIG_WATCHDOG 1
+#define CONFIG_SHOW_ACTIVITY 1
+#define CONFIG_SHOW_BOOT_PROGRESS 1
+
+#define CONFIG_CONS_INDEX 1
+#define CONFIG_BAUDRATE 9600
+#define CFG_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 }
+
+#define CONFIG_COMMANDS (CONFIG_CMD_DFL | CFG_CMD_ELF)
+
+/* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */
+#include <cmd_confdefs.h>
+
+/*
+ * Miscellaneous configurable options
+ */
+#define CFG_LONGHELP 1 /* undef to save memory */
+#define CFG_PROMPT "=> " /* Monitor Command Prompt */
+#define CFG_CBSIZE 256 /* Console I/O Buffer Size */
+#define CFG_PBSIZE (CFG_CBSIZE+sizeof(CFG_PROMPT)+16) /* Print Buffer Size */
+#define CFG_MAXARGS 16 /* max number of command args */
+#define CFG_BARGSIZE CFG_CBSIZE /* Boot Argument Buffer Size */
+#define CFG_LOAD_ADDR 0x00100000 /* default load address */
+#define CFG_HZ 1000 /* decrementer freq: 1 ms ticks */
+
+#define CONFIG_MISC_INIT_R 1 /* call misc_init_r() on init */
+
+/*-----------------------------------------------------------------------
+ * Boot options
+ */
+
+#define CONFIG_SERVERIP 10.0.0.1
+#define CONFIG_GATEWAYIP 10.0.0.1
+#define CONFIG_NETMASK 255.255.255.0
+#define CONFIG_LOADADDR 0x10000
+#define CONFIG_BOOTFILE "/mnt/ide0/p2/usr/tftp/oxc.elf"
+#define CONFIG_BOOTCOMMAND "tftp 0x10000 ; bootelf 0x10000"
+#define CONFIG_BOOTDELAY 10
+
+#define CFG_OXC_GENERATE_IP 1 /* Generate IP automatically */
+#define CFG_OXC_IPMASK 0x0A000000 /* 10.0.0.x */
+
+/*-----------------------------------------------------------------------
+ * PCI stuff
+ */
+
+#define CONFIG_PCI /* include pci support */
+
+#define CONFIG_NET_MULTI /* Multi ethernet cards support */
+
+#define CONFIG_EEPRO100 /* Ethernet Express PRO 100 */
+
+#define PCI_ENET0_IOADDR 0x80000000
+#define PCI_ENET0_MEMADDR 0x80000000
+#define PCI_ENET1_IOADDR 0x81000000
+#define PCI_ENET1_MEMADDR 0x81000000
+
+/*-----------------------------------------------------------------------
+ * FLASH
+ */
+
+#define CFG_FLASH_PRELIMBASE 0xFF800000
+#define CFG_FLASH_BASE (0-flash_info[0].size)
+
+#define CFG_MAX_FLASH_BANKS 1 /* max number of memory banks */
+#define CFG_MAX_FLASH_SECT 32 /* max number of sectors on one chip */
+
+#define CFG_FLASH_ERASE_TOUT 120000 /* Timeout for Flash Erase (in ms) */
+#define CFG_FLASH_WRITE_TOUT 500 /* Timeout for Flash Write (in ms) */
+
+/*-----------------------------------------------------------------------
+ * RAM
+ */
+
+#define CFG_SDRAM_BASE 0x00000000
+#define CFG_MAX_RAM_SIZE 0x10000000
+
+#define CFG_RESET_ADDRESS 0xFFF00100
+
+#define CFG_MONITOR_BASE TEXT_BASE
+#define CFG_MONITOR_LEN 0x00030000
+
+#if (CFG_MONITOR_BASE < CFG_FLASH_PRELIMBASE)
+# define CFG_RAMBOOT 1
+#else
+# undef CFG_RAMBOOT
+#endif
+
+#define CFG_INIT_RAM_ADDR 0x40000000
+#define CFG_INIT_RAM_END 0x1000
+
+#define CFG_GBL_DATA_SIZE 128
+#define CFG_GBL_DATA_OFFSET (CFG_INIT_RAM_END - CFG_GBL_DATA_SIZE)
+#define CFG_INIT_SP_OFFSET CFG_GBL_DATA_OFFSET
+
+#define CFG_MALLOC_LEN (512 << 10) /* Reserve 512 kB for malloc() */
+
+#define CFG_MEMTEST_START 0x00000000 /* memtest works on */
+#define CFG_MEMTEST_END 0x04000000 /* 0 ... 32 MB in DRAM */
+
+/*-----------------------------------------------------------------------
+ * Memory mapping
+ */
+
+#define CFG_CPLD_BASE 0xff000000 /* CPLD registers */
+#define CFG_CPLD_WATCHDOG (CFG_CPLD_BASE) /* Watchdog */
+#define CFG_CPLD_RESET (CFG_CPLD_BASE + 0x040000) /* Minor resets */
+#define CFG_UART_BASE (CFG_CPLD_BASE + 0x700000) /* debug UART */
+
+/*-----------------------------------------------------------------------
+ * NS16550 Configuration
+ */
+
+#define CFG_NS16550
+#define CFG_NS16550_SERIAL
+#define CFG_NS16550_REG_SIZE -4
+#define CFG_NS16550_CLK 1843200
+#define CFG_NS16550_COM1 CFG_UART_BASE
+
+/*-----------------------------------------------------------------------
+ * I2C Bus
+ */
+
+#define CONFIG_I2C 1 /* I2C support on ... */
+#define CONFIG_HARD_I2C 1 /* ... hardware one */
+#define CFG_I2C_SPEED 400000 /* I2C speed and slave address */
+#define CFG_I2C_SLAVE 0x7F /* I2C slave address */
+
+#define CFG_I2C_EXPANDER0_ADDR 0x20 /* PCF8574 expander 0 addrerr */
+#define CFG_I2C_EXPANDER1_ADDR 0x21 /* PCF8574 expander 1 addrerr */
+#define CFG_I2C_EXPANDER2_ADDR 0x26 /* PCF8574 expander 2 addrerr */
+
+/*-----------------------------------------------------------------------
+ * Environment
+ */
+
+#define CFG_ENV_IS_IN_FLASH 1
+#define CFG_ENV_ADDR 0xFFF30000 /* Offset of Environment Sector */
+#define CFG_ENV_SIZE 0x00010000 /* Total Size of Environment Sector */
+#define CONFIG_ENV_OVERWRITE 1 /* Allow modifying the environment */
+
+/*
+ * Low Level Configuration Settings
+ * (address mappings, register initial values, etc.)
+ * You should know what you are doing if you make changes here.
+ */
+
+#define CONFIG_SYS_CLK_FREQ 33000000 /* external frequency to pll */
+#define CONFIG_PLL_PCI_TO_MEM_MULTIPLIER 2
+
+#define CFG_EUMB_ADDR 0xFC000000
+
+/* MCCR1 */
+#define CFG_ROMNAL 0 /* rom/flash next access time */
+#define CFG_ROMFAL 19 /* rom/flash access time */
+
+/* MCCR2 */
+#define CFG_ASRISE 15 /* ASRISE=15 clocks */
+#define CFG_ASFALL 3 /* ASFALL=3 clocks */
+#define CFG_REFINT 1000 /* REFINT=1000 clocks */
+
+/* MCCR3 */
+#define CFG_BSTOPRE 0x35c /* Burst To Precharge */
+#define CFG_REFREC 7 /* Refresh to activate interval */
+#define CFG_RDLAT 4 /* data latency from read command */
+
+/* MCCR4 */
+#define CFG_PRETOACT 2 /* Precharge to activate interval */
+#define CFG_ACTTOPRE 5 /* Activate to Precharge interval */
+#define CFG_ACTORW 2 /* Activate to R/W */
+#define CFG_SDMODE_CAS_LAT 3 /* SDMODE CAS latency */
+#define CFG_SDMODE_WRAP 0 /* SDMODE wrap type */
+#define CFG_SDMODE_BURSTLEN 3 /* SDMODE Burst length 2=4, 3=8 */
+#define CFG_REGISTERD_TYPE_BUFFER 1
+
+/* memory bank settings*/
+/*
+ * only bits 20-29 are actually used from these vales to set the
+ * start/end address the upper two bits will be 0, and the lower 20
+ * bits will be set to 0x00000 for a start address, or 0xfffff for an
+ * end address
+ */
+#define CFG_BANK0_START 0x00000000
+#define CFG_BANK0_END (CFG_MAX_RAM_SIZE - 1)
+#define CFG_BANK0_ENABLE 1
+#define CFG_BANK1_START 0x00000000
+#define CFG_BANK1_END 0x00000000
+#define CFG_BANK1_ENABLE 0
+#define CFG_BANK2_START 0x00000000
+#define CFG_BANK2_END 0x00000000
+#define CFG_BANK2_ENABLE 0
+#define CFG_BANK3_START 0x00000000
+#define CFG_BANK3_END 0x00000000
+#define CFG_BANK3_ENABLE 0
+#define CFG_BANK4_START 0x00000000
+#define CFG_BANK4_END 0x00000000
+#define CFG_BANK4_ENABLE 0
+#define CFG_BANK5_START 0x00000000
+#define CFG_BANK5_END 0x00000000
+#define CFG_BANK5_ENABLE 0
+#define CFG_BANK6_START 0x00000000
+#define CFG_BANK6_END 0x00000000
+#define CFG_BANK6_ENABLE 0
+#define CFG_BANK7_START 0x00000000
+#define CFG_BANK7_END 0x00000000
+#define CFG_BANK7_ENABLE 0
+/*
+ * Memory bank enable bitmask, specifying which of the banks defined above
+ are actually present. MSB is for bank #7, LSB is for bank #0.
+ */
+#define CFG_BANK_ENABLE 0x01
+
+#define CFG_ODCR 0xff /* configures line driver impedances, */
+ /* see 8240 book for bit definitions */
+#define CFG_PGMAX 0x32 /* how long the 8240 retains the */
+ /* currently accessed page in memory */
+ /* see 8240 book for details */
+
+/* SDRAM 0 - 256MB */
+#define CFG_IBAT0L (CFG_SDRAM_BASE | BATL_PP_10 | BATL_MEMCOHERENCE)
+#define CFG_IBAT0U (CFG_SDRAM_BASE | BATU_BL_256M | BATU_VS | BATU_VP)
+
+/* stack in DCACHE @ 1GB (no backing mem) */
+#define CFG_IBAT1L (CFG_INIT_RAM_ADDR | BATL_PP_10 | BATL_MEMCOHERENCE)
+#define CFG_IBAT1U (CFG_INIT_RAM_ADDR | BATU_BL_128K | BATU_VS | BATU_VP)
+
+/* PCI memory */
+#define CFG_IBAT2L (0x80000000 | BATL_PP_10 | BATL_CACHEINHIBIT)
+#define CFG_IBAT2U (0x80000000 | BATU_BL_256M | BATU_VS | BATU_VP)
+
+/* Flash, config addrs, etc */
+#define CFG_IBAT3L (0xF0000000 | BATL_PP_10 | BATL_CACHEINHIBIT)
+#define CFG_IBAT3U (0xF0000000 | BATU_BL_256M | BATU_VS | BATU_VP)
+
+#define CFG_DBAT0L CFG_IBAT0L
+#define CFG_DBAT0U CFG_IBAT0U
+#define CFG_DBAT1L CFG_IBAT1L
+#define CFG_DBAT1U CFG_IBAT1U
+#define CFG_DBAT2L CFG_IBAT2L
+#define CFG_DBAT2U CFG_IBAT2U
+#define CFG_DBAT3L CFG_IBAT3L
+#define CFG_DBAT3U CFG_IBAT3U
+
+/*
+ * For booting Linux, the board info and command line data
+ * have to be in the first 8 MB of memory, since this is
+ * the maximum mapped by the Linux kernel during initialization.
+ */
+#define CFG_BOOTMAPSZ (8 << 20) /* Initial Memory map for Linux */
+
+/*-----------------------------------------------------------------------
+ * Cache Configuration
+ */
+#define CFG_CACHELINE_SIZE 32 /* For MPC8240 CPU */
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+# define CFG_CACHELINE_SHIFT 5 /* log base 2 of the above value */
+#endif
+
+/*
+ * Internal Definitions
+ *
+ * Boot Flags
+ */
+#define BOOTFLAG_COLD 0x01 /* Normal Power-On: Boot from FLASH */
+#define BOOTFLAG_WARM 0x02 /* Software reboot */
+
+#endif /* __CONFIG_H */
--- /dev/null
+/*
+ * (C) Copyright 2001
+ * Stefan Roese, esd gmbh germany, stefan.roese@esd-electronics.com
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/*
+ * board/config.h - configuration options, board specific
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+/*
+ * High Level Configuration Options
+ * (easy to change)
+ */
+
+#define CONFIG_405GP 1 /* This is a PPC405 CPU */
+#define CONFIG_4xx 1 /* ...member of PPC4xx family */
+#define CONFIG_PCI405 1 /* ...on a PCI405 board */
+
+#define CONFIG_BOARD_PRE_INIT 1 /* call board_pre_init() */
+#define CONFIG_MISC_INIT_R 1 /* call misc_init_r() on init */
+
+#define CONFIG_SYS_CLK_FREQ 25000000 /* external frequency to pll */
+
+#define CONFIG_BAUDRATE 9600
+#define CONFIG_BOOTDELAY 3 /* autoboot after 3 seconds */
+
+#if 0
+#define CONFIG_PREBOOT \
+ "crc32 f0207004 ffc 0;" \
+ "if cmp 0 f0207000 1;" \
+ "then;echo Old CRC is correct;crc32 f0207004 ff4 f0207000;" \
+ "else;echo Old CRC is bad;fi"
+#endif
+
+#undef CONFIG_BOOTARGS
+#if 1
+#define CONFIG_BOOTCOMMAND \
+ "bootm fffc0000"
+#else
+#define CONFIG_BOOTCOMMAND \
+ "mw.l 0 ffffffff; mw.l 4 ffffffff;" \
+ "while cmp 0 4 1; do echo Waiting for Host...;done;" \
+ "bootm 400000"
+#endif
+
+#define CONFIG_LOADS_ECHO 1 /* echo on for serial download */
+#define CFG_LOADS_BAUD_CHANGE 1 /* allow baudrate change */
+
+#define CONFIG_MII 1 /* MII PHY management */
+#define CONFIG_PHY_ADDR 0 /* PHY address */
+
+#define CONFIG_RTC_M48T35A 1 /* ST Electronics M48 timekeeper */
+
+#define CONFIG_COMMANDS ( CONFIG_CMD_DFL | \
+ CFG_CMD_PCI | \
+ CFG_CMD_IRQ | \
+ CFG_CMD_ELF | \
+ CFG_CMD_DATE | \
+ CFG_CMD_I2C | \
+ CFG_CMD_EEPROM )
+
+/* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */
+#include <cmd_confdefs.h>
+
+#undef CONFIG_WATCHDOG /* watchdog disabled */
+
+#define CONFIG_SDRAM_BANK0 1 /* init onboard SDRAM bank 0 */
+
+/*
+ * Miscellaneous configurable options
+ */
+#define CFG_LONGHELP /* undef to save memory */
+#define CFG_PROMPT "=> " /* Monitor Command Prompt */
+
+#define CFG_HUSH_PARSER /* use "hush" command parser */
+#ifdef CFG_HUSH_PARSER
+#define CFG_PROMPT_HUSH_PS2 "> "
+#endif
+
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+#define CFG_CBSIZE 1024 /* Console I/O Buffer Size */
+#else
+#define CFG_CBSIZE 256 /* Console I/O Buffer Size */
+#endif
+#define CFG_PBSIZE (CFG_CBSIZE+sizeof(CFG_PROMPT)+16) /* Print Buffer Size */
+#define CFG_MAXARGS 16 /* max number of command args */
+#define CFG_BARGSIZE CFG_CBSIZE /* Boot Argument Buffer Size */
+
+#define CFG_DEVICE_NULLDEV 1 /* include nulldev device */
+
+#define CFG_CONSOLE_INFO_QUIET 1 /* don't print console @ startup*/
+
+#define CFG_MEMTEST_START 0x0400000 /* memtest works on */
+#define CFG_MEMTEST_END 0x0C00000 /* 4 ... 12 MB in DRAM */
+
+#undef CFG_EXT_SERIAL_CLOCK /* no external serial clock used */
+#define CFG_IGNORE_405_UART_ERRATA_59 /* ignore ppc405gp errata #59 */
+#define CFG_BASE_BAUD 691200
+
+/* The following table includes the supported baudrates */
+#define CFG_BAUDRATE_TABLE \
+ { 300, 600, 1200, 2400, 4800, 9600, 19200, 38400, \
+ 57600, 115200, 230400, 460800, 921600 }
+
+#define CFG_LOAD_ADDR 0x100000 /* default load address */
+#define CFG_EXTBDINFO 1 /* To use extended board_into (bd_t) */
+
+#define CFG_HZ 1000 /* decrementer freq: 1 ms ticks */
+
+#define CONFIG_ZERO_BOOTDELAY_CHECK /* check for keypress on bootdelay==0 */
+
+/*-----------------------------------------------------------------------
+ * PCI stuff
+ *-----------------------------------------------------------------------
+ */
+#define PCI_HOST_ADAPTER 0 /* configure as pci adapter */
+#define PCI_HOST_FORCE 1 /* configure as pci host */
+#define PCI_HOST_AUTO 2 /* detected via arbiter enable */
+
+#define CONFIG_PCI /* include pci support */
+#define CONFIG_PCI_HOST PCI_HOST_ADAPTER /* select pci host function */
+#undef CONFIG_PCI_PNP /* no pci plug-and-play */
+ /* resource configuration */
+
+#define CONFIG_PCI_SCAN_SHOW /* print pci devices @ startup */
+
+#define CFG_PCI_SUBSYS_VENDORID 0x12FE /* PCI Vendor ID: esd gmbh */
+#define CFG_PCI_SUBSYS_DEVICEID 0x0407 /* PCI Device ID: PCI-405 */
+#define CFG_PCI_CLASSCODE 0x0280 /* PCI Class Code: Network/Other*/
+#define CFG_PCI_PTM1LA 0x00000000 /* point to sdram */
+#define CFG_PCI_PTM1MS 0xfc000001 /* 64MB, enable hard-wired to 1 */
+#define CFG_PCI_PTM1PCI 0x00000000 /* Host: use this pci address */
+
+#if 0 /* test-only */
+#define CFG_PCI_PTM2LA 0xffc00000 /* point to flash */
+#define CFG_PCI_PTM2MS 0xffc00001 /* 4MB, enable */
+#define CFG_PCI_PTM2PCI 0x04000000 /* Host: use this pci address */
+#else
+#define CFG_PCI_PTM2LA 0xef600000 /* point to internal regs */
+#define CFG_PCI_PTM2MS 0xef600001 /* 4MB, enable */
+#define CFG_PCI_PTM2PCI 0x04000000 /* Host: use this pci address */
+#endif
+
+/*-----------------------------------------------------------------------
+ * Start addresses for the final memory configuration
+ * (Set up by the startup code)
+ * Please note that CFG_SDRAM_BASE _must_ start at 0
+ */
+#define CFG_SDRAM_BASE 0x00000000
+#define CFG_FLASH_BASE 0xFFFD0000
+#define CFG_MONITOR_BASE CFG_FLASH_BASE
+#define CFG_MONITOR_LEN (192 * 1024) /* Reserve 196 kB for Monitor */
+#define CFG_MALLOC_LEN (128 * 1024) /* Reserve 128 kB for malloc() */
+
+/*
+ * For booting Linux, the board info and command line data
+ * have to be in the first 8 MB of memory, since this is
+ * the maximum mapped by the Linux kernel during initialization.
+ */
+#define CFG_BOOTMAPSZ (8 << 20) /* Initial Memory map for Linux */
+/*-----------------------------------------------------------------------
+ * FLASH organization
+ */
+#define CFG_MAX_FLASH_BANKS 1 /* max number of memory banks */
+#define CFG_MAX_FLASH_SECT 256 /* max number of sectors on one chip */
+
+#define CFG_FLASH_ERASE_TOUT 120000 /* Timeout for Flash Erase (in ms) */
+#define CFG_FLASH_WRITE_TOUT 500 /* Timeout for Flash Write (in ms) */
+
+#define CFG_FLASH_WORD_SIZE unsigned short /* flash word size (width) */
+#define CFG_FLASH_ADDR0 0x5555 /* 1st address for flash config cycles */
+#define CFG_FLASH_ADDR1 0x2AAA /* 2nd address for flash config cycles */
+/*
+ * The following defines are added for buggy IOP480 byte interface.
+ * All other boards should use the standard values (CPCI405 etc.)
+ */
+#define CFG_FLASH_READ0 0x0000 /* 0 is standard */
+#define CFG_FLASH_READ1 0x0001 /* 1 is standard */
+#define CFG_FLASH_READ2 0x0002 /* 2 is standard */
+
+#define CFG_FLASH_EMPTY_INFO /* print 'E' for empty sector on flinfo */
+
+#if 0 /* Use NVRAM for environment variables */
+/*-----------------------------------------------------------------------
+ * NVRAM organization
+ */
+#define CFG_ENV_IS_IN_NVRAM 1 /* use NVRAM for environment vars */
+#define CFG_ENV_SIZE 0x0ff8 /* Size of Environment vars */
+#define CFG_ENV_ADDR \
+ (CFG_NVRAM_BASE_ADDR+CFG_NVRAM_SIZE-(CFG_ENV_SIZE+8)) /* Env */
+
+#else /* Use EEPROM for environment variables */
+
+#define CFG_ENV_IS_IN_EEPROM 1 /* use EEPROM for environment vars */
+#define CFG_ENV_OFFSET 0x000 /* environment starts at the beginning of the EEPROM */
+#define CFG_ENV_SIZE 0x400 /* 1024 bytes may be used for env vars*/
+ /* total size of a CAT24WC08 is 1024 bytes */
+#endif
+
+#define CFG_NVRAM_BASE_ADDR 0xf0200000 /* NVRAM base address */
+#define CFG_NVRAM_SIZE (32*1024) /* NVRAM size */
+
+/*-----------------------------------------------------------------------
+ * I2C EEPROM (CAT24WC16) for environment
+ */
+#define CONFIG_HARD_I2C /* I2c with hardware support */
+#define CFG_I2C_SPEED 400000 /* I2C speed and slave address */
+#define CFG_I2C_SLAVE 0x7F
+
+#define CFG_I2C_EEPROM_ADDR 0x50 /* EEPROM CAT28WC08 */
+#define CFG_I2C_EEPROM_ADDR_LEN 1 /* Bytes of address */
+/* mask of address bits that overflow into the "EEPROM chip address" */
+#define CFG_I2C_EEPROM_ADDR_OVERFLOW 0x07
+#define CFG_EEPROM_PAGE_WRITE_BITS 4 /* The Catalyst CAT24WC08 has */
+ /* 16 byte page write mode using*/
+ /* last 4 bits of the address */
+#define CFG_EEPROM_PAGE_WRITE_DELAY_MS 10 /* and takes up to 10 msec */
+#define CFG_EEPROM_PAGE_WRITE_ENABLE
+
+/*-----------------------------------------------------------------------
+ * Cache Configuration
+ */
+#define CFG_DCACHE_SIZE 8192 /* For IBM 405 CPUs */
+#define CFG_CACHELINE_SIZE 32 /* ... */
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+#define CFG_CACHELINE_SHIFT 5 /* log base 2 of the above value */
+#endif
+
+/*
+ * Init Memory Controller:
+ *
+ * BR0/1 and OR0/1 (FLASH)
+ */
+
+#define FLASH_BASE0_PRELIM 0xFFE00000 /* FLASH bank #0 */
+
+/*-----------------------------------------------------------------------
+ * External Bus Controller (EBC) Setup
+ */
+
+/* Memory Bank 0 (Flash Bank 0) initialization */
+#define CFG_EBC_PB0AP 0x92015480
+#define CFG_EBC_PB0CR 0xFFC5A000 /* BAS=0xFFC,BS=4MB,BU=R/W,BW=16bit */
+
+/* Memory Bank 1 (NVRAM/RTC) initialization */
+#define CFG_EBC_PB1AP 0x01005280 /* TWT=2,WBN=1,WBF=1,TH=1,SOR=1 */
+#define CFG_EBC_PB1CR 0xF0218000 /* BAS=0xF02,BS=1MB,BU=R/W,BW=8bit */
+
+/* Memory Bank 2 (CAN0, 1) initialization */
+#define CFG_EBC_PB2AP 0x010053C0 /* BWT=2,WBN=1,WBF=1,TH=1,RE=1,SOR=1,BEM=1 */
+#define CFG_EBC_PB2CR 0xF0018000 /* BAS=0xF00,BS=1MB,BU=R/W,BW=8bit */
+
+/* Memory Bank 3 (FPGA internal) initialization */
+#define CFG_EBC_PB3AP 0x010053C0 /* BWT=2,WBN=1,WBF=1,TH=1,RE=1,SOR=1,BEM=1 */
+#define CFG_EBC_PB3CR 0xF041C000 /* BAS=0xF01,BS=1MB,BU=R/W,BW=32bit */
+#define CFG_FPGA_BASE_ADDR 0xF0400000
+
+/*-----------------------------------------------------------------------
+ * FPGA stuff
+ */
+/* FPGA internal regs */
+#define CFG_FPGA_MODE 0x00
+#define CFG_FPGA_STATUS 0x02
+#define CFG_FPGA_TS 0x04
+#define CFG_FPGA_TS_LOW 0x06
+#define CFG_FPGA_TS_CAP0 0x10
+#define CFG_FPGA_TS_CAP0_LOW 0x12
+#define CFG_FPGA_TS_CAP1 0x14
+#define CFG_FPGA_TS_CAP1_LOW 0x16
+#define CFG_FPGA_TS_CAP2 0x18
+#define CFG_FPGA_TS_CAP2_LOW 0x1a
+#define CFG_FPGA_TS_CAP3 0x1c
+#define CFG_FPGA_TS_CAP3_LOW 0x1e
+
+/* FPGA Mode Reg */
+#define CFG_FPGA_MODE_CF_RESET 0x0001
+#define CFG_FPGA_MODE_TS_IRQ_ENABLE 0x0100
+#define CFG_FPGA_MODE_TS_IRQ_CLEAR 0x1000
+#define CFG_FPGA_MODE_TS_CLEAR 0x2000
+
+/* FPGA Status Reg */
+#define CFG_FPGA_STATUS_DIP0 0x0001
+#define CFG_FPGA_STATUS_DIP1 0x0002
+#define CFG_FPGA_STATUS_DIP2 0x0004
+#define CFG_FPGA_STATUS_FLASH 0x0008
+#define CFG_FPGA_STATUS_TS_IRQ 0x1000
+
+#define CFG_FPGA_SPARTAN2 1 /* using Xilinx Spartan 2 now */
+#define CFG_FPGA_MAX_SIZE 32*1024 /* 32kByte is enough for XC2S15 */
+
+/* FPGA program pin configuration */
+#define CFG_FPGA_PRG 0x04000000 /* FPGA program pin (ppc output) */
+#define CFG_FPGA_CLK 0x02000000 /* FPGA clk pin (ppc output) */
+#define CFG_FPGA_DATA 0x01000000 /* FPGA data pin (ppc output) */
+#define CFG_FPGA_INIT 0x00400000 /* FPGA init pin (ppc input) */
+#define CFG_FPGA_DONE 0x00800000 /* FPGA done pin (ppc input) */
+
+/*-----------------------------------------------------------------------
+ * Definitions for initial stack pointer and data area (in data cache)
+ */
+#if 1 /* test-only */
+#define CFG_INIT_DCACHE_CS 7 /* use cs # 7 for data cache memory */
+
+#define CFG_INIT_RAM_ADDR 0x40000000 /* use data cache */
+#else
+#define CFG_INIT_RAM_ADDR 0x00df0000 /* inside of SDRAM */
+#endif
+#define CFG_INIT_RAM_END 0x2000 /* End of used area in RAM */
+#define CFG_GBL_DATA_SIZE 128 /* size in bytes reserved for initial data */
+#define CFG_GBL_DATA_OFFSET (CFG_INIT_RAM_END - CFG_GBL_DATA_SIZE)
+#define CFG_INIT_SP_OFFSET CFG_GBL_DATA_OFFSET
+
+
+/*
+ * Internal Definitions
+ *
+ * Boot Flags
+ */
+#define BOOTFLAG_COLD 0x01 /* Normal Power-On: Boot from FLASH */
+#define BOOTFLAG_WARM 0x02 /* Software reboot */
+
+#endif /* __CONFIG_H */
--- /dev/null
+/*
+ * (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
+ */
+
+/*
+ * board/config.h - configuration options, board specific
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+/***********************************************************
+ * High Level Configuration Options
+ * (easy to change)
+ ***********************************************************/
+#define CONFIG_405GP 1 /* This is a PPC405 CPU */
+#define CONFIG_4xx 1 /* ...member of PPC4xx family */
+#define CONFIG_PIP405 1 /* ...on a PIP405 board */
+/***********************************************************
+ * Clock
+ ***********************************************************/
+#define CONFIG_SYS_CLK_FREQ 33000000 /* external frequency to pll */
+
+/***********************************************************
+ * Command definitions
+ ***********************************************************/
+#define CONFIG_COMMANDS \
+ (CONFIG_CMD_DFL | \
+ CFG_CMD_IDE | \
+ CFG_CMD_DHCP | \
+ CFG_CMD_PCI | \
+ CFG_CMD_CACHE | \
+ CFG_CMD_IRQ | \
+ CFG_CMD_EEPROM | \
+ CFG_CMD_I2C | \
+ CFG_CMD_REGINFO | \
+ CFG_CMD_FDC | \
+ CFG_CMD_SCSI | \
+ CFG_CMD_DATE | \
+ CFG_CMD_ELF | \
+ CFG_CMD_USB | \
+ CFG_CMD_MII | \
+ CFG_CMD_SDRAM | \
+ CFG_CMD_DOC | \
+ CFG_CMD_SAVES | \
+ CFG_CMD_BSP )
+/* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */
+#include <cmd_confdefs.h>
+
+#define CFG_HUSH_PARSER
+#define CFG_PROMPT_HUSH_PS2 "> "
+/**************************************************************
+ * I2C Stuff:
+ * the PIP405 is equiped with an Atmel 24C128/256 EEPROM at address
+ * 0x53.
+ * Caution: on the same bus is the SPD (Serial Presens Detect
+ * EEPROM of the SDRAM
+ * The Atmel EEPROM uses 16Bit addressing.
+ ***************************************************************/
+#define CONFIG_HARD_I2C /* I2c with hardware support */
+#define CFG_I2C_SPEED 50000 /* I2C speed and slave address */
+#define CFG_I2C_SLAVE 0x7F
+
+#define CFG_I2C_EEPROM_ADDR 0x53
+#define CFG_I2C_EEPROM_ADDR_LEN 2
+#define CFG_ENV_IS_IN_EEPROM 1 /* use EEPROM for environment vars */
+#define CFG_ENV_OFFSET 0x000 /* environment starts at the beginning of the EEPROM */
+#define CFG_ENV_SIZE 0x800 /* 2 kBytes may be used for env vars */
+
+#undef CFG_I2C_EEPROM_ADDR_OVERFLOW
+#define CFG_EEPROM_PAGE_WRITE_BITS 6 /* The Atmel 24C128/256 has */
+ /* 64 byte page write mode using*/
+ /* last 6 bits of the address */
+#define CFG_EEPROM_PAGE_WRITE_ENABLE /* enable Page write */
+#define CFG_EEPROM_PAGE_WRITE_DELAY_MS 10 /* and takes up to 10 msec */
+
+
+/***************************************************************
+ * Definitions for Serial Presence Detect EEPROM address
+ * (to get SDRAM settings)
+ ***************************************************************/
+#define SPD_EEPROM_ADDRESS 0x50
+
+#define CONFIG_BOARD_PRE_INIT
+/**************************************************************
+ * Environment definitions
+ **************************************************************/
+#define CONFIG_BAUDRATE 9600 /* STD Baudrate */
+
+
+#define CONFIG_BOOTDELAY 5
+/* autoboot (do NOT change this set environment variable "bootdelay" to -1 instead) */
+#define CONFIG_BOOT_RETRY_TIME -10 /* feature is avaiable but not enabled */
+#define CONFIG_ZERO_BOOTDELAY_CHECK /* check console even if bootdelay = 0 */
+
+
+#define CONFIG_BOOTCOMMAND "diskboot 200000 0:1; bootm" /* autoboot command */
+#define CONFIG_BOOTARGS "console=ttyS0,9600 root=/dev/hda5" /* boot arguments */
+
+#define CONFIG_IPADDR 10.0.0.100
+#define CONFIG_SERVERIP 10.0.0.1
+#define CONFIG_PREBOOT
+/***************************************************************
+ * defines if the console is stored in the environment
+ ***************************************************************/
+#define CFG_CONSOLE_IS_IN_ENV /* stdin, stdout and stderr are in evironment */
+/***************************************************************
+ * defines if an overwrite_console function exists
+ *************************************************************/
+#define CFG_CONSOLE_OVERWRITE_ROUTINE
+#define CFG_CONSOLE_INFO_QUIET
+/***************************************************************
+ * defines if the overwrite_console should be stored in the
+ * environment
+ **************************************************************/
+#undef CFG_CONSOLE_ENV_OVERWRITE
+
+/**************************************************************
+ * loads config
+ *************************************************************/
+#define CONFIG_LOADS_ECHO 1 /* echo on for serial download */
+#define CFG_LOADS_BAUD_CHANGE 1 /* allow baudrate change */
+
+
+/***********************************************************
+ * Miscellaneous configurable options
+ **********************************************************/
+#define CFG_LONGHELP /* undef to save memory */
+#define CFG_PROMPT "=> " /* Monitor Command Prompt */
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+#define CFG_CBSIZE 1024 /* Console I/O Buffer Size */
+#else
+#define CFG_CBSIZE 256 /* Console I/O Buffer Size */
+#endif
+#define CFG_PBSIZE (CFG_CBSIZE+sizeof(CFG_PROMPT)+16) /* Print Buffer Size */
+#define CFG_MAXARGS 16 /* max number of command args */
+#define CFG_BARGSIZE CFG_CBSIZE /* Boot Argument Buffer Size */
+
+#define CFG_MEMTEST_START 0x0100000 /* memtest works on */
+#define CFG_MEMTEST_END 0x0C00000 /* 1 ... 12 MB in DRAM */
+
+#undef CFG_EXT_SERIAL_CLOCK /* no external serial clock used */
+#define CFG_BASE_BAUD 691200
+
+/* The following table includes the supported baudrates */
+#define CFG_BAUDRATE_TABLE \
+ { 300, 600, 1200, 2400, 4800, 9600, 19200, 38400, \
+ 57600, 115200, 230400, 460800, 921600 }
+
+#define CFG_LOAD_ADDR 0x200000 /* default load address */
+#define CFG_EXTBDINFO 1 /* To use extended board_into (bd_t) */
+
+#define CFG_HZ 1000 /* decrementer freq: 1 ms ticks */
+
+/*-----------------------------------------------------------------------
+ * PCI stuff
+ *-----------------------------------------------------------------------
+ */
+#define PCI_HOST_ADAPTER 0 /* configure ar pci adapter */
+#define PCI_HOST_FORCE 1 /* configure as pci host */
+#define PCI_HOST_AUTO 2 /* detected via arbiter enable */
+
+#define CONFIG_PCI /* include pci support */
+#define CONFIG_PCI_HOST PCI_HOST_FORCE /* configure as pci-host */
+#define CONFIG_PCI_PNP /* pci plug-and-play */
+ /* resource configuration */
+#define CFG_PCI_SUBSYS_VENDORID 0x0000 /* PCI Vendor ID: to-do!!! */
+#define CFG_PCI_SUBSYS_DEVICEID 0x0000 /* PCI Device ID: to-do!!! */
+#define CFG_PCI_PTM1LA 0x00000000 /* point to sdram */
+#define CFG_PCI_PTM1MS 0x80000001 /* 2GB, enable hard-wired to 1 */
+#define CFG_PCI_PTM1PCI 0x00000000 /* Host: use this pci address */
+#define CFG_PCI_PTM2LA 0x00000000 /* disabled */
+#define CFG_PCI_PTM2MS 0x00000000 /* disabled */
+#define CFG_PCI_PTM2PCI 0x00000000 /* Host: use this pci address */
+
+/*-----------------------------------------------------------------------
+ * Start addresses for the final memory configuration
+ * (Set up by the startup code)
+ * Please note that CFG_SDRAM_BASE _must_ start at 0
+ */
+#define CFG_SDRAM_BASE 0x00000000
+#define CFG_FLASH_BASE 0xFFF80000
+#define CFG_MONITOR_BASE CFG_FLASH_BASE
+#define CFG_MONITOR_LEN (512 * 1024) /* Reserve 512 kB for Monitor */
+#define CFG_MALLOC_LEN (128 * 1024) /* Reserve 128 kB for malloc() */
+
+/*
+ * For booting Linux, the board info and command line data
+ * have to be in the first 8 MB of memory, since this is
+ * the maximum mapped by the Linux kernel during initialization.
+ */
+#define CFG_BOOTMAPSZ (8 << 20) /* Initial Memory map for Linux */
+/*-----------------------------------------------------------------------
+ * FLASH organization
+ */
+#define CFG_MAX_FLASH_BANKS 1 /* max number of memory banks */
+#define CFG_MAX_FLASH_SECT 256 /* max number of sectors on one chip */
+
+#define CFG_FLASH_ERASE_TOUT 120000 /* Timeout for Flash Erase (in ms) */
+#define CFG_FLASH_WRITE_TOUT 500 /* Timeout for Flash Write (in ms) */
+
+/*-----------------------------------------------------------------------
+ * Cache Configuration
+ */
+#define CFG_DCACHE_SIZE 8192 /* For IBM 405 CPUs */
+#define CFG_CACHELINE_SIZE 32 /* ... */
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+#define CFG_CACHELINE_SHIFT 5 /* log base 2 of the above value */
+#endif
+
+/*
+ * Init Memory Controller:
+ */
+
+#define FLASH_BASE0_PRELIM 0xFFC00000 /* FLASH bank #0 */
+#define FLASH_BASE1_PRELIM 0 /* FLASH bank #1 */
+
+/* Configuration Port location */
+#define CONFIG_PORT_ADDR 0xF4000000
+#define MULTI_PURPOSE_SOCKET_ADDR 0xF8000000
+
+
+
+/*-----------------------------------------------------------------------
+ * Definitions for initial stack pointer and data area (in On Chip SRAM)
+ */
+#define CFG_TEMP_STACK_OCM 1
+#define CFG_OCM_DATA_ADDR 0xF0000000
+#define CFG_OCM_DATA_SIZE 0x1000
+#define CFG_INIT_RAM_ADDR CFG_OCM_DATA_ADDR /* inside of On Chip SRAM */
+#define CFG_INIT_RAM_END CFG_OCM_DATA_SIZE /* End of On Chip SRAM */
+#define CFG_GBL_DATA_SIZE 64 /* size in bytes reserved for initial data */
+#define CFG_GBL_DATA_OFFSET (CFG_INIT_RAM_END - CFG_GBL_DATA_SIZE)
+#define CFG_INIT_SP_OFFSET CFG_GBL_DATA_OFFSET
+
+/*
+ * Internal Definitions
+ *
+ * Boot Flags
+ */
+#define BOOTFLAG_COLD 0x01 /* Normal Power-On: Boot from FLASH */
+#define BOOTFLAG_WARM 0x02 /* Software reboot */
+
+
+/***********************************************************************
+ * External peripheral base address
+ ***********************************************************************/
+#define CFG_ISA_IO_BASE_ADDRESS 0xE8000000
+
+/***********************************************************************
+ * Last Stage Init
+ ***********************************************************************/
+#define CONFIG_LAST_STAGE_INIT
+/************************************************************
+ * Ethernet Stuff
+ ***********************************************************/
+#define CONFIG_MII 1 /* MII PHY management */
+#define CONFIG_PHY_ADDR 1 /* PHY address */
+#define CONFIG_CS8952_PHY 1 /* its a CS8952 PHY */
+/************************************************************
+ * RTC
+ ***********************************************************/
+#define CONFIG_RTC_MC146818
+#undef CONFIG_WATCHDOG /* watchdog disabled */
+
+/************************************************************
+ * IDE/ATA stuff
+ ************************************************************/
+#define CFG_IDE_MAXBUS 2 /* max. 2 IDE busses */
+#define CFG_IDE_MAXDEVICE (CFG_IDE_MAXBUS*2) /* max. 2 drives per IDE bus */
+
+#define CFG_ATA_BASE_ADDR CFG_ISA_IO_BASE_ADDRESS /* base address */
+#define CFG_ATA_IDE0_OFFSET 0x01F0 /* ide0 offste */
+#define CFG_ATA_IDE1_OFFSET 0x0170 /* ide1 offset */
+#define CFG_ATA_DATA_OFFSET 0 /* data reg offset */
+#define CFG_ATA_REG_OFFSET 0 /* reg offset */
+#define CFG_ATA_ALT_OFFSET 0x200 /* alternate register offset */
+
+#undef CONFIG_IDE_8xx_DIRECT /* no pcmcia interface required */
+#undef CONFIG_IDE_LED /* no led for ide supported */
+#define CONFIG_IDE_RESET /* reset for ide supported... */
+#define CONFIG_IDE_RESET_ROUTINE /* with a special reset function */
+
+/************************************************************
+ * ATAPI support (experimental)
+ ************************************************************/
+#define CONFIG_ATAPI /* enable ATAPI Support */
+
+/************************************************************
+ * SCSI support (experimental) only SYM53C8xx supported
+ ************************************************************/
+#define CONFIG_SCSI_SYM53C8XX
+#define CFG_SCSI_MAX_LUN 8 /* number of supported LUNs */
+#define CFG_SCSI_MAX_SCSI_ID 7 /* maximum SCSI ID (0..6) */
+#define CFG_SCSI_MAX_DEVICE CFG_SCSI_MAX_SCSI_ID * CFG_SCSI_MAX_LUN /* maximum Target devices */
+#define CFG_SCSI_SPIN_UP_TIME 2
+
+/************************************************************
+ * Disk-On-Chip configuration
+ ************************************************************/
+#define CFG_MAX_DOC_DEVICE 1 /* Max number of DOC devices */
+#define CFG_DOC_SHORT_TIMEOUT
+#define CFG_DOC_SUPPORT_2000
+#define CFG_DOC_SUPPORT_MILLENNIUM
+
+/************************************************************
+ * DISK Partition support
+ ************************************************************/
+#define CONFIG_DOS_PARTITION
+#define CONFIG_MAC_PARTITION
+#define CONFIG_ISO_PARTITION /* Experimental */
+
+/************************************************************
+ * Keyboard support
+ ************************************************************/
+#define CONFIG_ISA_KEYBOARD
+
+/************************************************************
+ * Video support
+ ************************************************************/
+#define CONFIG_VIDEO /*To enable video controller support */
+#define CONFIG_VIDEO_CT69000
+#define CONFIG_CFB_CONSOLE
+#define CONFIG_VIDEO_LOGO
+#define CONFIG_CONSOLE_EXTRA_INFO
+#define CONFIG_VGA_AS_SINGLE_DEVICE
+#define CONFIG_VIDEO_SW_CURSOR
+#define CONFIG_VIDEO_ONBOARD /* Video controller is on-board */
+
+/************************************************************
+ * USB support
+ ************************************************************/
+#define CONFIG_USB_UHCI
+#define CONFIG_USB_KEYBOARD
+#define CONFIG_USB_STORAGE
+
+/* Enable needed helper functions */
+#define CFG_DEVICE_DEREGISTER /* needs device_deregister */
+
+/************************************************************
+ * Debug support
+ ************************************************************/
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+#define CONFIG_KGDB_BAUDRATE 230400 /* speed to run kgdb serial port */
+#define CONFIG_KGDB_SER_INDEX 2 /* which serial port to use */
+#endif
+
+/************************************************************
+ * Ident
+ ************************************************************/
+#define VERSION_TAG "released"
+#define CONFIG_IDENT_STRING "\n(c) 2002 by MPL AG Switzerland, MEV-10066-001 " VERSION_TAG
+
+
+#endif /* __CONFIG_H */
--- /dev/null
+/*
+ * (C) Copyright 2002
+ * Wolfgang Grandegger, DENX Software Engineering, wg@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
+ */
+
+/* ------------------------------------------------------------------------- */
+
+/*
+ * board/config.h - configuration options, board specific
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+/*
+ * High Level Configuration Options
+ * (easy to change)
+ */
+
+#define CONFIG_MPC824X 1
+#define CONFIG_MPC8240 1
+#define CONFIG_PN62 1
+
+#define CONFIG_CONS_INDEX 1
+
+
+#define REMOVE_COMMANDS ( CFG_CMD_AUTOSCRIPT | \
+ CFG_CMD_LOADS | \
+ CFG_CMD_ENV | \
+ CFG_CMD_FLASH )
+
+#define CONFIG_COMMANDS ( (CONFIG_CMD_DFL & ~REMOVE_COMMANDS) |\
+ CFG_CMD_PCI |\
+ CFG_CMD_BSP)
+
+#define CONFIG_BAUDRATE 19200 /* console baudrate */
+
+#define CONFIG_BOOTDELAY 1 /* autoboot after n seconds */
+
+#define CONFIG_CLOCKS_IN_MHZ 1 /* clocks passsed to Linux in MHz */
+
+#define CONFIG_SERVERIP 10.0.0.201
+#define CONFIG_IPADDR 10.0.0.200
+#define CONFIG_ROOTPATH /opt/eldk/ppc_82xx
+#define CONFIG_NETMASK 255.255.255.0
+#undef CONFIG_BOOTARGS
+#if 0
+/* Boot Linux with NFS root filesystem */
+#define CONFIG_BOOTCOMMAND \
+ "setenv verify y;" \
+ "setenv bootargs console=ttyS0,19200 mem=31M quiet " \
+ "root=/dev/nfs rw nfsroot=$(serverip):$(rootpath) " \
+ "ip=$(ipaddr):$(serverip)::$(netmask):pn62:eth0:off;" \
+ "loadp 100000; bootm"
+ /* "tftpboot 100000 pImage; bootm" */
+#else
+/* Boot Linux with RAMdisk based filesystem (initrd, BusyBox) */
+#define CONFIG_BOOTCOMMAND \
+ "setenv verify n;" \
+ "setenv bootargs console=ttyS0,19200 mem=31M quiet " \
+ "root=/dev/ram rw " \
+ "ip=$(ipaddr):$(serverip)::$(netmask):pn62:eth0:off;" \
+ "loadp 200000; bootm"
+#endif
+
+/* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */
+#include <cmd_confdefs.h>
+
+
+/*
+ * Miscellaneous configurable options
+ */
+#define CFG_LONGHELP 1 /* undef to save memory */
+#define CFG_PROMPT "=> " /* Monitor Command Prompt */
+#define CFG_CBSIZE 256 /* Console I/O Buffer Size */
+#define CFG_PBSIZE (CFG_CBSIZE+sizeof(CFG_PROMPT)+16) /* Print Buffer Size */
+#define CFG_MAXARGS 16 /* max number of command args */
+#define CFG_BARGSIZE CFG_CBSIZE /* Boot Argument Buffer Size */
+#define CFG_LOAD_ADDR 0x00100000 /* default load address */
+#define CFG_HZ 1000 /* decrementer freq: 1 ms ticks */
+
+#define CONFIG_PRAM 1024 /* reserve 1 MB protected RAM */
+
+#define CONFIG_MISC_INIT_R 1 /* call misc_init_r() on init */
+
+#define CONFIG_SHOW_BOOT_PROGRESS 1 /* Show boot progress on LEDs */
+
+/*
+ * PCI stuff
+ */
+#define CONFIG_PCI /* include pci support */
+#define CONFIG_PCI_PNP /* we need Plug 'n Play */
+#if 0
+#define CONFIG_PCI_SCAN_SHOW /* show PCI auto-scan at boot */
+#endif
+
+/*
+ * Networking stuff
+ */
+#define CONFIG_NET_MULTI /* Multi ethernet cards support */
+
+#define CONFIG_PCNET /* there are 2 AMD PCnet 79C973 */
+#define CONFIG_PCNET_79C973
+
+#define _IO_BASE 0xfe000000 /* points to PCI I/O space */
+
+
+/*
+ * Start addresses for the final memory configuration
+ * (Set up by the startup code)
+ * Please note that CFG_SDRAM_BASE _must_ start at 0
+ */
+#define CFG_SDRAM_BASE 0x00000000
+#define CFG_MAX_RAM_SIZE 0x10000000
+
+#define CFG_RESET_ADDRESS 0xfff00100
+
+#undef CFG_RAMBOOT
+#define CFG_MONITOR_LEN 0x00030000
+#define CFG_MONITOR_BASE TEXT_BASE
+
+/*#define CFG_GBL_DATA_SIZE 256*/
+#define CFG_GBL_DATA_SIZE 128
+
+#define CFG_INIT_RAM_ADDR 0x40000000
+#define CFG_INIT_RAM_END 0x1000
+#define CFG_GBL_DATA_OFFSET (CFG_INIT_RAM_END - CFG_GBL_DATA_SIZE)
+
+
+#define CFG_NO_FLASH 1 /* There is no FLASH memory */
+
+#define CFG_ENV_IS_NOWHERE 1 /* Store ENV in memory only */
+#define CFG_ENV_OFFSET 0x00004000 /* Offset of Environment Sector */
+#define CFG_ENV_SIZE 0x00002000 /* Total Size of Environment Sector */
+
+#define CFG_MALLOC_LEN (512 << 10) /* Reserve 512 kB for malloc() */
+
+#define CFG_MEMTEST_START 0x00004000 /* memtest works on */
+#define CFG_MEMTEST_END 0x01f00000 /* 0 ... 32 MB in DRAM */
+
+/*
+ * Serial port configuration
+ */
+#define CFG_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 }
+
+#define CFG_NS16550
+#define CFG_NS16550_SERIAL
+
+#define CFG_NS16550_REG_SIZE 1
+
+#define CFG_NS16550_CLK 1843200
+
+#define CFG_NS16550_COM1 0xff800008
+#define CFG_NS16550_COM2 0xff800000
+
+/*
+ * Low Level Configuration Settings
+ * (address mappings, register initial values, etc.)
+ * You should know what you are doing if you make changes here.
+ */
+
+#define CONFIG_SYS_CLK_FREQ 33333333 /* external frequency to pll */
+#define CONFIG_PLL_PCI_TO_MEM_MULTIPLIER 3
+
+#define CFG_EUMB_ADDR 0xFCE00000
+
+/* MCCR1 */
+#define CFG_ROMNAL 3 /* rom/flash next access time */
+#define CFG_ROMFAL 7 /* rom/flash access time */
+
+/* MCCR2 */
+#define CFG_ASRISE 6 /* ASRISE in clocks */
+#define CFG_ASFALL 12 /* ASFALL in clocks */
+#define CFG_REFINT 5600 /* REFINT in clocks */
+
+/* MCCR3 */
+#define CFG_BSTOPRE 0x3cf /* Burst To Precharge */
+#define CFG_REFREC 2 /* Refresh to activate interval */
+#define CFG_RDLAT 3 /* data latency from read command */
+
+/* MCCR4 */
+#define CFG_PRETOACT 1 /* Precharge to activate interval */
+#define CFG_ACTTOPRE 3 /* Activate to Precharge interval */
+#define CFG_ACTORW 2 /* Activate to R/W */
+#define CFG_SDMODE_CAS_LAT 2 /* SDMODE CAS latency */
+#define CFG_SDMODE_WRAP 0 /* SDMODE Wrap type */
+#define CFG_SDMODE_BURSTLEN 2 /* SDMODE Burst length 2=4, 3=8 */
+#define CFG_REGISTERD_TYPE_BUFFER 1
+
+/* Memory bank settings:
+ *
+ * only bits 20-29 are actually used from these vales to set the
+ * start/qend address the upper two bits will be 0, and the lower 20
+ * bits will be set to 0x00000 for a start address, or 0xfffff for an
+ * end address
+ */
+#define CFG_BANK0_START 0x00000000
+#define CFG_BANK0_END (CFG_MAX_RAM_SIZE - 1)
+#define CFG_BANK0_ENABLE 1
+#define CFG_BANK1_START 0x00000000
+#define CFG_BANK1_END 0x00000000
+#define CFG_BANK1_ENABLE 0
+#define CFG_BANK2_START 0x00000000
+#define CFG_BANK2_END 0x00000000
+#define CFG_BANK2_ENABLE 0
+#define CFG_BANK3_START 0x00000000
+#define CFG_BANK3_END 0x00000000
+#define CFG_BANK3_ENABLE 0
+#define CFG_BANK4_START 0x00000000
+#define CFG_BANK4_END 0x00000000
+#define CFG_BANK4_ENABLE 0
+#define CFG_BANK5_START 0x00000000
+#define CFG_BANK5_END 0x00000000
+#define CFG_BANK5_ENABLE 0
+#define CFG_BANK6_START 0x00000000
+#define CFG_BANK6_END 0x00000000
+#define CFG_BANK6_ENABLE 0
+#define CFG_BANK7_START 0x00000000
+#define CFG_BANK7_END 0x00000000
+#define CFG_BANK7_ENABLE 0
+
+/*
+ * Memory bank enable bitmask, specifying which of the banks defined above
+ * are actually present. MSB is for bank #7, LSB is for bank #0.
+ */
+#define CFG_BANK_ENABLE 0x01
+
+#define CFG_ODCR 0xff /* configures line driver impedances, */
+ /* see 8240 book for bit definitions */
+#define CFG_PGMAX 0x32 /* how long the 8240 retains the */
+ /* currently accessed page in memory */
+ /* see 8240 book for details */
+
+/* SDRAM 0 - 256MB */
+#define CFG_IBAT0L (CFG_SDRAM_BASE | BATL_PP_10 | BATL_MEMCOHERENCE)
+#define CFG_IBAT0U (CFG_SDRAM_BASE | BATU_BL_256M | BATU_VS | BATU_VP)
+
+#define CFG_IBAT1L (CFG_INIT_RAM_ADDR | BATL_PP_10 | BATL_MEMCOHERENCE)
+#define CFG_IBAT1U (CFG_INIT_RAM_ADDR | BATU_BL_128K | BATU_VS | BATU_VP)
+
+/* PCI memory space */
+#define CFG_IBAT2L (0x80000000 | BATL_PP_10 | BATL_CACHEINHIBIT)
+#define CFG_IBAT2U (0x80000000 | BATU_BL_256M | BATU_VS | BATU_VP)
+
+/* Config addrs, etc */
+#define CFG_IBAT3L (0xF0000000 | BATL_PP_10 | BATL_CACHEINHIBIT)
+#define CFG_IBAT3U (0xF0000000 | BATU_BL_256M | BATU_VS | BATU_VP)
+
+#define CFG_DBAT0L CFG_IBAT0L
+#define CFG_DBAT0U CFG_IBAT0U
+#define CFG_DBAT1L CFG_IBAT1L
+#define CFG_DBAT1U CFG_IBAT1U
+#define CFG_DBAT2L CFG_IBAT2L
+#define CFG_DBAT2U CFG_IBAT2U
+#define CFG_DBAT3L CFG_IBAT3L
+#define CFG_DBAT3U CFG_IBAT3U
+
+/*
+ * For booting Linux, the board info and command line data
+ * have to be in the first 8 MB of memory, since this is
+ * the maximum mapped by the Linux kernel during initialization.
+ */
+#define CFG_BOOTMAPSZ (8 << 20) /* Initial Memory map for Linux */
+
+/*
+ * Cache Configuration
+ */
+#define CFG_CACHELINE_SIZE 32 /* For MPC8240 CPU */
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+# define CFG_CACHELINE_SHIFT 5 /* log base 2 of the above value */
+#endif
+
+
+/*
+ * Internal Definitions
+ *
+ * Boot Flags
+ */
+#define BOOTFLAG_COLD 0x01 /* Normal Power-On: Boot from FLASH */
+#define BOOTFLAG_WARM 0x02 /* Software reboot */
+
+
+#endif /* __CONFIG_H */
--- /dev/null
+/*
+ * (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
+ */
+
+/* ------------------------------------------------------------------------- */
+
+/*
+ * board/config.h - configuration options, board specific
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+/*
+ * High Level Configuration Options
+ * (easy to change)
+ */
+
+#define CONFIG_MPC824X 1
+#define CONFIG_MPC8240 1
+#define CONFIG_SANDPOINT 1
+
+#if 0
+#define USE_DINK32 1
+#else
+#undef USE_DINK32
+#endif
+
+#define CONFIG_CONS_INDEX 1
+#define CONFIG_BAUDRATE 115200
+#define CONFIG_DRAM_SPEED 100 /* MHz */
+
+#define CONFIG_COMMANDS ( (CONFIG_CMD_DFL & ~CFG_CMD_AUTOSCRIPT) | \
+ CFG_CMD_ELF | \
+ CFG_CMD_I2C | \
+ CFG_CMD_SDRAM | \
+ CFG_CMD_EEPROM | \
+ CFG_CMD_PCI )
+
+/* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */
+#include <cmd_confdefs.h>
+
+
+/*
+ * Miscellaneous configurable options
+ */
+#define CFG_LONGHELP 1 /* undef to save memory */
+#define CFG_PROMPT "=> " /* Monitor Command Prompt */
+#define CFG_CBSIZE 256 /* Console I/O Buffer Size */
+#define CFG_PBSIZE (CFG_CBSIZE+sizeof(CFG_PROMPT)+16) /* Print Buffer Size */
+#define CFG_MAXARGS 16 /* max number of command args */
+#define CFG_BARGSIZE CFG_CBSIZE /* Boot Argument Buffer Size */
+#define CFG_LOAD_ADDR 0x00100000 /* default load address */
+#define CFG_HZ 1000 /* decrementer freq: 1 ms ticks */
+
+/*-----------------------------------------------------------------------
+ * PCI stuff
+ *-----------------------------------------------------------------------
+ */
+#define CONFIG_PCI /* include pci support */
+#undef CONFIG_PCI_PNP
+
+#define CONFIG_NET_MULTI /* Multi ethernet cards support */
+
+#define CONFIG_EEPRO100
+
+#define PCI_ENET0_IOADDR 0x80000000
+#define PCI_ENET0_MEMADDR 0x80000000
+#define PCI_ENET1_IOADDR 0x81000000
+#define PCI_ENET1_MEMADDR 0x81000000
+
+
+/*-----------------------------------------------------------------------
+ * Start addresses for the final memory configuration
+ * (Set up by the startup code)
+ * Please note that CFG_SDRAM_BASE _must_ start at 0
+ */
+#define CFG_SDRAM_BASE 0x00000000
+#define CFG_MAX_RAM_SIZE 0x10000000
+
+#define CFG_RESET_ADDRESS 0xFFF00100
+
+#if defined (USE_DINK32)
+#define CFG_MONITOR_LEN 0x00030000
+#define CFG_MONITOR_BASE 0x00090000
+#define CFG_RAMBOOT 1
+#define CFG_INIT_RAM_ADDR (CFG_MONITOR_BASE + CFG_MONITOR_LEN)
+#define CFG_INIT_RAM_END 0x10000
+#define CFG_GBL_DATA_SIZE 256 /* size in bytes reserved for initial data */
+#define CFG_GBL_DATA_OFFSET (CFG_INIT_RAM_END - CFG_GBL_DATA_SIZE)
+#define CFG_INIT_SP_OFFSET CFG_GBL_DATA_OFFSET
+#else
+#undef CFG_RAMBOOT
+#define CFG_MONITOR_LEN 0x00030000
+#define CFG_MONITOR_BASE TEXT_BASE
+
+/*#define CFG_GBL_DATA_SIZE 256*/
+#define CFG_GBL_DATA_SIZE 128
+
+#define CFG_INIT_RAM_ADDR 0x40000000
+#define CFG_INIT_RAM_END 0x1000
+#define CFG_GBL_DATA_OFFSET (CFG_INIT_RAM_END - CFG_GBL_DATA_SIZE)
+
+#endif
+
+#define CFG_FLASH_BASE 0xFFF00000
+#if 0
+#define CFG_FLASH_SIZE (512 * 1024) /* sandpoint has tiny eeprom */
+#else
+#define CFG_FLASH_SIZE (1024 * 1024) /* Unity has onboard 1MByte flash */
+#endif
+#define CFG_ENV_IS_IN_FLASH 1
+#define CFG_ENV_OFFSET 0x00004000 /* Offset of Environment Sector */
+#define CFG_ENV_SIZE 0x00002000 /* Total Size of Environment Sector */
+
+#define CFG_MALLOC_LEN (512 << 10) /* Reserve 512 kB for malloc() */
+
+#define CFG_MEMTEST_START 0x00000000 /* memtest works on */
+#define CFG_MEMTEST_END 0x04000000 /* 0 ... 32 MB in DRAM */
+
+#define CFG_EUMB_ADDR 0xFC000000
+
+#define CFG_ISA_MEM 0xFD000000
+#define CFG_ISA_IO 0xFE000000
+
+#define CFG_FLASH_RANGE_BASE 0xFF000000 /* flash memory address range */
+#define CFG_FLASH_RANGE_SIZE 0x01000000
+#define FLASH_BASE0_PRELIM 0xFFF00000 /* sandpoint flash */
+#define FLASH_BASE1_PRELIM 0xFF000000 /* PMC onboard flash */
+
+/*
+ * select i2c support configuration
+ *
+ * Supported configurations are {none, software, hardware} drivers.
+ * If the software driver is chosen, there are some additional
+ * configuration items that the driver uses to drive the port pins.
+ */
+#define CONFIG_HARD_I2C 1 /* To enable I2C support */
+#undef CONFIG_SOFT_I2C /* I2C bit-banged */
+#define CFG_I2C_SPEED 400000 /* I2C speed and slave address */
+#define CFG_I2C_SLAVE 0x7F
+
+#ifdef CONFIG_SOFT_I2C
+#error "Soft I2C is not configured properly. Please review!"
+#define I2C_PORT 3 /* Port A=0, B=1, C=2, D=3 */
+#define I2C_ACTIVE (iop->pdir |= 0x00010000)
+#define I2C_TRISTATE (iop->pdir &= ~0x00010000)
+#define I2C_READ ((iop->pdat & 0x00010000) != 0)
+#define I2C_SDA(bit) if(bit) iop->pdat |= 0x00010000; \
+ else iop->pdat &= ~0x00010000
+#define I2C_SCL(bit) if(bit) iop->pdat |= 0x00020000; \
+ else iop->pdat &= ~0x00020000
+#define I2C_DELAY udelay(5) /* 1/4 I2C clock duration */
+#endif /* CONFIG_SOFT_I2C */
+
+
+#define CFG_I2C_EEPROM_ADDR 0x57 /* EEPROM IS24C02 */
+#define CFG_I2C_EEPROM_ADDR_LEN 1 /* Bytes of address */
+#define CFG_EEPROM_PAGE_WRITE_BITS 3 /* write page size */
+#define CFG_EEPROM_PAGE_WRITE_DELAY_MS 10 /* takes up to 10 msec */
+
+
+#define CFG_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 }
+#define CFG_FLASH_BANKS { FLASH_BASE0_PRELIM , FLASH_BASE1_PRELIM }
+
+/*-----------------------------------------------------------------------
+ * Definitions for initial stack pointer and data area (in DPRAM)
+ */
+
+
+#define CFG_WINBOND_83C553 1 /*has a winbond bridge */
+#define CFG_USE_WINBOND_IDE 0 /*use winbond 83c553 internal IDE ctrlr */
+#define CFG_WINBOND_ISA_CFG_ADDR 0x80005800 /*pci-isa bridge config addr */
+#define CFG_WINBOND_IDE_CFG_ADDR 0x80005900 /*ide config addr */
+
+#define CFG_IDE_MAXBUS 2 /* max. 2 IDE busses */
+#define CFG_IDE_MAXDEVICE (CFG_IDE_MAXBUS*2) /* max. 2 drives per IDE bus */
+
+/*
+ * NS87308 Configuration
+ */
+#define CFG_NS87308 /* Nat Semi super-io controller on ISA bus */
+
+#define CFG_NS87308_BADDR_10 1
+
+#define CFG_NS87308_DEVS ( CFG_NS87308_UART1 | \
+ CFG_NS87308_UART2 | \
+ CFG_NS87308_POWRMAN | \
+ CFG_NS87308_RTC_APC )
+
+#undef CFG_NS87308_PS2MOD
+
+#define CFG_NS87308_CS0_BASE 0x0076
+#define CFG_NS87308_CS0_CONF 0x30
+#define CFG_NS87308_CS1_BASE 0x0075
+#define CFG_NS87308_CS1_CONF 0x30
+#define CFG_NS87308_CS2_BASE 0x0074
+#define CFG_NS87308_CS2_CONF 0x30
+
+/*
+ * NS16550 Configuration
+ */
+#define CFG_NS16550
+#define CFG_NS16550_SERIAL
+
+#define CFG_NS16550_REG_SIZE 1
+
+#define CFG_NS16550_CLK 1843200
+
+#define CFG_NS16550_COM1 (CFG_ISA_IO + CFG_NS87308_UART1_BASE)
+#define CFG_NS16550_COM2 (CFG_ISA_IO + CFG_NS87308_UART2_BASE)
+
+/*
+ * Low Level Configuration Settings
+ * (address mappings, register initial values, etc.)
+ * You should know what you are doing if you make changes here.
+ */
+
+#define CONFIG_SYS_CLK_FREQ 33000000 /* external frequency to pll */
+#define CONFIG_PLL_PCI_TO_MEM_MULTIPLIER 2
+
+#define CFG_ROMNAL 7 /*rom/flash next access time */
+#define CFG_ROMFAL 11 /*rom/flash access time */
+
+#define CFG_REFINT 430 /* no of clock cycles between CBR refresh cycles */
+
+/* the following are for SDRAM only*/
+#define CFG_BSTOPRE 121 /* Burst To Precharge, sets open page interval */
+#define CFG_REFREC 8 /* Refresh to activate interval */
+#define CFG_RDLAT 4 /* data latency from read command */
+#define CFG_PRETOACT 3 /* Precharge to activate interval */
+#define CFG_ACTTOPRE 5 /* Activate to Precharge interval */
+#define CFG_ACTORW 3 /* Activate to R/W */
+#define CFG_SDMODE_CAS_LAT 3 /* SDMODE CAS latency */
+#define CFG_SDMODE_WRAP 0 /* SDMODE wrap type */
+#define CFG_SDMODE_BURSTLEN 2 /* SDMODE Burst length 2=4, 3=8 */
+
+#define CFG_REGISTERD_TYPE_BUFFER 1
+
+/* memory bank settings*/
+/*
+ * only bits 20-29 are actually used from these vales to set the
+ * start/end address the upper two bits will be 0, and the lower 20
+ * bits will be set to 0x00000 for a start address, or 0xfffff for an
+ * end address
+ */
+#define CFG_BANK0_START 0x00000000
+#define CFG_BANK0_END (CFG_MAX_RAM_SIZE - 1)
+#define CFG_BANK0_ENABLE 1
+#define CFG_BANK1_START 0x3ff00000
+#define CFG_BANK1_END 0x3fffffff
+#define CFG_BANK1_ENABLE 0
+#define CFG_BANK2_START 0x3ff00000
+#define CFG_BANK2_END 0x3fffffff
+#define CFG_BANK2_ENABLE 0
+#define CFG_BANK3_START 0x3ff00000
+#define CFG_BANK3_END 0x3fffffff
+#define CFG_BANK3_ENABLE 0
+#define CFG_BANK4_START 0x00000000
+#define CFG_BANK4_END 0x00000000
+#define CFG_BANK4_ENABLE 0
+#define CFG_BANK5_START 0x00000000
+#define CFG_BANK5_END 0x00000000
+#define CFG_BANK5_ENABLE 0
+#define CFG_BANK6_START 0x00000000
+#define CFG_BANK6_END 0x00000000
+#define CFG_BANK6_ENABLE 0
+#define CFG_BANK7_START 0x00000000
+#define CFG_BANK7_END 0x00000000
+#define CFG_BANK7_ENABLE 0
+/*
+ * Memory bank enable bitmask, specifying which of the banks defined above
+ are actually present. MSB is for bank #7, LSB is for bank #0.
+ */
+#define CFG_BANK_ENABLE 0x01
+
+#define CFG_ODCR 0xff /* configures line driver impedances, */
+ /* see 8240 book for bit definitions */
+#define CFG_PGMAX 0x32 /* how long the 8240 retains the */
+ /* currently accessed page in memory */
+ /* see 8240 book for details */
+
+/* SDRAM 0 - 256MB */
+#define CFG_IBAT0L (CFG_SDRAM_BASE | BATL_PP_10 | BATL_MEMCOHERENCE)
+#define CFG_IBAT0U (CFG_SDRAM_BASE | BATU_BL_256M | BATU_VS | BATU_VP)
+
+/* stack in DCACHE @ 1GB (no backing mem) */
+#if defined(USE_DINK32)
+#define CFG_IBAT1L (0x40000000 | BATL_PP_00 )
+#define CFG_IBAT1U (0x40000000 | BATU_BL_128K )
+#else
+#define CFG_IBAT1L (CFG_INIT_RAM_ADDR | BATL_PP_10 | BATL_MEMCOHERENCE)
+#define CFG_IBAT1U (CFG_INIT_RAM_ADDR | BATU_BL_128K | BATU_VS | BATU_VP)
+#endif
+
+/* PCI memory */
+#define CFG_IBAT2L (0x80000000 | BATL_PP_10 | BATL_CACHEINHIBIT)
+#define CFG_IBAT2U (0x80000000 | BATU_BL_256M | BATU_VS | BATU_VP)
+
+/* Flash, config addrs, etc */
+#define CFG_IBAT3L (0xF0000000 | BATL_PP_10 | BATL_CACHEINHIBIT)
+#define CFG_IBAT3U (0xF0000000 | BATU_BL_256M | BATU_VS | BATU_VP)
+
+#define CFG_DBAT0L CFG_IBAT0L
+#define CFG_DBAT0U CFG_IBAT0U
+#define CFG_DBAT1L CFG_IBAT1L
+#define CFG_DBAT1U CFG_IBAT1U
+#define CFG_DBAT2L CFG_IBAT2L
+#define CFG_DBAT2U CFG_IBAT2U
+#define CFG_DBAT3L CFG_IBAT3L
+#define CFG_DBAT3U CFG_IBAT3U
+
+/*
+ * For booting Linux, the board info and command line data
+ * have to be in the first 8 MB of memory, since this is
+ * the maximum mapped by the Linux kernel during initialization.
+ */
+#define CFG_BOOTMAPSZ (8 << 20) /* Initial Memory map for Linux */
+/*-----------------------------------------------------------------------
+ * FLASH organization
+ */
+#define CFG_MAX_FLASH_BANKS 2 /* max number of memory banks */
+#define CFG_MAX_FLASH_SECT 20 /* max number of sectors on one chip */
+
+#define CFG_FLASH_ERASE_TOUT 120000 /* Timeout for Flash Erase (in ms) */
+#define CFG_FLASH_WRITE_TOUT 500 /* Timeout for Flash Write (in ms) */
+
+/*-----------------------------------------------------------------------
+ * Cache Configuration
+ */
+#define CFG_CACHELINE_SIZE 32 /* For MPC8240 CPU */
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+# define CFG_CACHELINE_SHIFT 5 /* log base 2 of the above value */
+#endif
+
+
+/*
+ * Internal Definitions
+ *
+ * Boot Flags
+ */
+#define BOOTFLAG_COLD 0x01 /* Normal Power-On: Boot from FLASH */
+#define BOOTFLAG_WARM 0x02 /* Software reboot */
+
+
+/* values according to the manual */
+
+#define CONFIG_DRAM_50MHZ 1
+#define CONFIG_SDRAM_50MHZ
+
+#undef NR_8259_INTS
+#define NR_8259_INTS 1
+
+
+#define CONFIG_DISK_SPINUP_TIME 1000000
+
+
+#endif /* __CONFIG_H */
--- /dev/null
+/*
+ * (C) Copyright 2001, 2002
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/* ------------------------------------------------------------------------- */
+
+/*
+ * board/config.h - configuration options, board specific
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+/*
+ * High Level Configuration Options
+ * (easy to change)
+ */
+
+#define CONFIG_MPC824X 1
+#define CONFIG_MPC8245 1
+#define CONFIG_SANDPOINT 1
+
+#if 0
+#define USE_DINK32 1
+#else
+#undef USE_DINK32
+#endif
+
+#define CONFIG_CONS_INDEX 3 /* set to '3' for on-chip DUART */
+#define CONFIG_BAUDRATE 9600
+#define CONFIG_DRAM_SPEED 100 /* MHz */
+
+#define CONFIG_COMMANDS ( CONFIG_CMD_DFL | \
+ CFG_CMD_ELF | \
+ CFG_CMD_I2C | \
+ CFG_CMD_EEPROM | \
+ CFG_CMD_PCI )
+
+/* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */
+#include <cmd_confdefs.h>
+
+
+/*
+ * Miscellaneous configurable options
+ */
+#define CFG_LONGHELP 1 /* undef to save memory */
+#define CFG_PROMPT "=> " /* Monitor Command Prompt */
+#define CFG_CBSIZE 256 /* Console I/O Buffer Size */
+#define CFG_PBSIZE (CFG_CBSIZE+sizeof(CFG_PROMPT)+16) /* Print Buffer Size */
+#define CFG_MAXARGS 16 /* max number of command args */
+#define CFG_BARGSIZE CFG_CBSIZE /* Boot Argument Buffer Size */
+#define CFG_LOAD_ADDR 0x00100000 /* default load address */
+#define CFG_HZ 1000 /* decrementer freq: 1 ms ticks */
+
+/*-----------------------------------------------------------------------
+ * PCI stuff
+ *-----------------------------------------------------------------------
+ */
+#define CONFIG_PCI /* include pci support */
+#undef CONFIG_PCI_PNP
+
+#define CONFIG_NET_MULTI /* Multi ethernet cards support */
+
+#define CONFIG_EEPRO100
+#define CONFIG_NATSEMI
+#define CONFIG_NS8382X
+
+#define PCI_ENET0_IOADDR 0x80000000
+#define PCI_ENET0_MEMADDR 0x80000000
+#define PCI_ENET1_IOADDR 0x81000000
+#define PCI_ENET1_MEMADDR 0x81000000
+
+
+/*-----------------------------------------------------------------------
+ * Start addresses for the final memory configuration
+ * (Set up by the startup code)
+ * Please note that CFG_SDRAM_BASE _must_ start at 0
+ */
+#define CFG_SDRAM_BASE 0x00000000
+#define CFG_MAX_RAM_SIZE 0x10000000
+
+#define CFG_RESET_ADDRESS 0xFFF00100
+
+#if defined (USE_DINK32)
+#define CFG_MONITOR_LEN 0x00030000
+#define CFG_MONITOR_BASE 0x00090000
+#define CFG_RAMBOOT 1
+#define CFG_INIT_RAM_ADDR (CFG_MONITOR_BASE + CFG_MONITOR_LEN)
+#define CFG_INIT_RAM_END 0x10000
+#define CFG_GBL_DATA_SIZE 256 /* size in bytes reserved for initial data */
+#define CFG_GBL_DATA_OFFSET (CFG_INIT_RAM_END - CFG_GBL_DATA_SIZE)
+#define CFG_INIT_SP_OFFSET CFG_GBL_DATA_OFFSET
+#else
+#undef CFG_RAMBOOT
+#define CFG_MONITOR_LEN 0x00030000
+#define CFG_MONITOR_BASE TEXT_BASE
+
+/*#define CFG_GBL_DATA_SIZE 256*/
+#define CFG_GBL_DATA_SIZE 128
+
+#define CFG_INIT_RAM_ADDR 0x40000000
+#define CFG_INIT_RAM_END 0x1000
+#define CFG_GBL_DATA_OFFSET (CFG_INIT_RAM_END - CFG_GBL_DATA_SIZE)
+
+#endif
+
+#define CFG_FLASH_BASE 0xFFF00000
+#if 0
+#define CFG_FLASH_SIZE (512 * 1024) /* sandpoint has tiny eeprom */
+#else
+#define CFG_FLASH_SIZE (1024 * 1024) /* Unity has onboard 1MByte flash */
+#endif
+#define CFG_ENV_IS_IN_FLASH 1
+#define CFG_ENV_OFFSET 0x00004000 /* Offset of Environment Sector */
+#define CFG_ENV_SIZE 0x00002000 /* Total Size of Environment Sector */
+
+#define CFG_MALLOC_LEN (512 << 10) /* Reserve 512 kB for malloc() */
+
+#define CFG_MEMTEST_START 0x00000000 /* memtest works on */
+#define CFG_MEMTEST_END 0x04000000 /* 0 ... 32 MB in DRAM */
+
+#define CFG_EUMB_ADDR 0xFC000000
+
+#define CFG_ISA_MEM 0xFD000000
+#define CFG_ISA_IO 0xFE000000
+
+#define CFG_FLASH_RANGE_BASE 0xFF000000 /* flash memory address range */
+#define CFG_FLASH_RANGE_SIZE 0x01000000
+#define FLASH_BASE0_PRELIM 0xFFF00000 /* sandpoint flash */
+#define FLASH_BASE1_PRELIM 0xFF000000 /* PMC onboard flash */
+
+/*
+ * select i2c support configuration
+ *
+ * Supported configurations are {none, software, hardware} drivers.
+ * If the software driver is chosen, there are some additional
+ * configuration items that the driver uses to drive the port pins.
+ */
+#define CONFIG_HARD_I2C 1 /* To enable I2C support */
+#undef CONFIG_SOFT_I2C /* I2C bit-banged */
+#define CFG_I2C_SPEED 400000 /* I2C speed and slave address */
+#define CFG_I2C_SLAVE 0x7F
+
+#ifdef CONFIG_SOFT_I2C
+#error "Soft I2C is not configured properly. Please review!"
+#define I2C_PORT 3 /* Port A=0, B=1, C=2, D=3 */
+#define I2C_ACTIVE (iop->pdir |= 0x00010000)
+#define I2C_TRISTATE (iop->pdir &= ~0x00010000)
+#define I2C_READ ((iop->pdat & 0x00010000) != 0)
+#define I2C_SDA(bit) if(bit) iop->pdat |= 0x00010000; \
+ else iop->pdat &= ~0x00010000
+#define I2C_SCL(bit) if(bit) iop->pdat |= 0x00020000; \
+ else iop->pdat &= ~0x00020000
+#define I2C_DELAY udelay(5) /* 1/4 I2C clock duration */
+#endif /* CONFIG_SOFT_I2C */
+
+#define CFG_I2C_EEPROM_ADDR 0x57 /* EEPROM IS24C02 */
+#define CFG_I2C_EEPROM_ADDR_LEN 1 /* Bytes of address */
+#define CFG_EEPROM_PAGE_WRITE_BITS 3
+#define CFG_EEPROM_PAGE_WRITE_DELAY_MS 10 /* and takes up to 10 msec */
+
+#define CFG_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 }
+#define CFG_FLASH_BANKS { FLASH_BASE0_PRELIM , FLASH_BASE1_PRELIM }
+
+/*-----------------------------------------------------------------------
+ * Definitions for initial stack pointer and data area (in DPRAM)
+ */
+
+
+#define CFG_WINBOND_83C553 1 /*has a winbond bridge */
+#define CFG_USE_WINBOND_IDE 0 /*use winbond 83c553 internal IDE ctrlr */
+#define CFG_WINBOND_ISA_CFG_ADDR 0x80005800 /*pci-isa bridge config addr */
+#define CFG_WINBOND_IDE_CFG_ADDR 0x80005900 /*ide config addr */
+
+#define CFG_IDE_MAXBUS 2 /* max. 2 IDE busses */
+#define CFG_IDE_MAXDEVICE (CFG_IDE_MAXBUS*2) /* max. 2 drives per IDE bus */
+
+/*
+ * NS87308 Configuration
+ */
+#define CFG_NS87308 /* Nat Semi super-io controller on ISA bus */
+
+#define CFG_NS87308_BADDR_10 1
+
+#define CFG_NS87308_DEVS ( CFG_NS87308_UART1 | \
+ CFG_NS87308_UART2 | \
+ CFG_NS87308_POWRMAN | \
+ CFG_NS87308_RTC_APC )
+
+#undef CFG_NS87308_PS2MOD
+
+#define CFG_NS87308_CS0_BASE 0x0076
+#define CFG_NS87308_CS0_CONF 0x30
+#define CFG_NS87308_CS1_BASE 0x0075
+#define CFG_NS87308_CS1_CONF 0x30
+#define CFG_NS87308_CS2_BASE 0x0074
+#define CFG_NS87308_CS2_CONF 0x30
+
+/*
+ * NS16550 Configuration
+ */
+#define CFG_NS16550
+#define CFG_NS16550_SERIAL
+
+#define CFG_NS16550_REG_SIZE 1
+
+#define CFG_NS16550_CLK 1843200
+
+#define CFG_NS16550_COM1 (CFG_ISA_IO + CFG_NS87308_UART1_BASE)
+#define CFG_NS16550_COM2 (CFG_ISA_IO + CFG_NS87308_UART2_BASE)
+#define CFG_NS16550_COM3 (CFG_EUMB_ADDR + 0x4500)
+#define CFG_NS16550_COM4 (CFG_EUMB_ADDR + 0x4600)
+
+/*
+ * Low Level Configuration Settings
+ * (address mappings, register initial values, etc.)
+ * You should know what you are doing if you make changes here.
+ */
+
+#define CONFIG_SYS_CLK_FREQ 33333333 /* external frequency to pll */
+
+#define CFG_ROMNAL 7 /*rom/flash next access time */
+#define CFG_ROMFAL 11 /*rom/flash access time */
+
+#define CFG_REFINT 430 /* no of clock cycles between CBR refresh cycles */
+
+/* the following are for SDRAM only*/
+#define CFG_BSTOPRE 121 /* Burst To Precharge, sets open page interval */
+#define CFG_REFREC 8 /* Refresh to activate interval */
+#define CFG_RDLAT 4 /* data latency from read command */
+#define CFG_PRETOACT 3 /* Precharge to activate interval */
+#define CFG_ACTTOPRE 5 /* Activate to Precharge interval */
+#define CFG_ACTORW 3 /* Activate to R/W */
+#define CFG_SDMODE_CAS_LAT 3 /* SDMODE CAS latency */
+#define CFG_SDMODE_WRAP 0 /* SDMODE wrap type */
+#if 0
+#define CFG_SDMODE_BURSTLEN 2 /* OBSOLETE! SDMODE Burst length 2=4, 3=8 */
+#endif
+
+#define CFG_REGISTERD_TYPE_BUFFER 1
+#define CFG_EXTROM 1
+#define CFG_REGDIMM 0
+
+
+/* memory bank settings*/
+/*
+ * only bits 20-29 are actually used from these vales to set the
+ * start/end address the upper two bits will be 0, and the lower 20
+ * bits will be set to 0x00000 for a start address, or 0xfffff for an
+ * end address
+ */
+#define CFG_BANK0_START 0x00000000
+#define CFG_BANK0_END (CFG_MAX_RAM_SIZE - 1)
+#define CFG_BANK0_ENABLE 1
+#define CFG_BANK1_START 0x3ff00000
+#define CFG_BANK1_END 0x3fffffff
+#define CFG_BANK1_ENABLE 0
+#define CFG_BANK2_START 0x3ff00000
+#define CFG_BANK2_END 0x3fffffff
+#define CFG_BANK2_ENABLE 0
+#define CFG_BANK3_START 0x3ff00000
+#define CFG_BANK3_END 0x3fffffff
+#define CFG_BANK3_ENABLE 0
+#define CFG_BANK4_START 0x00000000
+#define CFG_BANK4_END 0x00000000
+#define CFG_BANK4_ENABLE 0
+#define CFG_BANK5_START 0x00000000
+#define CFG_BANK5_END 0x00000000
+#define CFG_BANK5_ENABLE 0
+#define CFG_BANK6_START 0x00000000
+#define CFG_BANK6_END 0x00000000
+#define CFG_BANK6_ENABLE 0
+#define CFG_BANK7_START 0x00000000
+#define CFG_BANK7_END 0x00000000
+#define CFG_BANK7_ENABLE 0
+/*
+ * Memory bank enable bitmask, specifying which of the banks defined above
+ are actually present. MSB is for bank #7, LSB is for bank #0.
+ */
+#define CFG_BANK_ENABLE 0x01
+
+#define CFG_ODCR 0xff /* configures line driver impedances, */
+ /* see 8240 book for bit definitions */
+#define CFG_PGMAX 0x32 /* how long the 8240 retains the */
+ /* currently accessed page in memory */
+ /* see 8240 book for details */
+
+/* SDRAM 0 - 256MB */
+#define CFG_IBAT0L (CFG_SDRAM_BASE | BATL_PP_10 | BATL_MEMCOHERENCE)
+#define CFG_IBAT0U (CFG_SDRAM_BASE | BATU_BL_256M | BATU_VS | BATU_VP)
+
+/* stack in DCACHE @ 1GB (no backing mem) */
+#if defined(USE_DINK32)
+#define CFG_IBAT1L (0x40000000 | BATL_PP_00 )
+#define CFG_IBAT1U (0x40000000 | BATU_BL_128K )
+#else
+#define CFG_IBAT1L (CFG_INIT_RAM_ADDR | BATL_PP_10 | BATL_MEMCOHERENCE)
+#define CFG_IBAT1U (CFG_INIT_RAM_ADDR | BATU_BL_128K | BATU_VS | BATU_VP)
+#endif
+
+/* PCI memory */
+#define CFG_IBAT2L (0x80000000 | BATL_PP_10 | BATL_CACHEINHIBIT)
+#define CFG_IBAT2U (0x80000000 | BATU_BL_256M | BATU_VS | BATU_VP)
+
+/* Flash, config addrs, etc */
+#define CFG_IBAT3L (0xF0000000 | BATL_PP_10 | BATL_CACHEINHIBIT)
+#define CFG_IBAT3U (0xF0000000 | BATU_BL_256M | BATU_VS | BATU_VP)
+
+#define CFG_DBAT0L CFG_IBAT0L
+#define CFG_DBAT0U CFG_IBAT0U
+#define CFG_DBAT1L CFG_IBAT1L
+#define CFG_DBAT1U CFG_IBAT1U
+#define CFG_DBAT2L CFG_IBAT2L
+#define CFG_DBAT2U CFG_IBAT2U
+#define CFG_DBAT3L CFG_IBAT3L
+#define CFG_DBAT3U CFG_IBAT3U
+
+/*
+ * For booting Linux, the board info and command line data
+ * have to be in the first 8 MB of memory, since this is
+ * the maximum mapped by the Linux kernel during initialization.
+ */
+#define CFG_BOOTMAPSZ (8 << 20) /* Initial Memory map for Linux */
+/*-----------------------------------------------------------------------
+ * FLASH organization
+ */
+#define CFG_MAX_FLASH_BANKS 2 /* max number of memory banks */
+#define CFG_MAX_FLASH_SECT 20 /* max number of sectors on one chip */
+
+#define CFG_FLASH_ERASE_TOUT 120000 /* Timeout for Flash Erase (in ms) */
+#define CFG_FLASH_WRITE_TOUT 500 /* Timeout for Flash Write (in ms) */
+
+/*-----------------------------------------------------------------------
+ * Cache Configuration
+ */
+#define CFG_CACHELINE_SIZE 32 /* For MPC8240 CPU */
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+# define CFG_CACHELINE_SHIFT 5 /* log base 2 of the above value */
+#endif
+
+
+/*
+ * Internal Definitions
+ *
+ * Boot Flags
+ */
+#define BOOTFLAG_COLD 0x01 /* Normal Power-On: Boot from FLASH */
+#define BOOTFLAG_WARM 0x02 /* Software reboot */
+
+
+/* values according to the manual */
+
+#define CONFIG_DRAM_50MHZ 1
+#define CONFIG_SDRAM_50MHZ
+
+#undef NR_8259_INTS
+#define NR_8259_INTS 1
+
+
+#define CONFIG_DISK_SPINUP_TIME 1000000
+
+
+#endif /* __CONFIG_H */
--- /dev/null
+/*
+ * (C) Copyright 2001
+ * Josh Huber <huber@mclx.com>, Mission Critical Linux, 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
+ */
+
+/*
+ * board/config.h - configuration options, board specific
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+#include <asm/processor.h>
+
+#define CFG_GT_6426x GT_64260 /* with a 64260 system controller */
+#define CONFIG_ETHER_PORT_MII /* use two MII ports */
+#define CONFIG_INTEL_LXT97X /* Intel LXT97X phy */
+
+#ifndef __ASSEMBLY__
+#include <galileo/core.h>
+#endif
+
+#include "../board/evb64260/local.h"
+
+#define CONFIG_EVB64260 1 /* this is an EVB64260 board */
+#define CONFIG_ZUMA_V2 1 /* always define this for ZUMA v2 */
+
+/* #define CONFIG_ZUMA_V2_OLD 1 */ /* backwards compat for old V2 board */
+
+#define CONFIG_BAUDRATE 38400 /* console baudrate = 38400 */
+
+#define CONFIG_ECC /* enable ECC support */
+
+#define CONFIG_750CX /* we have a 750CX/CXe (override local.h) */
+
+/* which initialization functions to call for this board */
+#define CONFIG_MISC_INIT_R
+#define CONFIG_BOARD_PRE_INIT
+#define CFG_BOARD_ASM_INIT
+
+#define CFG_BOARD_NAME "Zuma APv2"
+
+#define CFG_HUSH_PARSER
+#define CFG_PROMPT_HUSH_PS2 "> "
+
+/*
+ * The following defines let you select what serial you want to use
+ * for your console driver.
+ *
+ * what to do:
+ * to use the DUART, undef CONFIG_MPSC. If you have hacked a serial
+ * cable onto the second DUART channel, change the CFG_DUART port from 1
+ * to 0 below.
+ *
+ * to use the MPSC, #define CONFIG_MPSC. If you have wired up another
+ * mpsc channel, change CONFIG_MPSC_PORT to the desired value.
+ */
+#define CONFIG_MPSC
+
+#define CONFIG_MPSC_PORT 0
+
+#define CONFIG_NET_MULTI /* attempt all available adapters */
+
+/* define this if you want to enable GT MAC filtering */
+#define CONFIG_GT_USE_MAC_HASH_TABLE
+
+#if 1
+#define CONFIG_BOOTDELAY -1 /* autoboot disabled */
+#else
+#define CONFIG_BOOTDELAY 5 /* autoboot after 5 seconds */
+#endif
+#define CONFIG_ZERO_BOOTDELAY_CHECK
+
+#undef CONFIG_BOOTARGS
+
+#define CONFIG_BOOTCOMMAND \
+ "tftpboot && " \
+ "setenv bootargs root=/dev/nfs rw nfsroot=$serverip:$rootpath " \
+ "ip=$ipaddr:$serverip:$gatewayip:" \
+ "$netmask:$hostname:eth0:none panic=5 && bootm"
+
+#define CONFIG_LOADS_ECHO 0 /* echo off for serial download */
+#define CFG_LOADS_BAUD_CHANGE /* allow baudrate changes */
+
+#undef CONFIG_WATCHDOG /* watchdog disabled */
+#undef CONFIG_ALTIVEC /* undef to disable */
+
+#define CONFIG_BOOTP_MASK (CONFIG_BOOTP_DEFAULT | \
+ CONFIG_BOOTP_BOOTFILESIZE)
+
+#define CONFIG_MII /* enable MII commands */
+
+#define CONFIG_COMMANDS (CONFIG_CMD_DFL | \
+ CFG_CMD_ASKENV | \
+ CFG_CMD_BSP | \
+ CFG_CMD_JFFS2 | \
+ CFG_CMD_MII | \
+ CFG_CMD_DATE)
+
+/* Flash banks JFFS2 should use */
+#define CFG_JFFS2_FIRST_BANK 1
+#define CFG_JFFS2_NUM_BANKS 2
+
+/* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */
+#include <cmd_confdefs.h>
+
+/*
+ * Miscellaneous configurable options
+ */
+#define CFG_LONGHELP /* undef to save memory */
+#define CFG_PROMPT "=> " /* Monitor Command Prompt */
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+#define CFG_CBSIZE 1024 /* Console I/O Buffer Size */
+#else
+#define CFG_CBSIZE 256 /* Console I/O Buffer Size */
+#endif
+#define CFG_PBSIZE (CFG_CBSIZE+sizeof(CFG_PROMPT)+16) /* Print Buffer Size */
+#define CFG_MAXARGS 16 /* max number of command args */
+#define CFG_BARGSIZE CFG_CBSIZE /* Boot Argument Buffer Size */
+
+#define CFG_MEMTEST_START 0x00400000 /* memtest works on */
+#define CFG_MEMTEST_END 0x00C00000 /* 4 ... 12 MB in DRAM */
+
+#define CFG_LOAD_ADDR 0x00300000 /* default load address */
+
+#define CFG_HZ 1000 /* decr freq: 1ms ticks */
+
+#define CFG_BUS_HZ 133000000 /* 133 MHz */
+
+#define CFG_BUS_CLK CFG_BUS_HZ
+
+#define CFG_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200, 230400 }
+
+/*
+ * Low Level Configuration Settings
+ * (address mappings, register initial values, etc.)
+ * You should know what you are doing if you make changes here.
+ */
+
+/*-----------------------------------------------------------------------
+ * Definitions for initial stack pointer and data area
+ */
+#define CFG_INIT_RAM_ADDR 0x40000000
+#define CFG_INIT_RAM_END 0x1000
+#define CFG_GBL_DATA_SIZE 128 /* size in bytes reserved for init data */
+#define CFG_GBL_DATA_OFFSET (CFG_INIT_RAM_END - CFG_GBL_DATA_SIZE)
+#define CFG_INIT_RAM_LOCK
+
+
+/*-----------------------------------------------------------------------
+ * Start addresses for the final memory configuration
+ * (Set up by the startup code)
+ * Please note that CFG_SDRAM_BASE _must_ start at 0
+ */
+#define CFG_SDRAM_BASE 0x00000000
+#define CFG_FLASH_BASE 0xfff00000
+#define CFG_RESET_ADDRESS 0xfff00100
+#define CFG_MONITOR_LEN (256 << 10) /* Reserve 256 kB for Monitor */
+#define CFG_MONITOR_BASE CFG_FLASH_BASE
+#define CFG_MALLOC_LEN (256 << 10) /* Reserve 256 kB for malloc */
+
+/* areas to map different things with the GT in physical space */
+#define CFG_DRAM_BANKS 4
+#define CFG_DFL_GT_REGS 0x14000000 /* boot time GT_REGS */
+
+/* What to put in the bats. */
+#define CFG_MISC_REGION_BASE 0xf0000000
+
+/* Peripheral Device section */
+#define CFG_GT_REGS 0xf8000000 /* later mapped GT_REGS */
+#define CFG_DEV_BASE 0xf0000000
+#define CFG_DEV0_SIZE _64M /* zuma flash @ 0xf000.0000*/
+#define CFG_DEV1_SIZE _8M /* zuma IDE @ 0xf400.0000 */
+#define CFG_DEV2_SIZE _8M /* unused */
+#define CFG_DEV3_SIZE _8M /* unused */
+
+#define CFG_DEV0_PAR 0xc498243c
+ /* c 4 9 8 2 4 3 c */
+ /* 33 22|2222|22 22|111 1|11 11|1 1 | | */
+ /* 10 98|7654|32 10|987 6|54 32|1 098|7 654|3 210 */
+ /* 11|00|0100|10 01|100|0 00|10 0|100 0|011 1|100 */
+ /* 3| 0|.... ..| 1| 4 | 0 | 4 | 8 | 7 | 4 */
+
+#define CFG_DEV1_PAR 0xc01b6ac5
+ /* c 0 1 b 6 a c 5 */
+ /* 33 22|2222|22 22|111 1|11 11|1 1 | | */
+ /* 10 98|7654|32 10|987 6|54 32|1 098|7 654|3 210 */
+ /* 11|00|0000|00 01|101|1 01|10 1|010 1|100 0|101 */
+ /* 3| 0|.... ..| 1| 5 | 5 | 5 | 5 | 8 | 5 */
+
+
+
+#define CFG_8BIT_BOOT_PAR 0xc00b5e7c
+
+#define CFG_MPP_CONTROL_0 0x00007777 /* GPP[7:4] : REQ0[1:0] GNT0[1:0] */
+#define CFG_MPP_CONTROL_1 0x00000000 /* GPP[15:12] : GPP[11:8] */
+#define CFG_MPP_CONTROL_2 0x00008888 /* GPP[23:20] : REQ1[1:0] GNT1[1:0] */
+#define CFG_MPP_CONTROL_3 0x00000000 /* GPP[31:28] (int[3:0]) */
+ /* GPP[27:24] (27 is int4, rest are GPP) */
+
+#define CFG_SERIAL_PORT_MUX 0x00001101 /* 11=MPSC1/MPSC0 01=ETH, 0=only MII */
+#define CFG_GPP_LEVEL_CONTROL 0xf8000000 /* interrupt inputs: GPP[31:27] */
+
+#define CFG_SDRAM_CONFIG 0xe4e18200 /* 0x448 */
+ /* idmas use buffer 1,1
+ comm use buffer 1
+ pci use buffer 0,0 (pci1->0 pci0->0)
+ cpu use buffer 1 (R*18)
+ normal load (see also ifdef HVL)
+ standard SDRAM (see also ifdef REG)
+ non staggered refresh */
+ /* 31:26 25 23 20 19 18 16 */
+ /* 111001 00 111 0 0 00 1 */
+
+ /* refresh count=0x200
+ phy interleave disable (by default,
+ set later by dram config..)
+ virt interleave enable */
+ /* 15 14 13:0 */
+ /* 1 0 0x200 */
+
+#define CFG_DEV0_SPACE CFG_DEV_BASE
+#define CFG_DEV1_SPACE (CFG_DEV0_SPACE + CFG_DEV0_SIZE)
+#define CFG_DEV2_SPACE (CFG_DEV1_SPACE + CFG_DEV1_SIZE)
+#define CFG_DEV3_SPACE (CFG_DEV2_SPACE + CFG_DEV2_SIZE)
+
+/*-----------------------------------------------------------------------
+ * PCI stuff
+ */
+
+#define PCI_HOST_ADAPTER 0 /* configure ar pci adapter */
+#define PCI_HOST_FORCE 1 /* configure as pci host */
+#define PCI_HOST_AUTO 2 /* detected via arbiter enable */
+
+#define CONFIG_PCI /* include pci support */
+#define CONFIG_PCI_HOST PCI_HOST_FORCE /* select pci host function */
+#define CONFIG_PCI_PNP /* do pci plug-and-play */
+
+/* PCI MEMORY MAP section */
+#define CFG_PCI0_MEM_BASE 0x80000000
+#define CFG_PCI0_MEM_SIZE _128M
+#define CFG_PCI1_MEM_BASE 0x88000000
+#define CFG_PCI1_MEM_SIZE _128M
+
+#define CFG_PCI0_0_MEM_SPACE (CFG_PCI0_MEM_BASE)
+#define CFG_PCI1_0_MEM_SPACE (CFG_PCI1_MEM_BASE)
+
+/* PCI I/O MAP section */
+#define CFG_PCI0_IO_BASE 0xfa000000
+#define CFG_PCI0_IO_SIZE _16M
+#define CFG_PCI1_IO_BASE 0xfb000000
+#define CFG_PCI1_IO_SIZE _16M
+
+#define CFG_PCI0_IO_SPACE (CFG_PCI0_IO_BASE)
+#define CFG_PCI0_IO_SPACE_PCI 0x00000000
+#define CFG_PCI1_IO_SPACE (CFG_PCI1_IO_BASE)
+#define CFG_PCI1_IO_SPACE_PCI 0x00000000
+
+
+/*----------------------------------------------------------------------
+ * Initial BAT mappings
+ */
+
+/* NOTES:
+ * 1) GUARDED and WRITE_THRU not allowed in IBATS
+ * 2) CACHEINHIBIT and WRITETHROUGH not allowed together in same BAT
+ */
+
+/* SDRAM */
+#define CFG_IBAT0L (CFG_SDRAM_BASE | BATL_PP_RW | BATL_CACHEINHIBIT)
+#define CFG_IBAT0U (CFG_SDRAM_BASE | BATU_BL_256M | BATU_VS | BATU_VP)
+#define CFG_DBAT0L (CFG_SDRAM_BASE | BATL_PP_RW | BATL_CACHEINHIBIT | BATL_GUARDEDSTORAGE)
+#define CFG_DBAT0U CFG_IBAT0U
+
+/* init ram */
+#define CFG_IBAT1L (CFG_INIT_RAM_ADDR | BATL_PP_RW | BATL_MEMCOHERENCE)
+#define CFG_IBAT1U (CFG_INIT_RAM_ADDR | BATU_BL_128K | BATU_VS | BATU_VP)
+#define CFG_DBAT1L CFG_IBAT1L
+#define CFG_DBAT1U CFG_IBAT1U
+
+/* PCI0, PCI1 memory space (starting at PCI0 base, mapped in one BAT) */
+#define CFG_IBAT2L BATL_NO_ACCESS
+#define CFG_IBAT2U CFG_DBAT2U
+#define CFG_DBAT2L (CFG_PCI0_MEM_BASE | BATL_CACHEINHIBIT | BATL_PP_RW | BATL_GUARDEDSTORAGE)
+#define CFG_DBAT2U (CFG_PCI0_MEM_BASE | BATU_BL_256M | BATU_VS | BATU_VP)
+
+/* GT regs, bootrom, all the devices, PCI I/O */
+#define CFG_IBAT3L (CFG_MISC_REGION_BASE | BATL_CACHEINHIBIT | BATL_PP_RW)
+#define CFG_IBAT3U (CFG_MISC_REGION_BASE | BATU_VS | BATU_VP | BATU_BL_256M)
+#define CFG_DBAT3L (CFG_MISC_REGION_BASE | BATL_CACHEINHIBIT | BATL_PP_RW | BATL_GUARDEDSTORAGE)
+#define CFG_DBAT3U CFG_IBAT3U
+
+/*
+ * For booting Linux, the board info and command line data
+ * have to be in the first 8 MB of memory, since this is
+ * the maximum mapped by the Linux kernel during initialization.
+ */
+#define CFG_BOOTMAPSZ (8<<20) /* Initial Memory map for Linux */
+
+
+/*-----------------------------------------------------------------------
+ * FLASH organization
+ */
+#define CFG_MAX_FLASH_BANKS 3 /* max number of memory banks */
+#define CFG_MAX_FLASH_SECT 130 /* max number of sectors on one chip */
+
+#define CFG_EXTRA_FLASH_DEVICE DEVICE0 /* extra flash at device 0 */
+#define CFG_EXTRA_FLASH_WIDTH 2 /* 16 bit */
+
+#define CFG_FLASH_ERASE_TOUT 120000 /* Timeout for Flash Erase (in ms) */
+#define CFG_FLASH_WRITE_TOUT 500 /* Timeout for Flash Write (in ms) */
+#define CFG_FLASH_CFI 1
+
+#define CFG_ENV_IS_IN_FLASH 1
+#define CFG_ENV_SIZE 0x1000 /* Total Size of Environment Sector */
+#define CFG_ENV_SECT_SIZE 0x10000 /* see README - env sect real size */
+#define CFG_ENV_ADDR (0xfff80000 - CFG_ENV_SECT_SIZE)
+
+/*-----------------------------------------------------------------------
+ * Cache Configuration
+ */
+#define CFG_CACHELINE_SIZE 32 /* For all MPC74xx CPUs */
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+#define CFG_CACHELINE_SHIFT 5 /* log base 2 of the above value */
+#endif
+
+/*-----------------------------------------------------------------------
+ * L2CR setup -- make sure this is right for your board!
+ * look in include/mpc74xx.h for the defines used here
+ */
+
+#define CFG_L2
+
+#ifdef CONFIG_750CX
+#define L2_INIT 0
+#else
+#define L2_INIT (L2CR_L2SIZ_2M | L2CR_L2CLK_3 | L2CR_L2RAM_BURST | \
+ L2CR_L2OH_5 | L2CR_L2CTL | L2CR_L2WT)
+#endif
+
+#define L2_ENABLE (L2_INIT | L2CR_L2E)
+
+/*------------------------------------------------------------------------
+ * Real time clock
+ */
+#define CONFIG_RTC_DS1302
+
+
+/*------------------------------------------------------------------------
+ * Galileo I2C driver
+ */
+#define CONFIG_GT_I2C
+
+/*
+ * Internal Definitions
+ *
+ * Boot Flags
+ */
+#define BOOTFLAG_COLD 0x01 /* Normal Power-On: Boot from FLASH */
+#define BOOTFLAG_WARM 0x02 /* Software reboot */
+
+#endif /* __CONFIG_H */
--- /dev/null
+/*
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Alex Zuepke <azu@sysgo.de>
+ *
+ * Configuation settings for the Shannon/TuxScreen/IS2630 WebPhone Board.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+/*
+ * If we are developing, we might want to start armboot from ram
+ * so we MUST NOT initialize critical regs like mem-timing ...
+ */
+
+/*
+ * we just run in non-critical mode now, because we use the Inferno-Loader to
+ * bring us to live
+ */
+#define CONFIG_INFERNO /* we are using the inferno bootldr */
+#undef CONFIG_INIT_CRITICAL /* undef for developing */
+
+/*
+ * High Level Configuration Options
+ * (easy to change)
+ */
+#define CONFIG_SA1100 1 /* This is an SA1100 CPU */
+#define CONFIG_SHANNON 1 /* on an SHANNON/TuxScreen Board */
+
+#undef CONFIG_USE_IRQ /* we don't need IRQ/FIQ stuff */
+
+/*
+ * Size of malloc() pool
+ */
+#define CONFIG_MALLOC_SIZE (CFG_ENV_SIZE + 128*1024)
+
+/*
+ * Hardware drivers
+ */
+#define CONFIG_DRIVER_3C589 1
+
+/*
+ * select serial console configuration
+ */
+#define CONFIG_SERIAL3 1 /* we use SERIAL 3 */
+
+/* allow to overwrite serial and ethaddr */
+#define CONFIG_ENV_OVERWRITE
+
+#define CONFIG_BAUDRATE 115200
+
+#if 0 /* XXX - cannot test IDE anyway, so disabled for now - wd */
+#define CONFIG_COMMANDS (CONFIG_CMD_DFL | \
+ CFG_CMD_PCMCIA | \
+ CFG_CMD_IDE)
+#endif /* 0 */
+
+/* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */
+#include <cmd_confdefs.h>
+
+#define CONFIG_BOOTDELAY 3
+#define CONFIG_BOOTARGS "root=ramfs devfs=mount console=ttySA0,115200"
+#define CONFIG_NETMASK 255.255.0.0
+#define CONFIG_BOOTCOMMAND "help"
+
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+#define CONFIG_KGDB_BAUDRATE 230400 /* speed to run kgdb serial port */
+#define CONFIG_KGDB_SER_INDEX 2 /* which serial port to use */
+#endif
+
+/*
+ * Miscellaneous configurable options
+ */
+#define CFG_LONGHELP /* undef to save memory */
+#define CFG_PROMPT "TuxScreen # " /* Monitor Command Prompt */
+#define CFG_CBSIZE 256 /* Console I/O Buffer Size */
+#define CFG_PBSIZE (CFG_CBSIZE+sizeof(CFG_PROMPT)+16) /* Print Buffer Size */
+#define CFG_MAXARGS 16 /* max number of command args */
+#define CFG_BARGSIZE CFG_CBSIZE /* Boot Argument Buffer Size */
+
+#define CFG_MEMTEST_START 0xc0400000 /* memtest works on */
+#define CFG_MEMTEST_END 0xc0800000 /* 4 ... 8 MB in DRAM */
+
+#undef CFG_CLKS_IN_HZ /* everything, incl board info, in Hz */
+
+#define CFG_LOAD_ADDR 0xd0000000 /* default load address */
+
+#define CFG_HZ 3686400 /* incrementer freq: 3.6864 MHz */
+#define CFG_CPUSPEED 0x09 /* 190 MHz for Shannon */
+
+ /* valid baudrates */
+#define CFG_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 }
+
+#define CONFIG_DOS_PARTITION 1 /* DOS partitiion support */
+
+/*-----------------------------------------------------------------------
+ * Stack sizes
+ *
+ * The stack sizes are set up in start.S using the settings below
+ */
+#define CONFIG_STACKSIZE (128*1024) /* regular stack */
+#ifdef CONFIG_USE_IRQ
+#define CONFIG_STACKSIZE_IRQ (4*1024) /* IRQ stack */
+#define CONFIG_STACKSIZE_FIQ (4*1024) /* FIQ stack */
+#endif
+
+/*-----------------------------------------------------------------------
+ * Physical Memory Map
+ */
+/* BE CAREFUL */
+#define CONFIG_NR_DRAM_BANKS 4 /* we have 4 banks of EDORAM */
+#define PHYS_SDRAM_1 0xc0000000 /* RAM Bank #1 */
+#define PHYS_SDRAM_1_SIZE 0x00400000 /* 4 MB */
+#define PHYS_SDRAM_2 0xc8000000 /* RAM Bank #2 */
+#define PHYS_SDRAM_2_SIZE 0x00400000 /* 4 MB */
+#define PHYS_SDRAM_3 0xd0000000 /* RAM Bank #3 */
+#define PHYS_SDRAM_3_SIZE 0x00400000 /* 4 MB */
+#define PHYS_SDRAM_4 0xd8000000 /* RAM Bank #4 */
+#define PHYS_SDRAM_4_SIZE 0x00400000 /* 4 MB */
+
+
+#define PHYS_FLASH_1 0x00000000 /* Flash Bank #1 */
+#define PHYS_FLASH_SIZE 0x00400000 /* 4 MB */
+
+#define CFG_FLASH_BASE PHYS_FLASH_1
+
+/*-----------------------------------------------------------------------
+ * FLASH and environment organization
+ */
+#define CFG_MAX_FLASH_BANKS 1 /* max number of memory banks */
+#define CFG_MAX_FLASH_SECT (31+4) /* max number of sectors on one chip */
+
+/* timeout values are in ticks */
+#define CFG_FLASH_ERASE_TOUT (2*CFG_HZ) /* Timeout for Flash Erase */
+#define CFG_FLASH_WRITE_TOUT (2*CFG_HZ) /* Timeout for Flash Write */
+
+#define CFG_ENV_IS_IN_FLASH 1
+#ifdef CONFIG_INFERNO
+/* we take the last sector, 128 KB in size, but we only use 4 KB of it for stack reasons */
+#define CFG_ENV_ADDR (PHYS_FLASH_1 + 0x003E0000) /* Addr of Environment Sector */
+#define CFG_ENV_SIZE 0x4000 /* Total Size of Environment Sector */
+#else
+#define CFG_ENV_ADDR (PHYS_FLASH_1 + 0x1C000) /* Addr of Environment Sector */
+#define CFG_ENV_SIZE 0x4000 /* Total Size of Environment Sector */
+#endif
+
+/*-----------------------------------------------------------------------
+ * PCMCIA stuff
+ *-----------------------------------------------------------------------
+ *
+ */
+
+/* we pick the upper one */
+
+#define CONFIG_PCMCIA_SLOT_A
+
+#define CFG_PCMCIA_IO_ADDR (0x20000000)
+#define CFG_PCMCIA_IO_SIZE ( 64 << 20 )
+#define CFG_PCMCIA_DMA_ADDR (0x24000000)
+#define CFG_PCMCIA_DMA_SIZE ( 64 << 20 )
+#define CFG_PCMCIA_ATTRB_ADDR (0x2C000000)
+#define CFG_PCMCIA_ATTRB_SIZE ( 64 << 20 )
+#define CFG_PCMCIA_MEM_ADDR (0x28000000)
+#define CFG_PCMCIA_MEM_SIZE ( 64 << 20 )
+
+/* in fact, MEM and ATTRB are swapped - has to be corrected soon in cmd_pcmcia or so */
+
+/*-----------------------------------------------------------------------
+ * IDE/ATA stuff (Supports IDE harddisk on PCMCIA Adapter)
+ *-----------------------------------------------------------------------
+ */
+
+#define CONFIG_IDE_PCCARD 1 /* Use IDE with PC Card Adapter */
+
+#undef CONFIG_IDE_PCMCIA /* Direct IDE not supported */
+#undef CONFIG_IDE_LED /* LED for ide not supported */
+#undef CONFIG_IDE_RESET /* reset for ide not supported */
+
+#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
+
+/* it's simple, all regs are in I/O space */
+#define CFG_ATA_BASE_ADDR CFG_PCMCIA_ATTRB_ADDR
+
+/* Offset for data I/O */
+#define CFG_ATA_DATA_OFFSET (CFG_ATA_BASE_ADDR)
+
+/* Offset for normal register accesses */
+#define CFG_ATA_REG_OFFSET (CFG_ATA_BASE_ADDR)
+
+/* Offset for alternate registers */
+#define CFG_ATA_ALT_OFFSET (CFG_ATA_BASE_ADDR)
+
+/*-----------------------------------------------------------------------
+ */
+
+#endif /* __CONFIG_H */
--- /dev/null
+/*
+ * (C) Copyright 2002
+ * Gary Jennejohn <gj@denx.de>
+ *
+ * Configuation settings for the TRAB board.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+/*
+ * If we are developing, we might want to start armboot from ram
+ * so we MUST NOT initialize critical regs like mem-timing ...
+ */
+#define CONFIG_INIT_CRITICAL /* undef for developing */
+
+/*
+ * High Level Configuration Options
+ * (easy to change)
+ */
+#define CONFIG_ARM920T 1 /* This is an arm920t CPU */
+#define CONFIG_S3C2400 1 /* in a SAMSUNG S3C2400 SoC */
+#define CONFIG_TRAB 1 /* on a TRAB Board */
+#undef CONFIG_TRAB_50MHZ /* run the CPU at 50 MHz */
+
+/* input clock of PLL */
+#define CONFIG_PLL_INPUT_FREQ 12000000 /* TRAB has 12 MHz input clock */
+
+#undef CONFIG_USE_IRQ /* we don't need IRQ/FIQ stuff */
+
+#define CONFIG_CMDLINE_TAG 1 /* enable passing of ATAGs */
+#define CONFIG_SETUP_MEMORY_TAGS 1
+#define CONFIG_INITRD_TAG 1
+
+/*
+ * Size of malloc() pool
+ */
+#define CONFIG_MALLOC_SIZE (CFG_ENV_SIZE + 128*1024)
+
+/*
+ * Hardware drivers
+ */
+#define CONFIG_DRIVER_CS8900 1 /* we have a CS8900 on-board */
+#define CS8900_BASE 0x07000300 /* agrees with WIN CE PA */
+#define CS8900_BUS16 1 /* the Linux driver does accesses as shorts */
+
+#define CONFIG_VFD 1 /* VFD linear frame buffer driver */
+#define VFD_TEST_LOGO 1 /* output a test logo to the VFDs */
+
+/*
+ * select serial console configuration
+ */
+#define CONFIG_SERIAL1 1 /* we use SERIAL 1 on TRAB */
+
+#define CONFIG_HWFLOW /* include RTS/CTS flow control support */
+
+#define CONFIG_MODEM_SUPPORT 1 /* enable modem initialization stuff */
+
+#define CONFIG_MODEM_KEY_MAGIC "23" /* hold down these keys to enable modem */
+
+/*
+ * The following enables modem debugging stuff. The dbg() and
+ * 'char screen[1024]' are used for debug printfs. Unfortunately,
+ * it is usable only from BDI
+ */
+#undef CONFIG_MODEM_SUPPORT_DEBUG
+
+/* allow to overwrite serial and ethaddr */
+#define CONFIG_ENV_OVERWRITE
+
+#define CONFIG_BAUDRATE 115200
+
+#define CONFIG_TIMESTAMP 1 /* Print timestamp info for images */
+
+#ifdef CONFIG_HWFLOW
+#define CONFIG_COMMANDS_ADD_HWFLOW CFG_CMD_HWFLOW
+#else
+#define CONFIG_COMMANDS_ADD_HWFLOW 0
+#endif
+
+#ifdef CONFIG_VFD
+#define CONFIG_COMMANDS_ADD_VFD CFG_CMD_VFD
+#else
+#define CONFIG_COMMANDS_ADD_VFD 0
+#endif
+
+#ifndef USE_920T_MMU
+#define CONFIG_COMMANDS ((CONFIG_CMD_DFL & ~CFG_CMD_CACHE) | \
+ CFG_CMD_BSP | \
+ CONFIG_COMMANDS_ADD_HWFLOW | \
+ CONFIG_COMMANDS_ADD_VFD )
+#else
+#define CONFIG_COMMANDS (CONFIG_CMD_DFL | \
+ CFG_CMD_BSP | \
+ CONFIG_COMMANDS_ADD_HWFLOW | \
+ CONFIG_COMMANDS_ADD_VFD )
+#endif
+
+/* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */
+#include <cmd_confdefs.h>
+
+
+#define CONFIG_BOOTDELAY 5
+#define CONFIG_PREBOOT "echo;echo *** booting ***;echo"
+#define CONFIG_BOOTARGS "console=ttyS0"
+#define CONFIG_ETHADDR 00:D0:93:00:61:11
+#define CONFIG_NETMASK 255.255.255.0
+#define CONFIG_IPADDR 192.168.3.27
+#define CONFIG_SERVERIP 192.168.3.1
+#define CONFIG_BOOTCOMMAND "run flash_nfs"
+#define CONFIG_EXTRA_ENV_SETTINGS \
+ "nfs_args=setenv bootargs root=/dev/nfs rw " \
+ "nfsroot=$(serverip):$(rootpath)\0" \
+ "rootpath=/opt/eldk/arm_920TDI\0" \
+ "ram_args=setenv bootargs root=/dev/ram rw\0" \
+ "add_net=setenv bootargs $(bootargs) ethaddr=$(ethaddr) " \
+ "ip=$(ipaddr):$(serverip):$(gatewayip):$(netmask):$(hostname)::off\0" \
+ "add_misc=setenv bootargs $(bootargs) console=ttyS0 panic=1\0" \
+ "load=tftp 0xC100000 /tftpboot/TRAB/u-boot.bin\0" \
+ "update=protect off 1:0-7;era 1:0-7;cp.b 0xc100000 0 $(filesize);" \
+ "setenv filesize;saveenv\0" \
+ "loadfile=/tftpboot/TRAB/pImage\0" \
+ "loadaddr=c400000\0" \
+ "net_load=tftpboot $(loadaddr) $(loadfile)\0" \
+ "net_nfs=run net_load nfs_args add_net add_misc;bootm\0" \
+ "kernel_addr=00040000\0" \
+ "flash_nfs=run nfs_args add_net add_misc;bootm $(kernel_addr)\0" \
+ "mdm_init1=ATZ\0" \
+ "mdm_init2=ATS0=1\0" \
+ "mdm_flow_control=rts/cts\0"
+
+#if 0 /* disabled for development */
+#define CONFIG_AUTOBOOT_KEYED /* Enable password protection */
+#define CONFIG_AUTOBOOT_PROMPT "\nEnter password - autoboot in %d sec...\n"
+#define CONFIG_AUTOBOOT_DELAY_STR "system" /* 1st password */
+#endif
+
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+#define CONFIG_KGDB_BAUDRATE 115200 /* speed to run kgdb serial port */
+/* what's this ? it's not used anywhere */
+#define CONFIG_KGDB_SER_INDEX 1 /* which serial port to use */
+#endif
+
+/*
+ * Miscellaneous configurable options
+ */
+#define CFG_LONGHELP /* undef to save memory */
+#define CFG_PROMPT "TRAB # " /* Monitor Command Prompt */
+#define CFG_CBSIZE 256 /* Console I/O Buffer Size */
+#define CFG_PBSIZE (CFG_CBSIZE+sizeof(CFG_PROMPT)+16) /* Print Buffer Size */
+#define CFG_MAXARGS 16 /* max number of command args */
+#define CFG_BARGSIZE CFG_CBSIZE /* Boot Argument Buffer Size */
+
+#define CFG_MEMTEST_START 0x0c000000 /* memtest works on */
+#define CFG_MEMTEST_END 0x0d000000 /* 16 MB in DRAM */
+
+#undef CFG_CLKS_IN_HZ /* everything, incl board info, in Hz */
+
+#define CFG_LOAD_ADDR 0x0cf00000 /* default load address */
+
+#ifdef CONFIG_TRAB_50MHZ
+/* the PWM TImer 4 uses a counter of 15625 for 10 ms, so we need */
+/* it to wrap 100 times (total 1562500) to get 1 sec. */
+/* this should _really_ be calculated !! */
+#define CFG_HZ 1562500
+#else
+/* the PWM TImer 4 uses a counter of 10390 for 10 ms, so we need */
+/* it to wrap 100 times (total 1039000) to get 1 sec. */
+/* this should _really_ be calculated !! */
+#define CFG_HZ 1039000
+#endif
+
+/* valid baudrates */
+#define CFG_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 }
+
+#define CONFIG_MISC_INIT_R /* have misc_init_r() function */
+
+/*-----------------------------------------------------------------------
+ * Stack sizes
+ *
+ * The stack sizes are set up in start.S using the settings below
+ */
+#define CONFIG_STACKSIZE (128*1024) /* regular stack */
+#ifdef CONFIG_USE_IRQ
+#define CONFIG_STACKSIZE_IRQ (4*1024) /* IRQ stack */
+#define CONFIG_STACKSIZE_FIQ (4*1024) /* FIQ stack */
+#endif
+
+/*-----------------------------------------------------------------------
+ * Physical Memory Map
+ */
+#define CONFIG_NR_DRAM_BANKS 1 /* we have 1 bank of DRAM */
+#define PHYS_SDRAM_1 0x0c000000 /* SDRAM Bank #1 */
+#define PHYS_SDRAM_1_SIZE 0x01000000 /* 16 MB */
+
+#define PHYS_FLASH_1 0x00000000 /* Flash Bank #1 */
+#define PHYS_FLASH_SIZE 0x00800000 /* 8 MB */
+
+/* The following #defines are needed to get flash environment right */
+#define CFG_MONITOR_BASE PHYS_FLASH_1
+#define CFG_MONITOR_LEN (256 << 10)
+
+#define CFG_FLASH_BASE PHYS_FLASH_1
+
+/*-----------------------------------------------------------------------
+ * FLASH and environment organization
+ */
+#define CFG_MAX_FLASH_BANKS 1 /* max number of memory banks */
+#define CFG_MAX_FLASH_SECT (71) /* max number of sectors on one chip */
+
+/* timeout values are in ticks */
+#define CFG_FLASH_ERASE_TOUT (2*CFG_HZ) /* Timeout for Flash Erase */
+#define CFG_FLASH_WRITE_TOUT (2*CFG_HZ) /* Timeout for Flash Write */
+
+#define CFG_ENV_IS_IN_FLASH 1
+
+/* Address and size of Primary Environment Sector */
+#define CFG_ENV_ADDR (PHYS_FLASH_1 + 0x4000)
+#define CFG_ENV_SIZE 0x4000
+
+/* Address and size of Redundant Environment Sector */
+#define CFG_ENV_OFFSET_REDUND (CFG_ENV_ADDR+CFG_ENV_SIZE)
+#define CFG_ENV_SIZE_REDUND (CFG_ENV_SIZE)
+
+#endif /* __CONFIG_H */
--- /dev/null
+/*
+ * (C) Copyright 2001
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * (C) Copyright 2002
+ * Gregory E. Allen, gallen@arlut.utexas.edu
+ * Matthew E. Karger, karger@arlut.utexas.edu
+ * Applied Research Laboratories, The University of Texas at Austin
+ *
+ * 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
+ */
+
+/*
+ *
+ * Configuration settings for the utx8245 board.
+ *
+ */
+
+/* ------------------------------------------------------------------------- */
+
+/*
+ * board/config.h - configuration options, board specific
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+/*
+ * High Level Configuration Options
+ * (easy to change)
+ */
+
+#define CONFIG_MPC824X 1
+#define CONFIG_MPC8245 1
+#define CONFIG_UTX8245 1
+#define DEBUG 1
+
+#define CONFIG_CONS_INDEX 1
+#define CONFIG_BAUDRATE 57600
+#define CFG_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 }
+
+#define CONFIG_BOOTDELAY 5
+#define CONFIG_AUTOBOOT_PROMPT "autoboot in %d seconds\n"
+#define CONFIG_BOOTCOMMAND "bootm FF920000 FF800000" /* autoboot command */
+#define CONFIG_BOOTARGS "root=/dev/ram console=ttyS0,57600" /* RAMdisk */
+#define CONFIG_ETHADDR 41:52:4c:61:00:01 /* MAC address */
+#define CONFIG_SERVERIP 10.8.17.105
+#define CONFIG_ENV_OVERWRITE
+
+#define CONFIG_COMMANDS (CFG_CMD_DFL | CFG_CMD_BDI | CFG_CMD_PCI \
+ | CFG_CMD_FLASH | CFG_CMD_MEMORY \
+ | CFG_CMD_ENV | CFG_CMD_CONSOLE \
+ | CFG_CMD_LOADS | CFG_CMD_LOADB \
+ | CFG_CMD_IMI | CFG_CMD_CACHE \
+ | CFG_CMD_RUN | CFG_CMD_ECHO \
+ | CFG_CMD_REGINFO | CFG_CMD_NET\
+ | CFG_CMD_DHCP)
+
+/* This must be included AFTER the definition of CONFIG_COMMANDS (if any)
+ */
+#include <cmd_confdefs.h>
+
+
+/*
+ * Miscellaneous configurable options
+ */
+#define CFG_LONGHELP /* undef to save memory */
+#define CFG_PROMPT "=> " /* Monitor Command Prompt */
+#define CFG_CBSIZE 256 /* Console I/O Buffer Size */
+
+/* Print Buffer Size */
+#define CFG_PBSIZE (CFG_CBSIZE + sizeof(CFG_PROMPT) + 16)
+
+#define CFG_MAXARGS 16 /* max number of command args */
+#define CFG_BARGSIZE CFG_CBSIZE /* Boot Argument Buffer Size */
+#define CFG_LOAD_ADDR 0x00100000 /* Default load address */
+
+
+/*-----------------------------------------------------------------------
+ * PCI configuration
+ *-----------------------------------------------------------------------
+ */
+#define CONFIG_PCI /* include pci support */
+#undef CONFIG_PCI_PNP
+#define CONFIG_PCI_SCAN_SHOW
+#define CONFIG_NET_MULTI
+#define CONFIG_EEPRO100
+
+#define PCI_ENET0_IOADDR 0x80000000
+#define PCI_ENET0_MEMADDR 0x80000000
+#define PCI_FIREWIRE_IOADDR 0x81000000
+#define PCI_FIREWIRE_MEMADDR 0x81000000
+
+
+/*-----------------------------------------------------------------------
+ * Start addresses for the final memory configuration
+ * (Set up by the startup code)
+ * Please note that CFG_SDRAM_BASE _must_ start at 0
+ */
+#define CFG_SDRAM_BASE 0x00000000
+#define CFG_MAX_RAM_SIZE 0x10000000 /* amount of SDRAM */
+
+
+/* even though FLASHP_BASE is FF800000, with 2MB on RCS0, the
+ * reset vector is actually located at FF800100, but the 8245
+ * takes care of us.
+ */
+#define CFG_RESET_ADDRESS 0xFFF00100
+
+#define CFG_EUMB_ADDR 0xFC000000
+
+#define CFG_MONITOR_BASE TEXT_BASE
+
+#define CFG_MONITOR_LEN (256 << 10) /* Reserve 256 kB for Monitor */
+#define CFG_MALLOC_LEN (128 << 10) /* Reserve 128 kB for malloc() */
+
+/*#define CFG_DRAM_TEST 1 */
+#define CFG_MEMTEST_START 0x00003000 /* memtest works on 0...256 MB */
+#define CFG_MEMTEST_END 0x0ff8ffa8 /* in SDRAM, skips exception */
+ /* vectors and U-Boot */
+
+
+/*--------------------------------------------------------------------
+ * Definitions for initial stack pointer and data area
+ *------------------------------------------------------------------*/
+#define CFG_GBL_DATA_SIZE 128 /* Size in bytes reserved for */
+ /* initial data */
+#define CFG_INIT_RAM_ADDR 0x40000000
+#define CFG_INIT_RAM_END 0x1000
+#define CFG_GBL_DATA_OFFSET (CFG_INIT_RAM_END - CFG_GBL_DATA_SIZE)
+
+/*--------------------------------------------------------------------
+ * NS16550 Configuration
+ *------------------------------------------------------------------*/
+#define CFG_NS16550
+#define CFG_NS16550_SERIAL
+
+#define CFG_NS16550_REG_SIZE 1
+
+#define CFG_NS16550_CLK get_bus_freq(0)
+
+#define CFG_NS16550_COM1 (CFG_EUMB_ADDR + 0x4500)
+#define CFG_NS16550_COM2 (CFG_EUMB_ADDR + 0x4600)
+
+/*--------------------------------------------------------------------
+ * Low Level Configuration Settings
+ * (address mappings, register initial values, etc.)
+ * You should know what you are doing if you make changes here.
+ * For the detail description refer to the MPC8240 user's manual.
+ *------------------------------------------------------------------*/
+
+#define CONFIG_SYS_CLK_FREQ 33000000
+#define CFG_HZ 1000
+
+#define CFG_ETH_DEV_FN 0x7800
+#define CFG_ETH_IOBASE 0x00104000
+
+
+/*--------------------------------------------------------------------
+ * Memory Control Configuration Register values
+ * - see sec. 4.12 of MPC8245 UM
+ *------------------------------------------------------------------*/
+
+/* MCCR1 */
+#define CFG_ROMNAL 0
+#define CFG_ROMFAL 2 /* (tacc=70ns)*mem_freq - 2 */
+#define CFG_BANK0_ROW 2 /* SDRAM bank 7-0 row address */
+#define CFG_BANK1_ROW 2 /* bit count */
+#define CFG_BANK2_ROW 0
+#define CFG_BANK3_ROW 0
+#define CFG_BANK4_ROW 0
+#define CFG_BANK5_ROW 0
+#define CFG_BANK6_ROW 0
+#define CFG_BANK7_ROW 0
+
+/* MCCR2, refresh interval clock cycles */
+#define CFG_REFINT 480 /* 33 MHz SDRAM clock was 480 */
+
+/* Burst To Precharge. Bits of this value go to MCCR3 and MCCR4 */
+#define CFG_BSTOPRE 1023 /* burst to precharge[0..9], */
+ /* sets open page interval */
+
+/* MCCR3 */
+#define CFG_REFREC 5 /* Refresh to activate interval, trc */
+
+/* MCCR4 */
+#define CFG_PRETOACT 2 /* trp */
+#define CFG_ACTTOPRE 7 /* trcd + (burst length - 1) + tdrl */
+#define CFG_SDMODE_CAS_LAT 3 /* SDMODE CAS latancy */
+#define CFG_SDMODE_WRAP 0 /* SDMODE wrap type, sequential */
+#define CFG_ACTORW 2 /* trcd min */
+#define CFG_DBUS_SIZE2 1 /* set for 8-bit RCS1, clear for 32,64 */
+#define CFG_REGISTERD_TYPE_BUFFER 1
+#define CFG_EXTROM 1
+#define CFG_REGDIMM 0
+
+/* calculate according to formula in sec. 6-22 of 8245 UM */
+#define CFG_PGMAX 50 /* how long the 8245 retains the */
+ /* currently accessed page in memory */
+ /* was 45 */
+
+#define CFG_SDRAM_DSCD 0x20 /* SDRAM data in sample clock delay - note */
+ /* bottom 3 bits MUST be 0 */
+
+#define CFG_DLL_MAX_DELAY 0x04
+#define CFG_DLL_EXTEND 0x80
+#define CFG_PCI_HOLD_DEL 0x20
+
+
+/* Memory bank settings.
+ * Only bits 20-29 are actually used from these values to set the
+ * start/end addresses. The upper two bits will always be 0, and the lower
+ * 20 bits will be 0x00000 for a start address, or 0xfffff for an end
+ * address. Refer to the MPC8245 user manual.
+ */
+
+#define CFG_BANK0_START 0x00000000
+#define CFG_BANK0_END (CFG_MAX_RAM_SIZE/2 - 1)
+#define CFG_BANK0_ENABLE 1
+#define CFG_BANK1_START CFG_MAX_RAM_SIZE/2
+#define CFG_BANK1_END (CFG_MAX_RAM_SIZE - 1)
+#define CFG_BANK1_ENABLE 1
+#define CFG_BANK2_START 0x3ff00000 /* not available in this design */
+#define CFG_BANK2_END 0x3fffffff
+#define CFG_BANK2_ENABLE 0
+#define CFG_BANK3_START 0x3ff00000
+#define CFG_BANK3_END 0x3fffffff
+#define CFG_BANK3_ENABLE 0
+#define CFG_BANK4_START 0x3ff00000
+#define CFG_BANK4_END 0x3fffffff
+#define CFG_BANK4_ENABLE 0
+#define CFG_BANK5_START 0x3ff00000
+#define CFG_BANK5_END 0x3fffffff
+#define CFG_BANK5_ENABLE 0
+#define CFG_BANK6_START 0x3ff00000
+#define CFG_BANK6_END 0x3fffffff
+#define CFG_BANK6_ENABLE 0
+#define CFG_BANK7_START 0x3ff00000
+#define CFG_BANK7_END 0x3fffffff
+#define CFG_BANK7_ENABLE 0
+
+/*--------------------------------------------------------------------
+ * 4.4 - Output Driver Control Register
+ *------------------------------------------------------------------*/
+#define CFG_ODCR 0xe5
+
+/*--------------------------------------------------------------------
+ * 4.8 - Error Handling Registers
+ *------------------------------------------------------------------*/
+#define CFG_ERRENR1 0x11 /* enable SDRAM refresh overflow error */
+
+/* SDRAM 0-256 MB */
+#define CFG_IBAT0L (CFG_SDRAM_BASE | BATL_PP_10 | BATL_MEMCOHERENCE)
+#define CFG_IBAT0U (CFG_SDRAM_BASE | BATU_BL_256M | BATU_VS | BATU_VP)
+
+/* stack in dcache */
+#define CFG_IBAT1L (CFG_INIT_RAM_ADDR | BATL_PP_10 | BATL_MEMCOHERENCE)
+#define CFG_IBAT1U (CFG_INIT_RAM_ADDR | BATU_BL_128K | BATU_VS | BATU_VP)
+
+/* PCI memory */
+#define CFG_IBAT2L (0x80000000 | BATL_PP_10 | BATL_CACHEINHIBIT)
+#define CFG_IBAT2U (0x80000000 | BATU_BL_256M | BATU_VS | BATU_VP)
+
+/* Flash, config addrs, etc. */
+#define CFG_IBAT3L (0xF0000000 | BATL_PP_10 | BATL_CACHEINHIBIT)
+#define CFG_IBAT3U (0xF0000000 | BATU_BL_256M | BATU_VS | BATU_VP)
+
+#define CFG_DBAT0L CFG_IBAT0L
+#define CFG_DBAT0U CFG_IBAT0U
+#define CFG_DBAT1L CFG_IBAT1L
+#define CFG_DBAT1U CFG_IBAT1U
+#define CFG_DBAT2L CFG_IBAT2L
+#define CFG_DBAT2U CFG_IBAT2U
+#define CFG_DBAT3L CFG_IBAT3L
+#define CFG_DBAT3U CFG_IBAT3U
+
+/*
+ * For booting Linux, the board info and command line data
+ * have to be in the first 8 MB of memory, since this is
+ * the maximum mapped by the Linux kernel during initialization.
+ */
+#define CFG_BOOTMAPSZ (8 << 20) /* Initial Memory map for Linux */
+
+/*-----------------------------------------------------------------------
+ * FLASH organization (AMD AM29LV116D)
+ */
+#define CFG_FLASH_BASE 0xFF800000
+
+#define CFG_MAX_FLASH_BANKS 1 /* Max number of flash banks */
+#define CFG_MAX_FLASH_SECT 35 /* Max number of sectors in one bank */
+
+#define CFG_FLASH_ERASE_TOUT 120000 /* Timeout for Flash Erase (in ms) */
+#define CFG_FLASH_WRITE_TOUT 500 /* Timeout for Flash Write (in ms) */
+
+ /* Warning: environment is not EMBEDDED in the U-Boot code.
+ * It's stored in flash separately.
+ */
+#define CFG_ENV_IS_IN_FLASH 1
+
+#define CFG_ENV_ADDR 0xFF9FA000 /* flash sector SA33 */
+#define CFG_ENV_SIZE 0x2000 /* Size of the Environment */
+#define CFG_ENV_OFFSET 0 /* starting right at the beginning */
+#define CFG_ENV_SECT_SIZE 0x2000 /* Size of the Environment Sector */
+
+
+#if CFG_MONITOR_BASE >= CFG_FLASH_BASE
+#undef CFG_RAMBOOT
+#else
+#define CFG_RAMBOOT
+#endif
+
+
+/*-----------------------------------------------------------------------
+ * Cache Configuration
+ */
+#define CFG_CACHELINE_SIZE 32
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+# define CFG_CACHELINE_SHIFT 5 /* log base 2 of the above value */
+#endif
+
+/*
+ * Internal Definitions
+ *
+ * Boot Flags
+ */
+#define BOOTFLAG_COLD 0x01 /* Normal Power-On: Boot from FLASH */
+#define BOOTFLAG_WARM 0x02 /* Software reboot */
+
+
+#endif /* __CONFIG_H */
--- /dev/null
+/*
+ * (C) Copyright 2001
+ * Erik Theisen, Wave 7 Optics, etheisen@mindspring.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
+ */
+
+/*
+ * Digital Thermometers and Thermostats.
+ */
+#ifndef _DTT_H_
+#define _DTT_H_
+
+#if defined(CONFIG_DTT_LM75) || defined(CONFIG_DTT_DS1621)
+#define CONFIG_DTT /* We have a DTT */
+
+#define DTT_COMMERCIAL_MAX_TEMP 70 /* 0 - +70 C */
+#define DTT_INDUSTRIAL_MAX_TEMP 85 /* -40 - +85 C */
+#define DTT_AUTOMOTIVE_MAX_TEMP 105 /* -40 - +105 C */
+#ifndef CFG_DTT_MAX_TEMP
+#define CFG_DTT_MAX_TEMP DTT_COMMERCIAL_MAX_TEMP
+#endif
+#ifndef CFG_DTT_HYSTERESIS
+#define CFG_DTT_HYSTERESIS 5 /* 5 C */
+#endif
+
+extern int dtt_init (void);
+extern int dtt_read(int sensor, int reg);
+extern int dtt_write(int sensor, int reg, int val);
+extern int dtt_get_temp(int sensor);
+#endif
+
+#if defined(CONFIG_DTT_LM75)
+#define DTT_READ_TEMP 0x0
+#define DTT_CONFIG 0x1
+#define DTT_TEMP_HYST 0x2
+#define DTT_TEMP_SET 0x3
+#endif
+
+#if defined(CONFIG_DTT_DS1621)
+#define DTT_READ_TEMP 0xAA
+#define DTT_READ_COUNTER 0xA8
+#define DTT_READ_SLOPE 0xA9
+#define DTT_WRITE_START_CONV 0xEE
+#define DTT_WRITE_STOP_CONV 0x22
+#define DTT_TEMP_HIGH 0xA1
+#define DTT_TEMP_LOW 0xA2
+#define DTT_CONFIG 0xAC
+#endif
+
+#endif /* _DTT_H_ */
--- /dev/null
+/*
+ * (C) Copyright 2002
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef _ENVIRONMENT_H_
+#define _ENVIRONMENT_H_ 1
+
+/**************************************************************************
+ *
+ * The "environment" is stored as a list of '\0' terminated
+ * "name=value" strings. The end of the list is marked by a double
+ * '\0'. New entries are always added at the end. Deleting an entry
+ * shifts the remaining entries to the front. Replacing an entry is a
+ * combination of deleting the old value and adding the new one.
+ *
+ * The environment is preceeded by a 32 bit CRC over the data part.
+ *
+ **************************************************************************
+ */
+
+#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_OFFSET
+# define CFG_ENV_OFFSET (CFG_ENV_ADDR - CFG_FLASH_BASE)
+# endif
+# if !defined(CFG_ENV_ADDR_REDUND) && defined(CFG_ENV_OFFSET_REDUND)
+# define CFG_ENV_ADDR_REDUND (CFG_FLASH_BASE + CFG_ENV_OFFSET_REDUND)
+# endif
+# ifndef CFG_ENV_SIZE
+# define CFG_ENV_SIZE CFG_ENV_SECT_SIZE
+# endif
+# if defined(CFG_ENV_ADDR_REDUND) && !defined(CFG_ENV_SIZE_REDUND)
+# define CFG_ENV_SIZE_REDUND CFG_ENV_SIZE
+# endif
+# if (CFG_ENV_ADDR >= CFG_MONITOR_BASE) && \
+ (CFG_ENV_ADDR+CFG_ENV_SIZE) <= (CFG_MONITOR_BASE + CFG_MONITOR_LEN)
+# define ENV_IS_EMBEDDED 1
+# endif
+# if defined(CFG_ENV_ADDR_REDUND) || defined(CFG_ENV_OFFSET_REDUND)
+# define CFG_REDUNDAND_ENVIRONMENT 1
+# endif
+#endif /* CFG_ENV_IS_IN_FLASH */
+
+
+#ifdef CFG_REDUNDAND_ENVIRONMENT
+# define ENV_HEADER_SIZE (sizeof(unsigned long) + 1)
+#else
+# define ENV_HEADER_SIZE (sizeof(unsigned long))
+#endif
+
+
+#define ENV_SIZE (CFG_ENV_SIZE - ENV_HEADER_SIZE)
+
+typedef struct environment_s {
+ unsigned long crc; /* CRC32 over data bytes */
+#ifdef CFG_REDUNDAND_ENVIRONMENT
+ unsigned char flags; /* active/obsolete flags */
+#endif
+ unsigned char data[ENV_SIZE]; /* Environment data */
+} env_t;
+
+#endif /* _ENVIRONMENT_H_ */
--- /dev/null
+#ifndef _LINUX_BYTEORDER_GENERIC_H
+#define _LINUX_BYTEORDER_GENERIC_H
+
+/*
+ * linux/byteorder_generic.h
+ * Generic Byte-reordering support
+ *
+ * Francois-Rene Rideau <fare@tunes.org> 19970707
+ * gathered all the good ideas from all asm-foo/byteorder.h into one file,
+ * cleaned them up.
+ * I hope it is compliant with non-GCC compilers.
+ * I decided to put __BYTEORDER_HAS_U64__ in byteorder.h,
+ * because I wasn't sure it would be ok to put it in types.h
+ * Upgraded it to 2.1.43
+ * Francois-Rene Rideau <fare@tunes.org> 19971012
+ * Upgraded it to 2.1.57
+ * to please Linus T., replaced huge #ifdef's between little/big endian
+ * by nestedly #include'd files.
+ * Francois-Rene Rideau <fare@tunes.org> 19971205
+ * Made it to 2.1.71; now a facelift:
+ * Put files under include/linux/byteorder/
+ * Split swab from generic support.
+ *
+ * TODO:
+ * = Regular kernel maintainers could also replace all these manual
+ * byteswap macros that remain, disseminated among drivers,
+ * after some grep or the sources...
+ * = Linus might want to rename all these macros and files to fit his taste,
+ * to fit his personal naming scheme.
+ * = it seems that a few drivers would also appreciate
+ * nybble swapping support...
+ * = every architecture could add their byteswap macro in asm/byteorder.h
+ * see how some architectures already do (i386, alpha, ppc, etc)
+ * = cpu_to_beXX and beXX_to_cpu might some day need to be well
+ * distinguished throughout the kernel. This is not the case currently,
+ * since little endian, big endian, and pdp endian machines needn't it.
+ * But this might be the case for, say, a port of Linux to 20/21 bit
+ * architectures (and F21 Linux addict around?).
+ */
+
+/*
+ * The following macros are to be defined by <asm/byteorder.h>:
+ *
+ * Conversion of long and short int between network and host format
+ * ntohl(__u32 x)
+ * ntohs(__u16 x)
+ * htonl(__u32 x)
+ * htons(__u16 x)
+ * It seems that some programs (which? where? or perhaps a standard? POSIX?)
+ * might like the above to be functions, not macros (why?).
+ * if that's true, then detect them, and take measures.
+ * Anyway, the measure is: define only ___ntohl as a macro instead,
+ * and in a separate file, have
+ * unsigned long inline ntohl(x){return ___ntohl(x);}
+ *
+ * The same for constant arguments
+ * __constant_ntohl(__u32 x)
+ * __constant_ntohs(__u16 x)
+ * __constant_htonl(__u32 x)
+ * __constant_htons(__u16 x)
+ *
+ * Conversion of XX-bit integers (16- 32- or 64-)
+ * between native CPU format and little/big endian format
+ * 64-bit stuff only defined for proper architectures
+ * cpu_to_[bl]eXX(__uXX x)
+ * [bl]eXX_to_cpu(__uXX x)
+ *
+ * The same, but takes a pointer to the value to convert
+ * cpu_to_[bl]eXXp(__uXX x)
+ * [bl]eXX_to_cpup(__uXX x)
+ *
+ * The same, but change in situ
+ * cpu_to_[bl]eXXs(__uXX x)
+ * [bl]eXX_to_cpus(__uXX x)
+ *
+ * See asm-foo/byteorder.h for examples of how to provide
+ * architecture-optimized versions
+ *
+ */
+
+
+#if defined(__KERNEL__)
+/*
+ * inside the kernel, we can use nicknames;
+ * outside of it, we must avoid POSIX namespace pollution...
+ */
+#define cpu_to_le64 __cpu_to_le64
+#define le64_to_cpu __le64_to_cpu
+#define cpu_to_le32 __cpu_to_le32
+#define le32_to_cpu __le32_to_cpu
+#define cpu_to_le16 __cpu_to_le16
+#define le16_to_cpu __le16_to_cpu
+#define cpu_to_be64 __cpu_to_be64
+#define be64_to_cpu __be64_to_cpu
+#define cpu_to_be32 __cpu_to_be32
+#define be32_to_cpu __be32_to_cpu
+#define cpu_to_be16 __cpu_to_be16
+#define be16_to_cpu __be16_to_cpu
+#define cpu_to_le64p __cpu_to_le64p
+#define le64_to_cpup __le64_to_cpup
+#define cpu_to_le32p __cpu_to_le32p
+#define le32_to_cpup __le32_to_cpup
+#define cpu_to_le16p __cpu_to_le16p
+#define le16_to_cpup __le16_to_cpup
+#define cpu_to_be64p __cpu_to_be64p
+#define be64_to_cpup __be64_to_cpup
+#define cpu_to_be32p __cpu_to_be32p
+#define be32_to_cpup __be32_to_cpup
+#define cpu_to_be16p __cpu_to_be16p
+#define be16_to_cpup __be16_to_cpup
+#define cpu_to_le64s __cpu_to_le64s
+#define le64_to_cpus __le64_to_cpus
+#define cpu_to_le32s __cpu_to_le32s
+#define le32_to_cpus __le32_to_cpus
+#define cpu_to_le16s __cpu_to_le16s
+#define le16_to_cpus __le16_to_cpus
+#define cpu_to_be64s __cpu_to_be64s
+#define be64_to_cpus __be64_to_cpus
+#define cpu_to_be32s __cpu_to_be32s
+#define be32_to_cpus __be32_to_cpus
+#define cpu_to_be16s __cpu_to_be16s
+#define be16_to_cpus __be16_to_cpus
+#endif
+
+
+/*
+ * Handle ntohl and suches. These have various compatibility
+ * issues - like we want to give the prototype even though we
+ * also have a macro for them in case some strange program
+ * wants to take the address of the thing or something..
+ *
+ * Note that these used to return a "long" in libc5, even though
+ * long is often 64-bit these days.. Thus the casts.
+ *
+ * They have to be macros in order to do the constant folding
+ * correctly - if the argument passed into a inline function
+ * it is no longer constant according to gcc..
+ */
+
+#undef ntohl
+#undef ntohs
+#undef htonl
+#undef htons
+
+/*
+ * Do the prototypes. Somebody might want to take the
+ * address or some such sick thing..
+ */
+#if defined(__KERNEL__) || (defined (__GLIBC__) && __GLIBC__ >= 2)
+extern __u32 ntohl(__u32);
+extern __u32 htonl(__u32);
+#else
+extern unsigned long int ntohl(unsigned long int);
+extern unsigned long int htonl(unsigned long int);
+#endif
+extern unsigned short int ntohs(unsigned short int);
+extern unsigned short int htons(unsigned short int);
+
+
+#if defined(__GNUC__) && (__GNUC__ >= 2)
+
+#define ___htonl(x) __cpu_to_be32(x)
+#define ___htons(x) __cpu_to_be16(x)
+#define ___ntohl(x) __be32_to_cpu(x)
+#define ___ntohs(x) __be16_to_cpu(x)
+
+#if defined(__KERNEL__) || (defined (__GLIBC__) && __GLIBC__ >= 2)
+#define htonl(x) ___htonl(x)
+#define ntohl(x) ___ntohl(x)
+#else
+#define htonl(x) ((unsigned long)___htonl(x))
+#define ntohl(x) ((unsigned long)___ntohl(x))
+#endif
+#define htons(x) ___htons(x)
+#define ntohs(x) ___ntohs(x)
+
+#endif /* OPTIMIZE */
+
+
+#endif /* _LINUX_BYTEORDER_GENERIC_H */
--- /dev/null
+/*
+ * Copyright Rob Taylor, Flying Pig Systems Ltd. 2000.
+ * Copyright (C) 2001, James Dougherty, jfd@cs.stanford.edu
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef __MPC824X_H__
+#define __MPC824X_H__
+
+#include <config.h>
+
+/* CPU Types */
+#define CPU_TYPE_601 0x01 /* PPC 601 CPU */
+#define CPU_TYPE_602 0x02 /* PPC 602 CPU */
+#define CPU_TYPE_603 0x03 /* PPC 603 CPU */
+#define CPU_TYPE_603E 0x06 /* PPC 603e CPU */
+#define CPU_TYPE_603P 0x07 /* PPC 603p CPU */
+#define CPU_TYPE_604 0x04 /* PPC 604 CPU */
+#define CPU_TYPE_604E 0x09 /* PPC 604e CPU */
+#define CPU_TYPE_604R 0x0a /* PPC 604r CPU */
+#define CPU_TYPE_750 0x08 /* PPC 750 CPU */
+#define CPU_TYPE_8240 0x81 /* PPC 8240 CPU */
+#define CPU_TYPE_8245 0x8081 /* PPC 8245/8241 CPU */
+#define _CACHE_ALIGN_SIZE 32 /* cache line size */
+
+/* spr976 - DMISS data tlb miss address register
+ * spr977 - DCMP data tlb miss compare register
+ * spr978 - HASH1 PTEG1 address register
+ * spr980 - HASH2 PTEG2 address register
+ * IMISS - instruction tlb miss address register
+ * ICMP - instruction TLB mis compare register
+ * RPA - real page address register
+ * HID0 - hardware implemntation register
+ * HID2 - instruction address breakpoint register
+ */
+
+/* Kahlua/MPC8240 defines */
+#define VEN_DEV_ID 0x00021057 /* Vendor and Dev. ID for MPC106 */
+#define KAHLUA_ID 0x00031057 /* Vendor & Dev Id for Kahlua's PCI */
+#define KAHLUA2_ID 0x00061057 /* 8245 is aka Kahlua-2 */
+#define BMC_BASE 0x80000000 /* Kahlua ID in PCI Memory space */
+#define CHRP_REG_ADDR 0xfec00000 /* MPC107 Config, Map B */
+#define CHRP_REG_DATA 0xfee00000 /* MPC107 Config, Map B */
+#define CHRP_ISA_MEM_PHYS 0xfd000000
+#define CHRP_ISA_MEM_BUS 0x00000000
+#define CHRP_ISA_MEM_SIZE 0x01000000
+#define CHRP_ISA_IO_PHYS 0xfe000000
+#define CHRP_ISA_IO_BUS 0x00000000
+#define CHRP_ISA_IO_SIZE 0x00800000
+#define CHRP_PCI_IO_PHYS 0xfe800000
+#define CHRP_PCI_IO_BUS 0x00800000
+#define CHRP_PCI_IO_SIZE 0x00400000
+#define CHRP_PCI_MEM_PHYS 0x80000000
+#define CHRP_PCI_MEM_BUS 0x80000000
+#define CHRP_PCI_MEM_SIZE 0x7d000000
+#define CHRP_PCI_MEMORY_PHYS 0x00000000
+#define CHRP_PCI_MEMORY_BUS 0x00000000
+#define CHRP_PCI_MEMORY_SIZE 0x40000000
+#define PREP_REG_ADDR 0x80000cf8 /* MPC107 Config, Map A */
+#define PREP_REG_DATA 0x80000cfc /* MPC107 Config, Map A */
+#define PREP_ISA_IO_PHYS 0x80000000
+#define PREP_ISA_IO_BUS 0x00000000
+#define PREP_ISA_IO_SIZE 0x00800000
+#define PREP_PCI_IO_PHYS 0x81000000
+#define PREP_PCI_IO_BUS 0x01000000
+#define PREP_PCI_IO_SIZE 0x3e800000
+#define PREP_PCI_MEM_PHYS 0xc0000000
+#define PREP_PCI_MEM_BUS 0x00000000
+#define PREP_PCI_MEM_SIZE 0x3f000000
+#define PREP_PCI_MEMORY_PHYS 0x00000000
+#define PREP_PCI_MEMORY_BUS 0x80000000
+#define PREP_PCI_MEMORY_SIZE 0x80000000
+#define MPC107_PCI_CMD 0x80000004 /* MPC107 PCI cmd reg */
+#define MPC107_PCI_STAT 0x80000006 /* MPC107 PCI status reg */
+#define PROC_INT1_ADR 0x800000a8 /* MPC107 Processor i/f cfg1 */
+#define PROC_INT2_ADR 0x800000ac /* MPC107 Processor i/f cfg2 */
+#define MEM_CONT1_ADR 0x800000f0 /* MPC107 Memory control config. 1 */
+#define MEM_CONT2_ADR 0x800000f4 /* MPC107 Memory control config. 2 */
+#define MEM_CONT3_ADR 0x800000f8 /* MPC107 Memory control config. 3 */
+#define MEM_CONT4_ADR 0x800000fc /* MPC107 Memory control config. 4 */
+#define MEM_ERREN1_ADR 0x800000c0 /* MPC107 Memory error enable 1 */
+#define MEM_START1_ADR 0x80000080 /* MPC107 Memory starting addr */
+#define MEM_START2_ADR 0x80000084 /* MPC107 Memory starting addr-lo */
+#define XMEM_START1_ADR 0x80000088 /* MPC107 Extended mem. start addr-hi*/
+#define XMEM_START2_ADR 0x8000008c /* MPC107 Extended mem. start addr-lo*/
+#define MEM_END1_ADR 0x80000090 /* MPC107 Memory ending address */
+#define MEM_END2_ADR 0x80000094 /* MPC107 Memory ending addr-lo */
+#define XMEM_END1_ADR 0x80000098 /* MPC107 Extended mem. end addrs-hi */
+#define XMEM_END2_ADR 0x8000009c /* MPC107 Extended mem. end addrs-lo*/
+#define OUT_DRV_CONT 0x80000073 /* MPC107 Output Driver Control reg */
+#define MEM_EN_ADR 0x800000a0 /* Memory bank enable */
+#define PAGE_MODE 0x800000a3 /* MPC107 Page Mode Counter/Timer */
+
+/*-----------------------------------------------------------------------
+ * Exception offsets (PowerPC standard)
+ */
+#define EXC_OFF_RESERVED0 0x0000 /* Reserved */
+#define EXC_OFF_SYS_RESET 0x0100 /* System reset */
+#define EXC_OFF_MACH_CHCK 0x0200 /* Machine Check */
+#define EXC_OFF_DATA_STOR 0x0300 /* Data Storage */
+#define EXC_OFF_INS_STOR 0x0400 /* Instruction Storage */
+#define EXC_OFF_EXTERNAL 0x0500 /* External */
+#define EXC_OFF_ALIGN 0x0600 /* Alignment */
+#define EXC_OFF_PROGRAM 0x0700 /* Program */
+#define EXC_OFF_FPUNAVAIL 0x0800 /* Floating-point Unavailable */
+#define EXC_OFF_DECR 0x0900 /* Decrementer */
+#define EXC_OFF_RESERVED1 0x0A00 /* Reserved */
+#define EXC_OFF_RESERVED2 0x0B00 /* Reserved */
+#define EXC_OFF_SYS_CALL 0x0C00 /* System Call */
+#define EXC_OFF_TRACE 0x0D00 /* Trace */
+#define EXC_OFF_FPUNASSIST 0x0E00 /* Floating-point Assist */
+
+ /* 0x0E10 - 0x0FFF are marked reserved in The PowerPC Architecture book */
+ /* these found in DINK code - may not apply to 8240*/
+#define EXC_OFF_PMI 0x0F00 /* Performance Monitoring Interrupt */
+#define EXC_OFF_VMXUI 0x0F20 /* VMX (AltiVec) Unavailable Interrupt */
+
+ /* 0x1000 - 0x2FFF are implementation specific */
+ /* these found in DINK code - may not apply to 8240 */
+#define EXC_OFF_ITME 0x1000 /* Instruction Translation Miss Exception */
+#define EXC_OFF_DLTME 0x1100 /* Data Load Translation Miss Exception */
+#define EXC_OFF_DSTME 0x1200 /* Data Store Translation Miss Exception */
+#define EXC_OFF_IABE 0x1300 /* Instruction Addr Breakpoint Exception */
+#define EXC_OFF_SMIE 0x1400 /* System Management Interrupt Exception */
+#define EXC_OFF_JMDDI 0x1600 /* Java Mode denorm detect Interr -- WTF??*/
+#define EXC_OFF_RMTE 0x2000 /* Run Mode or Trace Exception */
+
+#define MAP_A_CONFIG_ADDR_HIGH 0x8000 /* Upper half of CONFIG_ADDR for Map A */
+#define MAP_A_CONFIG_ADDR_LOW 0x0CF8 /* Lower half of CONFIG_ADDR for Map A */
+#define MAP_A_CONFIG_DATA_HIGH 0x8000 /* Upper half of CONFIG_DAT for Map A */
+#define MAP_A_CONFIG_DATA_LOW 0x0CFC /* Lower half of CONFIG_DAT for Map A */
+#define MAP_B_CONFIG_ADDR_HIGH 0xfec0 /* Upper half of CONFIG_ADDR for Map B */
+#define MAP_B_CONFIG_ADDR_LOW 0x0000 /* Lower half of CONFIG_ADDR for Map B */
+#define MAP_B_CONFIG_DATA_HIGH 0xfee0 /* Upper half of CONFIG_DAT for Map B */
+#define MAP_B_CONFIG_DATA_LOW 0x0000 /* Lower half of CONFIG_DAT for Map B */
+
+
+#if defined(CFG_ADDR_MAP_A)
+#define CONFIG_ADDR_HIGH MAP_A_CONFIG_ADDR_HIGH /* Upper half of CONFIG_ADDR */
+#define CONFIG_ADDR_LOW MAP_A_CONFIG_ADDR_LOW /* Lower half of CONFIG_ADDR */
+#define CONFIG_DATA_HIGH MAP_A_CONFIG_DATA_HIGH /* Upper half of CONFIG_DAT */
+#define CONFIG_DATA_LOW MAP_A_CONFIG_DATA_LOW /* Lower half of CONFIG_DAT */
+#else /* Assume Map B, default */
+#define CONFIG_ADDR_HIGH MAP_B_CONFIG_ADDR_HIGH /* Upper half of CONFIG_ADDR */
+#define CONFIG_ADDR_LOW MAP_B_CONFIG_ADDR_LOW /* Lower half of CONFIG_ADDR */
+#define CONFIG_DATA_HIGH MAP_B_CONFIG_DATA_HIGH /* Upper half of CONFIG_DAT */
+#define CONFIG_DATA_LOW MAP_B_CONFIG_DATA_LOW /* Lower half of CONFIG_DAT */
+#endif
+
+#define CONFIG_ADDR (CONFIG_ADDR_HIGH << 16 | CONFIG_ADDR_LOW)
+
+#define CONFIG_DATA (CONFIG_DATA_HIGH << 16 | CONFIG_DATA_LOW)
+
+/* Macros to write to config registers. addr should be a constant in all cases */
+
+#define CONFIG_WRITE_BYTE( addr, data ) \
+ __asm__ __volatile__( \
+ " stwbrx %1, 0, %0\n \
+ sync\n \
+ stb %3, %4(%2)\n \
+ sync " \
+ : /* no output */ \
+ : "r" (CONFIG_ADDR), "r" ((addr) & ~3), \
+ "b" (CONFIG_DATA), "r" (data), \
+ "n" ((addr) & 3));
+
+#define CONFIG_WRITE_HALFWORD( addr, data ) \
+ __asm__ __volatile__( \
+ " stwbrx %1, 0, %0\n \
+ sync\n \
+ sthbrx %3, %4, %2\n \
+ sync " \
+ : /* no output */ \
+ : "r" (CONFIG_ADDR), "r" ((addr) & ~3), \
+ "r" (CONFIG_DATA), "r" (data), \
+ "b" ((addr) & 3));
+
+/* this assumes it's writeing on word boundaries*/
+#define CONFIG_WRITE_WORD( addr, data ) \
+ __asm__ __volatile__( \
+ " stwbrx %1, 0, %0\n \
+ sync\n \
+ stwbrx %3, 0, %2\n \
+ sync " \
+ : /* no output */ \
+ : "r" (CONFIG_ADDR), "r" (addr), \
+ "r" (CONFIG_DATA), "r" (data));
+
+/* Configuration register reads*/
+
+#define CONFIG_READ_BYTE( addr, reg ) \
+ __asm__ ( \
+ " stwbrx %1, 0, %2\n \
+ sync\n \
+ lbz %0, %4(%3)\n \
+ sync " \
+ : "=r" (reg) \
+ : "r" ((addr) & ~3), "r" (CONFIG_ADDR), \
+ "b" (CONFIG_DATA), "n" ((addr) & 3));
+
+
+#define CONFIG_READ_HALFWORD( addr, reg ) \
+ __asm__ ( \
+ " stwbrx %1, 0, %2\n \
+ sync\n \
+ lhbrx %0, %4, %3\n \
+ sync " \
+ : "=r" (reg) \
+ : "r" ((addr) & ~3), "r" (CONFIG_ADDR), \
+ "r" (CONFIG_DATA), \
+ "b" ((addr) & 3));
+
+/* this assumes it's reading on word boundaries*/
+#define CONFIG_READ_WORD( addr, reg ) \
+ __asm__ ( \
+ " stwbrx %1, 0, %2\n \
+ sync\n \
+ lwbrx %0, 0, %3\n \
+ sync " \
+ : "=r" (reg) \
+ : "r" (addr), "r" (CONFIG_ADDR),\
+ "r" (CONFIG_DATA));
+
+/*
+ * configuration register 'addresses'.
+ * These are described in chaper 5 of the 8240 users manual.
+ * Where the register has an abreviation in the manual, this has
+ * been usaed here, otherwise a name in keeping with the norm has
+ * been invented.
+ * Note that some of these registers aren't documented in the manual.
+ */
+
+#define PCICR 0x80000004 /* PCI Command Register */
+#define PCISR 0x80000006 /* PCI Status Register */
+#define REVID 0x80000008 /* CPU revision id */
+#define PIR 0x80000009 /* PCI Programming Interface Register */
+#define PBCCR 0x8000000b /* PCI Base Class Code Register */
+#define PCLSR 0x8000000c /* Processor Cache Line Size Register */
+#define PLTR 0x8000000d /* PCI Latancy Timer Register */
+#define PHTR 0x8000000e /* PCI Header Type Register */
+#define BISTCTRL 0x8000000f /* BIST Control */
+#define LMBAR 0x80000010 /* Local Base Addres Register */
+#define PCSRBAR 0x80000014 /* PCSR Base Address Register */
+#define ILR 0x8000003c /* PCI Interrupt Line Register */
+#define IPR 0x8000003d /* Interrupt Pin Register */
+#define MINGNT 0x8000003e /* MIN GNI */
+#define MAXLAT 0x8000003f /* MAX LAT */
+#define PCIACR 0x80000046 /* PCI Arbiter Control Register */
+#define PMCR1 0x80000070 /* Power management config. 1 */
+#define PMCR2 0x80000072 /* Power management config. 2 */
+#define ODCR 0x80000073 /* Output Driver Control Register */
+#define CLKDCR 0x80000074 /* CLK Driver Control Register */
+#if defined(CONFIG_MPC8245) || defined(CONFIG_MPC8241)
+#define MIOCR1 0x80000076 /* Miscellaneous I/O Control Register 1 */
+#define MIOCR2 0x80000077 /* Miscellaneous I/O Control Register 2 */
+#endif
+#define EUMBBAR 0x80000078 /* Embedded Utilities Memory Block Base Address Register */
+#define EUMBBAR_VAL 0x80500000 /* PCI Relocation offset for EUMB region */
+#define EUMBSIZE 0x00100000 /* Size of EUMB region */
+
+#define MSAR1 0x80000080 /* Memory Starting Address Register 1 */
+#define MSAR2 0x80000084 /* Memory Starting Address Register 2 */
+#define EMSAR1 0x80000088 /* Extended Memory Starting Address Register 1*/
+#define EMSAR2 0x8000008c /* Extended Memory Starting Address Register 2*/
+#define MEAR1 0x80000090 /* Memory Ending Address Register 1 */
+#define MEAR2 0x80000094 /* Memory Ending Address Register 2 */
+#define EMEAR1 0x80000098 /* Extended Memory Ending Address Register 1 */
+#define EMEAR2 0x8000009c /* Extended Memory Ending Address Register 2 */
+#define MBER 0x800000a0 /* Memory bank Enable Register*/
+#define MPMR 0x800000a3 /* Memory Page Mode Register (stores PGMAX) */
+#define PICR1 0x800000a8 /* Processor Interface Configuration Register 1 */
+#define PICR2 0x800000ac /* Processor Interface Configuration Register 2 */
+#define ECCSBECR 0x800000b8 /* ECC Single-Bit Error Counter Register */
+#define ECCSBETR 0x800000b8 /* ECC Single-Bit Error Trigger Register */
+#define ERRENR1 0x800000c0 /* Error Enableing Register 1 */
+#define ERRENR2 0x800000c4 /* Error Enableing Register 2 */
+#define ERRDR1 0x800000c1 /* Error Detection Register 1 */
+#define IPBESR 0x800000c3 /* Internal Processor Error Status Register */
+#define ERRDR2 0x800000c5 /* Error Detection Register 2 */
+#define PBESR 0x800000c7 /* PCI Bus Error Status Register */
+#define PBEAR 0x800000c8 /* Processor/PCI Bus Error Status Register */
+#define AMBOR 0x800000e0 /* Address Map B Options Register */
+#define MCCR1 0x800000f0 /* Memory Control Configuration Register 1 */
+#define MCCR2 0x800000f4 /* Memory Control Configuration Register 2 */
+#define MCCR3 0x800000f8 /* Memory Control Configuration Register 3 */
+#define MCCR4 0x800000fc /* Memory Control Configuration Register 4 */
+
+/* some values for some of the above */
+
+#define PICR1_CF_APARK 0x00000008
+#define PICR1_LE_MODE 0x00000020
+#define PICR1_ST_GATH_EN 0x00000040
+#if defined(CONFIG_MPC8240)
+#define PICR1_EN_PCS 0x00000080 /* according to dink code, sets the 8240 to handle pci config space */
+#elif defined(CONFIG_MPC8245) || defined(CONFIG_MPC8241)
+#define PICR1_NO_BUSW_CK 0x00000080 /* no bus width check for flash writes */
+#define PICR1_DEC 0x00000100 /* Time Base enable on 8245/8241 */
+#define ERCR1 0x800000d0 /* Extended ROM Configuration Register 1 */
+#define ERCR2 0x800000d4 /* Extended ROM Configuration Register 2 */
+#define ERCR3 0x800000d8 /* Extended ROM Configuration Register 3 */
+#define ERCR4 0x800000dc /* Extended ROM Configuration Register 4 */
+#define MIOCR1 0x80000076 /* Miscellaneous I/O Control Register 1 */
+#define MIOCR1_ADR_X 0x80000074 /* Miscellaneous I/O Control Register 1 */
+#define MIOCR1_SHIFT 2
+#define MIOCR2 0x80000077 /* Miscellaneous I/O Control Register 2 */
+#define MIOCR2_ADR_X 0x80000074 /* Miscellaneous I/O Control Register 1 */
+#define MIOCR2_SHIFT 3
+#define ODCR_ADR_X 0x80000070 /* Output Driver Control register */
+#define ODCR_SHIFT 3
+#define PMCR2_ADR 0x80000072 /* Power Mgmnt Cfg 2 register */
+#define PMCR2_ADR_X 0x80000070
+#define PMCR2_SHIFT 3
+#define PMCR1_ADR 0x80000070 /* Power Mgmnt Cfg 1 reister */
+#else
+#error Specific type of MPC824x must be defined (i.e. CONFIG_MPC8240)
+#endif
+#define PICR1_CF_DPARK 0x00000200
+#define PICR1_MCP_EN 0x00000800
+#define PICR1_FLASH_WR_EN 0x00001000
+#ifdef CONFIG_MPC8240
+#define PICR1_ADDRESS_MAP 0x00010000
+#define PIRC1_MSK 0xff000000
+#endif
+#define PICR1_PROC_TYPE_MSK 0x00060000
+#define PICR1_PROC_TYPE_603E 0x00040000
+#define PICR1_RCS0 0x00100000
+
+#define PICR2_CF_SNOOP_WS_MASK 0x000c0000
+#define PICR2_CF_SNOOP_WS_0WS 0x00000000
+#define PICR2_CF_SNOOP_WS_1WS 0x00040000
+#define PICR2_CF_SNOOP_WS_2WS 0x00080000
+#define PICR2_CF_SNOOP_WS_3WS 0x000c0000
+#define PICR2_CF_APHASE_WS_MASK 0x0000000c
+#define PICR2_CF_APHASE_WS_0WS 0x00000000
+#define PICR2_CF_APHASE_WS_1WS 0x00000004
+#define PICR2_CF_APHASE_WS_2WS 0x00000008
+#define PICR2_CF_APHASE_WS_3WS 0x0000000c
+
+#define MCCR1_ROMNAL_SHIFT 28
+#define MCCR1_ROMNAL_MSK 0xf0000000
+#define MCCR1_ROMFAL_SHIFT 23
+#define MCCR1_ROMFAL_MSK 0x0f800000
+#define MCCR1_DBUS_SIZE0 0x00400000
+#define MCCR1_BURST 0x00100000
+#define MCCR1_MEMGO 0x00080000
+#define MCCR1_SREN 0x00040000
+#if defined(CONFIG_MPC8240)
+#define MCCR1_RAM_TYPE 0x00020000
+#elif defined(CONFIG_MPC8245) || defined(CONFIG_MPC8241)
+#define MCCR1_SDRAM_EN 0x00020000
+#else
+#error Specific type of MPC824x must be defined (i.e. CONFIG_MPC8240)
+#endif
+#define MCCR1_PCKEN 0x00010000
+#define MCCR1_BANK1ROW_SHIFT 2
+#define MCCR1_BANK2ROW_SHIFT 4
+#define MCCR1_BANK3ROW_SHIFT 6
+#define MCCR1_BANK4ROW_SHIFT 8
+#define MCCR1_BANK5ROW_SHIFT 10
+#define MCCR1_BANK6ROW_SHIFT 12
+#define MCCR1_BANK7ROW_SHIFT 14
+
+#define MCCR2_TS_WAIT_TIMER_MSK 0xe0000000
+#define MCCR2_TS_WAIT_TIMER_SHIFT 29
+#define MCCR2_ASRISE_MSK 0x1e000000
+#define MCCR2_ASRISE_SHIFT 25
+#define MCCR2_ASFALL_MSK 0x01e00000
+#define MCCR2_ASFALL_SHIFT 21
+
+#define MCCR2_INLINE_PAR_NOT_ECC 0x00100000
+#define MCCR2_WRITE_PARITY_CHK 0x00080000
+#define MCCR2_INLFRD_PARECC_CHK_EN 0x00040000
+#ifdef CONFIG_MPC8240
+#define MCCR2_ECC_EN 0x00020000
+#define MCCR2_EDO 0x00010000
+#endif
+#define MCCR2_REFINT_MSK 0x0000fffc
+#define MCCR2_REFINT_SHIFT 2
+#define MCCR2_RSV_PG 0x00000002
+#define MCCR2_PMW_PAR 0x00000001
+
+#define MCCR3_BSTOPRE2TO5_MSK 0xf0000000 /*BSTOPRE[2-5]*/
+#define MCCR3_BSTOPRE2TO5_SHIFT 28
+#define MCCR3_REFREC_MSK 0x0f000000
+#define MCCR3_REFREC_SHIFT 24
+#ifdef CONFIG_MPC8240
+#define MCCR3_RDLAT_MSK 0x00f00000
+#define MCCR3_RDLAT_SHIFT 20
+#define MCCR3_CPX 0x00010000
+#define MCCR3_RAS6P_MSK 0x00078000
+#define MCCR3_RAS6P_SHIFT 15
+#define MCCR3_CAS5_MSK 0x00007000
+#define MCCR3_CAS5_SHIFT 12
+#define MCCR3_CP4_MSK 0x00000e00
+#define MCCR3_CP4_SHIFT 9
+#define MCCR3_CAS3_MSK 0x000001c0
+#define MCCR3_CAS3_SHIFT 6
+#define MCCR3_RCD2_MSK 0x00000038
+#define MCCR3_RCD2_SHIFT 3
+#define MCCR3_RP1_MSK 0x00000007
+#define MCCR3_RP1_SHIFT 0
+#endif
+
+#define MCCR4_PRETOACT_MSK 0xf0000000
+#define MCCR4_PRETOACT_SHIFT 28
+#define MCCR4_ACTTOPRE_MSK 0x0f000000
+#define MCCR4_ACTTOPRE_SHIFT 24
+#define MCCR4_WMODE 0x00800000
+#define MCCR4_INLINE 0x00400000
+#if defined(CONFIG_MPC8240)
+#define MCCR4_BIT21 0x00200000 /* this include cos DINK code sets it- unknown function*/
+#elif defined(CONFIG_MPC8245) || defined(CONFIG_MPC8241)
+#define MCCR4_EXTROM 0x00200000 /* enables Extended ROM space */
+#else
+#error Specific type of MPC824x must be defined (i.e. CONFIG_MPC8240)
+#endif
+#define MCCR4_REGISTERED 0x00100000
+#define MCCR4_BSTOPRE0TO1_MSK 0x000c0000 /*BSTOPRE[0-1]*/
+#define MCCR4_BSTOPRE0TO1_SHIFT 18
+#define MCCR4_REGDIMM 0x00008000
+#define MCCR4_SDMODE_MSK 0x00007f00
+#define MCCR4_SDMODE_SHIFT 8
+#define MCCR4_ACTTORW_MSK 0x000000f0
+#define MCCR4_ACTTORW_SHIFT 4
+#define MCCR4_BSTOPRE6TO9_MSK 0x0000000f /*BSTOPRE[6-9]*/
+#define MCCR4_BSTOPRE6TO9_SHIFT 0
+#define MCCR4_DBUS_SIZE2_SHIFT 17
+
+#define MICR_ADDR_MASK 0x0ff00000
+#define MICR_ADDR_SHIFT 20
+#define MICR_EADDR_MASK 0x30000000
+#define MICR_EADDR_SHIFT 28
+
+#define BATU_BEPI_MSK 0xfffe0000
+#define BATU_BL_MSK 0x00001ffc
+
+#define BATU_BL_128K 0x00000000
+#define BATU_BL_256K 0x00000004
+#define BATU_BL_512K 0x0000000c
+#define BATU_BL_1M 0x0000001c
+#define BATU_BL_2M 0x0000003c
+#define BATU_BL_4M 0x0000007c
+#define BATU_BL_8M 0x000000fc
+#define BATU_BL_16M 0x000001fc
+#define BATU_BL_32M 0x000003fc
+#define BATU_BL_64M 0x000007fc
+#define BATU_BL_128M 0x00000ffc
+#define BATU_BL_256M 0x00001ffc
+
+#define BATU_VS 0x00000002
+#define BATU_VP 0x00000001
+
+#define BATL_BRPN_MSK 0xfffe0000
+#define BATL_WIMG_MSK 0x00000078
+
+#define BATL_WRITETHROUGH 0x00000040
+#define BATL_CACHEINHIBIT 0x00000020
+#define BATL_MEMCOHERENCE 0x00000010
+#define BATL_GUARDEDSTORAGE 0x00000008
+
+#define BATL_PP_MSK 0x00000003
+#define BATL_PP_00 0x00000000 /* No access */
+#define BATL_PP_01 0x00000001 /* Read-only */
+#define BATL_PP_10 0x00000002 /* Read-write */
+#define BATL_PP_11 0x00000003
+
+/*
+ * I'd attempt to do defines for the PP bits, but it's use is a bit
+ * too complex, see the PowerPC Operating Environment Architecture
+ * section in the PowerPc arch book, chapter 4.
+ */
+
+/*eumb and epic config*/
+
+#define EPIC_FPR 0x00041000
+#define EPIC_GCR 0x00041020
+#define EPIC_EICR 0x00041030
+#define EPIC_EVI 0x00041080
+#define EPIC_PI 0x00041090
+#define EPIC_SVR 0x000410E0
+#define EPIC_TFRR 0x000410F0
+
+/*
+ * Note the information for these is rather mangled in the 8240 manual.
+ * These are guesses.
+ */
+
+#define EPIC_GTCCR0 0x00041100
+#define EPIC_GTCCR1 0x00041140
+#define EPIC_GTCCR2 0x00041180
+#define EPIC_GTCCR3 0x000411C0
+#define EPIC_GTBCR0 0x00041110
+#define EPIC_GTBCR1 0x00041150
+#define EPIC_GTBCR2 0x00041190
+#define EPIC_GTBCR3 0x000411D0
+#define EPIC_GTVPR0 0x00041120
+#define EPIC_GTVPR1 0x00041160
+#define EPIC_GTVPR2 0x000411a0
+#define EPIC_GTVPR3 0x000411e0
+#define EPIC_GTDR0 0x00041130
+#define EPIC_GTDR1 0x00041170
+#define EPIC_GTDR2 0x000411b0
+#define EPIC_GTDR3 0x000411f0
+
+#define EPIC_IVPR0 0x00050200
+#define EPIC_IVPR1 0x00050220
+#define EPIC_IVPR2 0x00050240
+#define EPIC_IVPR3 0x00050260
+#define EPIC_IVPR4 0x00050280
+
+#define EPIC_SVPR0 0x00050200
+#define EPIC_SVPR1 0x00050220
+#define EPIC_SVPR2 0x00050240
+#define EPIC_SVPR3 0x00050260
+#define EPIC_SVPR4 0x00050280
+#define EPIC_SVPR5 0x000502A0
+#define EPIC_SVPR6 0x000502C0
+#define EPIC_SVPR7 0x000502E0
+#define EPIC_SVPR8 0x00050300
+#define EPIC_SVPR9 0x00050320
+#define EPIC_SVPRa 0x00050340
+#define EPIC_SVPRb 0x00050360
+#define EPIC_SVPRc 0x00050380
+#define EPIC_SVPRd 0x000503A0
+#define EPIC_SVPRe 0x000503C0
+#define EPIC_SVPRf 0x000503E0
+
+/* MPC8240 Byte Swap/PCI Support Macros */
+#define BYTE_SWAP_16_BIT(x) ( (((x) & 0x00ff) << 8) | ( (x) >> 8) )
+#define LONGSWAP(x) ((((x) & 0x000000ff) << 24) | (((x) & 0x0000ff00) << 8)|\
+ (((x) & 0x00ff0000) >> 8) | (((x) & 0xff000000) >> 24) )
+#define PCISWAP(x) LONGSWAP(x)
+
+#ifndef __ASSEMBLY__
+
+/*
+ * MPC107 Support
+ *
+ */
+unsigned int mpc824x_mpc107_getreg(unsigned int regNum);
+void mpc824x_mpc107_setreg(unsigned int regNum, unsigned int regVal);
+void mpc824x_mpc107_write8(unsigned int address, unsigned char data);
+void mpc824x_mpc107_write16(unsigned int address, unsigned short data);
+void mpc824x_mpc107_write32(unsigned int address, unsigned int data);
+unsigned char mpc824x_mpc107_read8(unsigned int address);
+unsigned short mpc824x_mpc107_read16(unsigned int address);
+unsigned int mpc824x_mpc107_read32(unsigned int address);
+unsigned int mpc824x_eummbar_read(unsigned int regNum);
+void mpc824x_eummbar_write(unsigned int regNum, unsigned int regVal);
+
+#ifdef CONFIG_PCI
+struct pci_controller;
+void pci_cpm824x_init(struct pci_controller* hose);
+#endif
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* __MPC824X_H__ */
--- /dev/null
+/*
+ * (C) Copyright 2001 Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Andreas Heppel <aheppel@sysgo.de>
+ *
+ * (C) Copyright 2002
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * aloong with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef _PCI_H
+#define _PCI_H
+
+/*
+ * Under PCI, each device has 256 bytes of configuration address space,
+ * of which the first 64 bytes are standardized as follows:
+ */
+#define PCI_VENDOR_ID 0x00 /* 16 bits */
+#define PCI_DEVICE_ID 0x02 /* 16 bits */
+#define PCI_COMMAND 0x04 /* 16 bits */
+#define PCI_COMMAND_IO 0x1 /* Enable response in I/O space */
+#define PCI_COMMAND_MEMORY 0x2 /* Enable response in Memory space */
+#define PCI_COMMAND_MASTER 0x4 /* Enable bus mastering */
+#define PCI_COMMAND_SPECIAL 0x8 /* Enable response to special cycles */
+#define PCI_COMMAND_INVALIDATE 0x10 /* Use memory write and invalidate */
+#define PCI_COMMAND_VGA_PALETTE 0x20 /* Enable palette snooping */
+#define PCI_COMMAND_PARITY 0x40 /* Enable parity checking */
+#define PCI_COMMAND_WAIT 0x80 /* Enable address/data stepping */
+#define PCI_COMMAND_SERR 0x100 /* Enable SERR */
+#define PCI_COMMAND_FAST_BACK 0x200 /* Enable back-to-back writes */
+
+#define PCI_STATUS 0x06 /* 16 bits */
+#define PCI_STATUS_CAP_LIST 0x10 /* Support Capability List */
+#define PCI_STATUS_66MHZ 0x20 /* Support 66 Mhz PCI 2.1 bus */
+#define PCI_STATUS_UDF 0x40 /* Support User Definable Features [obsolete] */
+#define PCI_STATUS_FAST_BACK 0x80 /* Accept fast-back to back */
+#define PCI_STATUS_PARITY 0x100 /* Detected parity error */
+#define PCI_STATUS_DEVSEL_MASK 0x600 /* DEVSEL timing */
+#define PCI_STATUS_DEVSEL_FAST 0x000
+#define PCI_STATUS_DEVSEL_MEDIUM 0x200
+#define PCI_STATUS_DEVSEL_SLOW 0x400
+#define PCI_STATUS_SIG_TARGET_ABORT 0x800 /* Set on target abort */
+#define PCI_STATUS_REC_TARGET_ABORT 0x1000 /* Master ack of " */
+#define PCI_STATUS_REC_MASTER_ABORT 0x2000 /* Set on master abort */
+#define PCI_STATUS_SIG_SYSTEM_ERROR 0x4000 /* Set when we drive SERR */
+#define PCI_STATUS_DETECTED_PARITY 0x8000 /* Set on parity error */
+
+#define PCI_CLASS_REVISION 0x08 /* High 24 bits are class, low 8
+ revision */
+#define PCI_REVISION_ID 0x08 /* Revision ID */
+#define PCI_CLASS_PROG 0x09 /* Reg. Level Programming Interface */
+#define PCI_CLASS_DEVICE 0x0a /* Device class */
+#define PCI_CLASS_CODE 0x0b /* Device class code */
+#define PCI_CLASS_SUB_CODE 0x0a /* Device sub-class code */
+
+#define PCI_CACHE_LINE_SIZE 0x0c /* 8 bits */
+#define PCI_LATENCY_TIMER 0x0d /* 8 bits */
+#define PCI_HEADER_TYPE 0x0e /* 8 bits */
+#define PCI_HEADER_TYPE_NORMAL 0
+#define PCI_HEADER_TYPE_BRIDGE 1
+#define PCI_HEADER_TYPE_CARDBUS 2
+
+#define PCI_BIST 0x0f /* 8 bits */
+#define PCI_BIST_CODE_MASK 0x0f /* Return result */
+#define PCI_BIST_START 0x40 /* 1 to start BIST, 2 secs or less */
+#define PCI_BIST_CAPABLE 0x80 /* 1 if BIST capable */
+
+/*
+ * Base addresses specify locations in memory or I/O space.
+ * Decoded size can be determined by writing a value of
+ * 0xffffffff to the register, and reading it back. Only
+ * 1 bits are decoded.
+ */
+#define PCI_BASE_ADDRESS_0 0x10 /* 32 bits */
+#define PCI_BASE_ADDRESS_1 0x14 /* 32 bits [htype 0,1 only] */
+#define PCI_BASE_ADDRESS_2 0x18 /* 32 bits [htype 0 only] */
+#define PCI_BASE_ADDRESS_3 0x1c /* 32 bits */
+#define PCI_BASE_ADDRESS_4 0x20 /* 32 bits */
+#define PCI_BASE_ADDRESS_5 0x24 /* 32 bits */
+#define PCI_BASE_ADDRESS_SPACE 0x01 /* 0 = memory, 1 = I/O */
+#define PCI_BASE_ADDRESS_SPACE_IO 0x01
+#define PCI_BASE_ADDRESS_SPACE_MEMORY 0x00
+#define PCI_BASE_ADDRESS_MEM_TYPE_MASK 0x06
+#define PCI_BASE_ADDRESS_MEM_TYPE_32 0x00 /* 32 bit address */
+#define PCI_BASE_ADDRESS_MEM_TYPE_1M 0x02 /* Below 1M [obsolete] */
+#define PCI_BASE_ADDRESS_MEM_TYPE_64 0x04 /* 64 bit address */
+#define PCI_BASE_ADDRESS_MEM_PREFETCH 0x08 /* prefetchable? */
+#define PCI_BASE_ADDRESS_MEM_MASK (~0x0fUL)
+#define PCI_BASE_ADDRESS_IO_MASK (~0x03UL)
+/* bit 1 is reserved if address_space = 1 */
+
+/* Header type 0 (normal devices) */
+#define PCI_CARDBUS_CIS 0x28
+#define PCI_SUBSYSTEM_VENDOR_ID 0x2c
+#define PCI_SUBSYSTEM_ID 0x2e
+#define PCI_ROM_ADDRESS 0x30 /* Bits 31..11 are address, 10..1 reserved */
+#define PCI_ROM_ADDRESS_ENABLE 0x01
+#define PCI_ROM_ADDRESS_MASK (~0x7ffUL)
+
+#define PCI_CAPABILITY_LIST 0x34 /* Offset of first capability list entry */
+
+/* 0x35-0x3b are reserved */
+#define PCI_INTERRUPT_LINE 0x3c /* 8 bits */
+#define PCI_INTERRUPT_PIN 0x3d /* 8 bits */
+#define PCI_MIN_GNT 0x3e /* 8 bits */
+#define PCI_MAX_LAT 0x3f /* 8 bits */
+
+/* Header type 1 (PCI-to-PCI bridges) */
+#define PCI_PRIMARY_BUS 0x18 /* Primary bus number */
+#define PCI_SECONDARY_BUS 0x19 /* Secondary bus number */
+#define PCI_SUBORDINATE_BUS 0x1a /* Highest bus number behind the bridge */
+#define PCI_SEC_LATENCY_TIMER 0x1b /* Latency timer for secondary interface */
+#define PCI_IO_BASE 0x1c /* I/O range behind the bridge */
+#define PCI_IO_LIMIT 0x1d
+#define PCI_IO_RANGE_TYPE_MASK 0x0f /* I/O bridging type */
+#define PCI_IO_RANGE_TYPE_16 0x00
+#define PCI_IO_RANGE_TYPE_32 0x01
+#define PCI_IO_RANGE_MASK ~0x0f
+#define PCI_SEC_STATUS 0x1e /* Secondary status register, only bit 14 used */
+#define PCI_MEMORY_BASE 0x20 /* Memory range behind */
+#define PCI_MEMORY_LIMIT 0x22
+#define PCI_MEMORY_RANGE_TYPE_MASK 0x0f
+#define PCI_MEMORY_RANGE_MASK ~0x0f
+#define PCI_PREF_MEMORY_BASE 0x24 /* Prefetchable memory range behind */
+#define PCI_PREF_MEMORY_LIMIT 0x26
+#define PCI_PREF_RANGE_TYPE_MASK 0x0f
+#define PCI_PREF_RANGE_TYPE_32 0x00
+#define PCI_PREF_RANGE_TYPE_64 0x01
+#define PCI_PREF_RANGE_MASK ~0x0f
+#define PCI_PREF_BASE_UPPER32 0x28 /* Upper half of prefetchable memory range */
+#define PCI_PREF_LIMIT_UPPER32 0x2c
+#define PCI_IO_BASE_UPPER16 0x30 /* Upper half of I/O addresses */
+#define PCI_IO_LIMIT_UPPER16 0x32
+/* 0x34 same as for htype 0 */
+/* 0x35-0x3b is reserved */
+#define PCI_ROM_ADDRESS1 0x38 /* Same as PCI_ROM_ADDRESS, but for htype 1 */
+/* 0x3c-0x3d are same as for htype 0 */
+#define PCI_BRIDGE_CONTROL 0x3e
+#define PCI_BRIDGE_CTL_PARITY 0x01 /* Enable parity detection on secondary interface */
+#define PCI_BRIDGE_CTL_SERR 0x02 /* The same for SERR forwarding */
+#define PCI_BRIDGE_CTL_NO_ISA 0x04 /* Disable bridging of ISA ports */
+#define PCI_BRIDGE_CTL_VGA 0x08 /* Forward VGA addresses */
+#define PCI_BRIDGE_CTL_MASTER_ABORT 0x20 /* Report master aborts */
+#define PCI_BRIDGE_CTL_BUS_RESET 0x40 /* Secondary bus reset */
+#define PCI_BRIDGE_CTL_FAST_BACK 0x80 /* Fast Back2Back enabled on secondary interface */
+
+/* Header type 2 (CardBus bridges) */
+#define PCI_CB_CAPABILITY_LIST 0x14
+/* 0x15 reserved */
+#define PCI_CB_SEC_STATUS 0x16 /* Secondary status */
+#define PCI_CB_PRIMARY_BUS 0x18 /* PCI bus number */
+#define PCI_CB_CARD_BUS 0x19 /* CardBus bus number */
+#define PCI_CB_SUBORDINATE_BUS 0x1a /* Subordinate bus number */
+#define PCI_CB_LATENCY_TIMER 0x1b /* CardBus latency timer */
+#define PCI_CB_MEMORY_BASE_0 0x1c
+#define PCI_CB_MEMORY_LIMIT_0 0x20
+#define PCI_CB_MEMORY_BASE_1 0x24
+#define PCI_CB_MEMORY_LIMIT_1 0x28
+#define PCI_CB_IO_BASE_0 0x2c
+#define PCI_CB_IO_BASE_0_HI 0x2e
+#define PCI_CB_IO_LIMIT_0 0x30
+#define PCI_CB_IO_LIMIT_0_HI 0x32
+#define PCI_CB_IO_BASE_1 0x34
+#define PCI_CB_IO_BASE_1_HI 0x36
+#define PCI_CB_IO_LIMIT_1 0x38
+#define PCI_CB_IO_LIMIT_1_HI 0x3a
+#define PCI_CB_IO_RANGE_MASK ~0x03
+/* 0x3c-0x3d are same as for htype 0 */
+#define PCI_CB_BRIDGE_CONTROL 0x3e
+#define PCI_CB_BRIDGE_CTL_PARITY 0x01 /* Similar to standard bridge control register */
+#define PCI_CB_BRIDGE_CTL_SERR 0x02
+#define PCI_CB_BRIDGE_CTL_ISA 0x04
+#define PCI_CB_BRIDGE_CTL_VGA 0x08
+#define PCI_CB_BRIDGE_CTL_MASTER_ABORT 0x20
+#define PCI_CB_BRIDGE_CTL_CB_RESET 0x40 /* CardBus reset */
+#define PCI_CB_BRIDGE_CTL_16BIT_INT 0x80 /* Enable interrupt for 16-bit cards */
+#define PCI_CB_BRIDGE_CTL_PREFETCH_MEM0 0x100 /* Prefetch enable for both memory regions */
+#define PCI_CB_BRIDGE_CTL_PREFETCH_MEM1 0x200
+#define PCI_CB_BRIDGE_CTL_POST_WRITES 0x400
+#define PCI_CB_SUBSYSTEM_VENDOR_ID 0x40
+#define PCI_CB_SUBSYSTEM_ID 0x42
+#define PCI_CB_LEGACY_MODE_BASE 0x44 /* 16-bit PC Card legacy mode base address (ExCa) */
+/* 0x48-0x7f reserved */
+
+/* Capability lists */
+
+#define PCI_CAP_LIST_ID 0 /* Capability ID */
+#define PCI_CAP_ID_PM 0x01 /* Power Management */
+#define PCI_CAP_ID_AGP 0x02 /* Accelerated Graphics Port */
+#define PCI_CAP_ID_VPD 0x03 /* Vital Product Data */
+#define PCI_CAP_ID_SLOTID 0x04 /* Slot Identification */
+#define PCI_CAP_ID_MSI 0x05 /* Message Signalled Interrupts */
+#define PCI_CAP_ID_CHSWP 0x06 /* CompactPCI HotSwap */
+#define PCI_CAP_LIST_NEXT 1 /* Next capability in the list */
+#define PCI_CAP_FLAGS 2 /* Capability defined flags (16 bits) */
+#define PCI_CAP_SIZEOF 4
+
+/* Power Management Registers */
+
+#define PCI_PM_CAP_VER_MASK 0x0007 /* Version */
+#define PCI_PM_CAP_PME_CLOCK 0x0008 /* PME clock required */
+#define PCI_PM_CAP_AUX_POWER 0x0010 /* Auxilliary power support */
+#define PCI_PM_CAP_DSI 0x0020 /* Device specific initialization */
+#define PCI_PM_CAP_D1 0x0200 /* D1 power state support */
+#define PCI_PM_CAP_D2 0x0400 /* D2 power state support */
+#define PCI_PM_CAP_PME 0x0800 /* PME pin supported */
+#define PCI_PM_CTRL 4 /* PM control and status register */
+#define PCI_PM_CTRL_STATE_MASK 0x0003 /* Current power state (D0 to D3) */
+#define PCI_PM_CTRL_PME_ENABLE 0x0100 /* PME pin enable */
+#define PCI_PM_CTRL_DATA_SEL_MASK 0x1e00 /* Data select (??) */
+#define PCI_PM_CTRL_DATA_SCALE_MASK 0x6000 /* Data scale (??) */
+#define PCI_PM_CTRL_PME_STATUS 0x8000 /* PME pin status */
+#define PCI_PM_PPB_EXTENSIONS 6 /* PPB support extensions (??) */
+#define PCI_PM_PPB_B2_B3 0x40 /* Stop clock when in D3hot (??) */
+#define PCI_PM_BPCC_ENABLE 0x80 /* Bus power/clock control enable (??) */
+#define PCI_PM_DATA_REGISTER 7 /* (??) */
+#define PCI_PM_SIZEOF 8
+
+/* AGP registers */
+
+#define PCI_AGP_VERSION 2 /* BCD version number */
+#define PCI_AGP_RFU 3 /* Rest of capability flags */
+#define PCI_AGP_STATUS 4 /* Status register */
+#define PCI_AGP_STATUS_RQ_MASK 0xff000000 /* Maximum number of requests - 1 */
+#define PCI_AGP_STATUS_SBA 0x0200 /* Sideband addressing supported */
+#define PCI_AGP_STATUS_64BIT 0x0020 /* 64-bit addressing supported */
+#define PCI_AGP_STATUS_FW 0x0010 /* FW transfers supported */
+#define PCI_AGP_STATUS_RATE4 0x0004 /* 4x transfer rate supported */
+#define PCI_AGP_STATUS_RATE2 0x0002 /* 2x transfer rate supported */
+#define PCI_AGP_STATUS_RATE1 0x0001 /* 1x transfer rate supported */
+#define PCI_AGP_COMMAND 8 /* Control register */
+#define PCI_AGP_COMMAND_RQ_MASK 0xff000000 /* Master: Maximum number of requests */
+#define PCI_AGP_COMMAND_SBA 0x0200 /* Sideband addressing enabled */
+#define PCI_AGP_COMMAND_AGP 0x0100 /* Allow processing of AGP transactions */
+#define PCI_AGP_COMMAND_64BIT 0x0020 /* Allow processing of 64-bit addresses */
+#define PCI_AGP_COMMAND_FW 0x0010 /* Force FW transfers */
+#define PCI_AGP_COMMAND_RATE4 0x0004 /* Use 4x rate */
+#define PCI_AGP_COMMAND_RATE2 0x0002 /* Use 4x rate */
+#define PCI_AGP_COMMAND_RATE1 0x0001 /* Use 4x rate */
+#define PCI_AGP_SIZEOF 12
+
+/* Slot Identification */
+
+#define PCI_SID_ESR 2 /* Expansion Slot Register */
+#define PCI_SID_ESR_NSLOTS 0x1f /* Number of expansion slots available */
+#define PCI_SID_ESR_FIC 0x20 /* First In Chassis Flag */
+#define PCI_SID_CHASSIS_NR 3 /* Chassis Number */
+
+/* Message Signalled Interrupts registers */
+
+#define PCI_MSI_FLAGS 2 /* Various flags */
+#define PCI_MSI_FLAGS_64BIT 0x80 /* 64-bit addresses allowed */
+#define PCI_MSI_FLAGS_QSIZE 0x70 /* Message queue size configured */
+#define PCI_MSI_FLAGS_QMASK 0x0e /* Maximum queue size available */
+#define PCI_MSI_FLAGS_ENABLE 0x01 /* MSI feature enabled */
+#define PCI_MSI_RFU 3 /* Rest of capability flags */
+#define PCI_MSI_ADDRESS_LO 4 /* Lower 32 bits */
+#define PCI_MSI_ADDRESS_HI 8 /* Upper 32 bits (if PCI_MSI_FLAGS_64BIT set) */
+#define PCI_MSI_DATA_32 8 /* 16 bits of data for 32-bit devices */
+#define PCI_MSI_DATA_64 12 /* 16 bits of data for 64-bit devices */
+
+#define PCI_MAX_PCI_DEVICES 32
+#define PCI_MAX_PCI_FUNCTIONS 8
+
+/* Include the ID list */
+
+#include <pci_ids.h>
+
+struct pci_region {
+ unsigned long bus_start; /* Start on the bus */
+ unsigned long phys_start; /* Start in physical address space */
+ unsigned long size; /* Size */
+ unsigned long flags; /* Resource flags */
+
+ unsigned long bus_lower;
+};
+
+#define PCI_REGION_MEM 0x00000000 /* PCI memory space */
+#define PCI_REGION_IO 0x00000001 /* PCI IO space */
+#define PCI_REGION_TYPE 0x00000001
+
+#define PCI_REGION_MEMORY 0x00000100 /* System memory */
+#define PCI_REGION_RO 0x00000200 /* Read-only memory */
+
+extern __inline__ void pci_set_region(struct pci_region *reg,
+ unsigned long bus_start,
+ unsigned long phys_start,
+ unsigned long size,
+ unsigned long flags) {
+ reg->bus_start = bus_start;
+ reg->phys_start = phys_start;
+ reg->size = size;
+ reg->flags = flags;
+}
+
+typedef int pci_dev_t;
+
+#define PCI_BUS(d) (((d) >> 16) & 0xff)
+#define PCI_DEV(d) (((d) >> 11) & 0x1f)
+#define PCI_FUNC(d) (((d) >> 8) & 0x7)
+#define PCI_BDF(b,d,f) ((b) << 16 | (d) << 11 | (f) << 8)
+
+#define PCI_ANY_ID (~0)
+
+struct pci_device_id {
+ unsigned int vendor, device; /* Vendor and device ID or PCI_ANY_ID */
+};
+
+struct pci_controller;
+
+struct pci_config_table {
+ unsigned int vendor, device; /* Vendor and device ID or PCI_ANY_ID */
+ unsigned int class; /* Class ID, or PCI_ANY_ID */
+ unsigned int bus; /* Bus number, or PCI_ANY_ID */
+ unsigned int dev; /* Device number, or PCI_ANY_ID */
+ unsigned int func; /* Function number, or PCI_ANY_ID */
+
+ void (*config_device)(struct pci_controller* hose, pci_dev_t dev,
+ struct pci_config_table *);
+ unsigned long priv[3];
+};
+
+extern void pci_cfgfunc_nothing(struct pci_controller* hose, pci_dev_t dev,
+ struct pci_config_table *);
+extern void pci_cfgfunc_config_device(struct pci_controller* hose, pci_dev_t dev,
+ struct pci_config_table *);
+
+#define MAX_PCI_REGIONS 7
+
+/*
+ * Structure of a PCI controller (host bridge)
+ */
+struct pci_controller {
+ struct pci_controller *next;
+
+ int first_busno;
+ int last_busno;
+
+ volatile unsigned int *cfg_addr;
+ volatile unsigned char *cfg_data;
+
+ struct pci_region regions[MAX_PCI_REGIONS];
+ int region_count;
+
+ struct pci_config_table *config_table;
+
+ void (*fixup_irq)(struct pci_controller *, pci_dev_t);
+
+ /* Low-level architecture-dependent routines */
+ int (*read_byte)(struct pci_controller*, pci_dev_t, int where, u8 *);
+ int (*read_word)(struct pci_controller*, pci_dev_t, int where, u16 *);
+ int (*read_dword)(struct pci_controller*, pci_dev_t, int where, u32 *);
+ int (*write_byte)(struct pci_controller*, pci_dev_t, int where, u8);
+ int (*write_word)(struct pci_controller*, pci_dev_t, int where, u16);
+ int (*write_dword)(struct pci_controller*, pci_dev_t, int where, u32);
+
+ /* Used by auto config */
+ struct pci_region *pci_mem, *pci_io;
+
+ /* Used by ppc405 autoconfig*/
+ struct pci_region *pci_fb;
+};
+
+extern __inline__ void pci_set_ops(struct pci_controller *hose,
+ int (*read_byte)(struct pci_controller*,
+ pci_dev_t, int where, u8 *),
+ int (*read_word)(struct pci_controller*,
+ pci_dev_t, int where, u16 *),
+ int (*read_dword)(struct pci_controller*,
+ pci_dev_t, int where, u32 *),
+ int (*write_byte)(struct pci_controller*,
+ pci_dev_t, int where, u8),
+ int (*write_word)(struct pci_controller*,
+ pci_dev_t, int where, u16),
+ int (*write_dword)(struct pci_controller*,
+ pci_dev_t, int where, u32)) {
+ hose->read_byte = read_byte;
+ hose->read_word = read_word;
+ hose->read_dword = read_dword;
+ hose->write_byte = write_byte;
+ hose->write_word = write_word;
+ hose->write_dword = write_dword;
+}
+
+extern void pci_setup_indirect(struct pci_controller* hose, u32 cfg_addr, u32 cfg_data);
+
+extern unsigned long pci_hose_bus_to_phys(struct pci_controller* hose,
+ unsigned long addr, unsigned long flags);
+extern unsigned long pci_hose_phys_to_bus(struct pci_controller* hose,
+ unsigned long addr, unsigned long flags);
+
+#define pci_phys_to_bus(dev, addr, flags) \
+ pci_hose_phys_to_bus(pci_bus_to_hose(PCI_BUS(dev)), (addr), (flags))
+#define pci_bus_to_phys(dev, addr, flags) \
+ pci_hose_bus_to_phys(pci_bus_to_hose(PCI_BUS(dev)), (addr), (flags))
+
+#define pci_phys_to_mem(dev, addr) pci_phys_to_bus((dev), (addr), PCI_REGION_MEM)
+#define pci_mem_to_phys(dev, addr) pci_bus_to_phys((dev), (addr), PCI_REGION_MEM)
+#define pci_phys_to_io(dev, addr) pci_phys_to_bus((dev), (addr), PCI_REGION_IO)
+#define pci_io_to_phys(dev, addr) pci_bus_to_phys((dev), (addr), PCI_REGION_IO)
+
+extern int pci_hose_read_config_byte(struct pci_controller *hose,
+ pci_dev_t dev, int where, u8 *val);
+extern int pci_hose_read_config_word(struct pci_controller *hose,
+ pci_dev_t dev, int where, u16 *val);
+extern int pci_hose_read_config_dword(struct pci_controller *hose,
+ pci_dev_t dev, int where, u32 *val);
+extern int pci_hose_write_config_byte(struct pci_controller *hose,
+ pci_dev_t dev, int where, u8 val);
+extern int pci_hose_write_config_word(struct pci_controller *hose,
+ pci_dev_t dev, int where, u16 val);
+extern int pci_hose_write_config_dword(struct pci_controller *hose,
+ pci_dev_t dev, int where, u32 val);
+
+extern int pci_read_config_byte(pci_dev_t dev, int where, u8 *val);
+extern int pci_read_config_word(pci_dev_t dev, int where, u16 *val);
+extern int pci_read_config_dword(pci_dev_t dev, int where, u32 *val);
+extern int pci_write_config_byte(pci_dev_t dev, int where, u8 val);
+extern int pci_write_config_word(pci_dev_t dev, int where, u16 val);
+extern int pci_write_config_dword(pci_dev_t dev, int where, u32 val);
+
+extern int pci_hose_read_config_byte_via_dword(struct pci_controller *hose,
+ pci_dev_t dev, int where, u8 *val);
+extern int pci_hose_read_config_word_via_dword(struct pci_controller *hose,
+ pci_dev_t dev, int where, u16 *val);
+extern int pci_hose_write_config_byte_via_dword(struct pci_controller *hose,
+ pci_dev_t dev, int where, u8 val);
+extern int pci_hose_write_config_word_via_dword(struct pci_controller *hose,
+ pci_dev_t dev, int where, u16 val);
+
+extern void pci_register_hose(struct pci_controller* hose);
+extern struct pci_controller* pci_bus_to_hose(int bus);
+
+extern int pci_hose_scan(struct pci_controller *hose);
+extern int pci_hose_scan_bus(struct pci_controller *hose, int bus);
+
+extern void pciauto_region_init(struct pci_region* res);
+extern void pciauto_region_align(struct pci_region *res, unsigned long size);
+extern int pciauto_region_allocate(struct pci_region* res, unsigned int size, unsigned int *bar);
+extern void pciauto_setup_device(struct pci_controller *hose,
+ pci_dev_t dev, int bars_num,
+ struct pci_region *mem,
+ struct pci_region *io);
+void pciauto_config_device(struct pci_controller *hose, pci_dev_t dev);
+
+extern pci_dev_t pci_find_device (unsigned int vendor, unsigned int device, int index);
+extern pci_dev_t pci_find_devices (struct pci_device_id *ids, int index);
+
+extern int pci_hose_config_device(struct pci_controller *hose,
+ pci_dev_t dev,
+ unsigned long io,
+ unsigned long mem,
+ unsigned long command);
+
+#ifdef CONFIG_MPC824X
+extern void pci_mpc824x_init (struct pci_controller *hose);
+#endif
+
+#endif /* _PCI_H */
--- /dev/null
+/*
+ * (C) Copyright 1997-2002 ELTEC Elektronik AG
+ * Frank Gottschling <fgottschling@eltec.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
+ */
+
+/*
+ * smiLynxEM.h
+ * Silicon Motion graphic interface for sm810/sm710/sm712 accelerator
+ *
+ *
+ * modification history
+ * --------------------
+ * 04-18-2002 Rewritten for U-Boot <fgottschling@eltec.de>.
+ */
+
+#ifndef _SMI_LYNX_EM_H_
+#define _SMI_LYNX_EM_H_
+
+/*
+ * SMI 710/712 have 4MB internal RAM; SMI 810 2MB internal + 2MB external
+ */
+#define VIDEO_MEM_SIZE 0x400000
+
+/*
+ * Supported video modes for SMI Lynx E/EM/EM+
+ */
+#define VIDEO_MODES 7
+#define DUAL_800_600 0 /* SMI710:VGA1:75Hz (pitch=1600) */
+ /* VGA2:60/120Hz (pitch=1600) */
+ /* SMI810:VGA1:75Hz (pitch=1600) */
+ /* VGA2:75Hz (pitch=1600) */
+#define DUAL_1024_768 1 /* VGA1:75Hz VGA2:73Hz (pitch=2048) */
+#define SINGLE_800_600 2 /* VGA1:75Hz (pitch=800) */
+#define SINGLE_1024_768 3 /* VGA1:75Hz (pitch=1024) */
+#define SINGLE_1280_1024 4 /* VGA1:75Hz (pitch=1280) */
+#define TV_MODE_CCIR 5 /* VGA1:50Hz (h=720;v=576;pitch=720) */
+#define TV_MODE_EIA 6 /* VGA1:60Hz (h=720;v=484;pitch=720) */
+
+
+/*
+ * ISA mapped regs
+ */
+#define SMI_INDX_C4 (pGD->isaBase + 0x03c4) /* index reg */
+#define SMI_DATA_C5 (pGD->isaBase + 0x03c5) /* data reg */
+#define SMI_INDX_D4 (pGD->isaBase + 0x03d4) /* index reg */
+#define SMI_DATA_D5 (pGD->isaBase + 0x03d5) /* data reg */
+#define SMI_INDX_CE (pGD->isaBase + 0x03ce) /* index reg */
+#define SMI_DATA_CF (pGD->isaBase + 0x03cf) /* data reg */
+#define SMI_LOCK_REG (pGD->isaBase + 0x03c3) /* unlock/lock ext crt reg */
+#define SMI_MISC_REG (pGD->isaBase + 0x03c2) /* misc reg */
+#define SMI_LUT_MASK (pGD->isaBase + 0x03c6) /* lut mask reg */
+#define SMI_LUT_START (pGD->isaBase + 0x03c8) /* lut start index */
+#define SMI_LUT_RGB (pGD->isaBase + 0x03c9) /* lut colors auto incr.*/
+
+
+/*
+ * Video processor control
+ */
+typedef struct {
+ unsigned int control;
+ unsigned int colorKey;
+ unsigned int colorKeyMask;
+ unsigned int start;
+ unsigned short offset;
+ unsigned short width;
+ unsigned int fifoPrio;
+ unsigned int fifoERL;
+ unsigned int YUVtoRGB;
+} SmiVideoProc;
+
+/*
+ * Video window control
+ */
+typedef struct {
+ unsigned short top;
+ unsigned short left;
+ unsigned short bottom;
+ unsigned short right;
+ unsigned int srcStart;
+ unsigned short width;
+ unsigned short offset;
+ unsigned char hStretch;
+ unsigned char vStretch;
+} SmiVideoWin;
+
+/*
+ * Capture port control
+ */
+typedef struct {
+ unsigned int control;
+ unsigned short topClip;
+ unsigned short leftClip;
+ unsigned short srcHeight;
+ unsigned short srcWidth;
+ unsigned int srcBufStart1;
+ unsigned int srcBufStart2;
+ unsigned short srcOffset;
+ unsigned short fifoControl;
+} SmiCapturePort;
+
+
+/******************************************************************************/
+/* Export Graphic Driver Control */
+/******************************************************************************/
+
+typedef struct {
+ unsigned int isaBase;
+ unsigned int pciBase;
+ unsigned int dprBase;
+ unsigned int vprBase;
+ unsigned int cprBase;
+ unsigned int frameAdrs;
+ unsigned int memSize;
+ unsigned int mode;
+ unsigned int gdfIndex;
+ unsigned int gdfBytesPP;
+ unsigned int fg;
+ unsigned int bg;
+ unsigned int plnSizeX;
+ unsigned int plnSizeY;
+ unsigned int winSizeX;
+ unsigned int winSizeY;
+ char modeIdent[80];
+} GraphicDevice;
+
+extern GraphicDevice smi;
+
+
+/******************************************************************************/
+/* Export Graphic Functions */
+/******************************************************************************/
+
+void *video_hw_init (void); /* returns GraphicDevice struct or NULL */
+
+void video_hw_bitblt (
+ unsigned int bpp, /* bytes per pixel */
+ unsigned int src_x, /* source pos x */
+ unsigned int src_y, /* source pos y */
+ unsigned int dst_x, /* dest pos x */
+ unsigned int dst_y, /* dest pos y */
+ unsigned int dim_x, /* frame width */
+ unsigned int dim_y /* frame height */
+ );
+
+void video_hw_rectfill (
+ unsigned int bpp, /* bytes per pixel */
+ unsigned int dst_x, /* dest pos x */
+ unsigned int dst_y, /* dest pos y */
+ unsigned int dim_x, /* frame width */
+ unsigned int dim_y, /* frame height */
+ unsigned int color /* fill color */
+ );
+
+void video_set_lut (
+ unsigned int index, /* color number */
+ unsigned char r, /* red */
+ unsigned char g, /* green */
+ unsigned char b /* blue */
+ );
+
+#endif /*_SMI_LYNX_EM_H_ */
--- /dev/null
+/*
+ * (C) Copyright 2002
+ * Rich Ireland, Enterasys Networks, rireland@enterasys.com.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ */
+
+#ifndef _SPARTAN2_H_
+#define _SPARTAN2_H_
+
+#include <xilinx.h>
+
+extern int Spartan2_load( Xilinx_desc *desc, void *image, size_t size );
+extern int Spartan2_dump( Xilinx_desc *desc, void *buf, size_t bsize );
+extern int Spartan2_info( Xilinx_desc *desc );
+extern int Spartan2_reloc( Xilinx_desc *desc, ulong reloc_off );
+
+/* Slave Parallel Implementation function table */
+typedef struct {
+ Xilinx_pre_fn pre;
+ Xilinx_pgm_fn pgm;
+ Xilinx_init_fn init;
+ Xilinx_err_fn err;
+ Xilinx_done_fn done;
+ Xilinx_clk_fn clk;
+ Xilinx_cs_fn cs;
+ Xilinx_wr_fn wr;
+ Xilinx_rdata_fn rdata;
+ Xilinx_wdata_fn wdata;
+ Xilinx_busy_fn busy;
+ Xilinx_abort_fn abort;
+ Xilinx_post_fn post;
+ int relocated;
+} Xilinx_Spartan2_Slave_Parallel_fns;
+
+/* Slave Serial Implementation function table */
+typedef struct {
+ Xilinx_pgm_fn pgm;
+ Xilinx_clk_fn clk;
+ Xilinx_rdata_fn rdata;
+ Xilinx_wdata_fn wdata;
+ int relocated;
+} Xilinx_Spartan2_Slave_Serial_fns;
+
+/* Device Image Sizes
+ *********************************************************************/
+/* Spartan-II (2.5V) */
+#define XILINX_XC2S15_SIZE 197728/8
+#define XILINX_XC2S30_SIZE 336800/8
+#define XILINX_XC2S50_SIZE 559232/8
+#define XILINX_XC2S100_SIZE 781248/8
+#define XILINX_XC2S150_SIZE 1040128/8
+
+/* Descriptor Macros
+ *********************************************************************/
+/* Spartan-II devices */
+#define XILINX_XC2S15_DESC(iface, fn_table, cookie) \
+{ Xilinx_Spartan2, iface, XILINX_XC2S15_SIZE, fn_table, cookie }
+
+#define XILINX_XC2S30_DESC(iface, fn_table, cookie) \
+{ Xilinx_Spartan2, iface, XILINX_XC2S30_SIZE, fn_table, cookie }
+
+#define XILINX_XC2S50_DESC(iface, fn_table, cookie) \
+{ Xilinx_Spartan2, iface, XILINX_XC2S50_SIZE, fn_table, cookie }
+
+#define XILINX_XC2S100_DESC(iface, fn_table, cookie) \
+{ Xilinx_Spartan2, iface, XILINX_XC2S100_SIZE, fn_table, cookie }
+
+#define XILINX_XC2S150_DESC(iface, fn_table, cookie) \
+{ Xilinx_Spartan2, iface, XILINX_XC2S150_SIZE, fn_table, cookie }
+
+#endif /* _SPARTAN2_H_ */
+
--- /dev/null
+/*
+ * (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
+ */
+
+/*
+ * The purpose of this code is to signal the operational status of a
+ * target which usually boots over the network; while running in
+ * PCBoot, a status LED is blinking. As soon as a valid BOOTP reply
+ * message has been received, the LED is turned off. The Linux
+ * kernel, once it is running, will start blinking the LED again,
+ * with another frequency.
+ */
+
+#ifndef _STATUS_LED_H_
+#define _STATUS_LED_H_
+
+#ifdef CONFIG_STATUS_LED
+
+#define STATUS_LED_OFF 0
+#define STATUS_LED_BLINKING 1
+#define STATUS_LED_ON 2
+
+void status_led_tick (unsigned long timestamp);
+void status_led_set (int led, int state);
+
+/***** TQM8xxL ********************************************************/
+#if defined(CONFIG_TQM8xxL)
+# define STATUS_LED_PAR im_cpm.cp_pbpar
+# define STATUS_LED_DIR im_cpm.cp_pbdir
+# define STATUS_LED_ODR im_cpm.cp_pbodr
+# define STATUS_LED_DAT im_cpm.cp_pbdat
+
+# define STATUS_LED_BIT 0x00000001
+# define STATUS_LED_PERIOD (CFG_HZ / 2)
+# define STATUS_LED_STATE STATUS_LED_BLINKING
+
+# define STATUS_LED_ACTIVE 1 /* LED on for bit == 1 */
+
+# define STATUS_LED_BOOT 0 /* LED 0 used for boot status */
+
+/***** MVS v1 **********************************************************/
+#elif (defined(CONFIG_MVS) && CONFIG_MVS < 2)
+# define STATUS_LED_PAR im_ioport.iop_pdpar
+# define STATUS_LED_DIR im_ioport.iop_pddir
+# undef STATUS_LED_ODR
+# define STATUS_LED_DAT im_ioport.iop_pddat
+
+# define STATUS_LED_BIT 0x00000001
+# define STATUS_LED_PERIOD (CFG_HZ / 2)
+# define STATUS_LED_STATE STATUS_LED_BLINKING
+
+# define STATUS_LED_ACTIVE 1 /* LED on for bit == 1 */
+
+# define STATUS_LED_BOOT 0 /* LED 0 used for boot status */
+
+/***** ETX_094 ********************************************************/
+#elif defined(CONFIG_ETX094)
+
+# define STATUS_LED_PAR im_ioport.iop_pdpar
+# define STATUS_LED_DIR im_ioport.iop_pddir
+# undef STATUS_LED_ODR
+# define STATUS_LED_DAT im_ioport.iop_pddat
+
+# define STATUS_LED_BIT 0x00000001
+# define STATUS_LED_PERIOD (CFG_HZ / 2)
+# define STATUS_LED_STATE STATUS_LED_BLINKING
+
+# define STATUS_LED_ACTIVE 0 /* LED on for bit == 0 */
+
+# define STATUS_LED_BOOT 0 /* LED 0 used for boot status */
+
+/***** GEN860T *********************************************************/
+#elif defined(CONFIG_GEN860T)
+
+# define STATUS_LED_PAR im_ioport.iop_papar
+# define STATUS_LED_DIR im_ioport.iop_padir
+# define STATUS_LED_ODR im_ioport.iop_paodr
+# define STATUS_LED_DAT im_ioport.iop_padat
+
+# define STATUS_LED_BIT 0x0800 /* Red LED 0 is on PA.4 */
+# define STATUS_LED_PERIOD (CFG_HZ / 2)
+# define STATUS_LED_STATE STATUS_LED_BLINKING
+# define STATUS_LED_BIT1 0x0400 /* Grn LED 1 is on PA.5 */
+# define STATUS_LED_PERIOD1 (CFG_HZ / 2)
+# define STATUS_LED_STATE1 STATUS_LED_BLINKING
+# define STATUS_LED_BIT2 0x0080 /* Red LED 2 is on PA.8 */
+# define STATUS_LED_PERIOD2 (CFG_HZ / 2)
+# define STATUS_LED_STATE2 STATUS_LED_BLINKING
+# define STATUS_LED_BIT3 0x0040 /* Grn LED 3 is on PA.9 */
+# define STATUS_LED_PERIOD3 (CFG_HZ / 2)
+# define STATUS_LED_STATE3 STATUS_LED_BLINKING
+
+# define STATUS_LED_ACTIVE 1 /* LED on for bit == 1 */
+# define STATUS_LED_BOOT 0 /* Boot status on LED 1 */
+
+/***** IVMS8 **********************************************************/
+#elif defined(CONFIG_IVMS8)
+
+# define STATUS_LED_PAR im_cpm.cp_pbpar
+# define STATUS_LED_DIR im_cpm.cp_pbdir
+# define STATUS_LED_ODR im_cpm.cp_pbodr
+# define STATUS_LED_DAT im_cpm.cp_pbdat
+
+# define STATUS_LED_BIT 0x00000010 /* LED 0 is on PB.27 */
+# define STATUS_LED_PERIOD (1 * CFG_HZ)
+# define STATUS_LED_STATE STATUS_LED_OFF
+# define STATUS_LED_BIT1 0x00000020 /* LED 1 is on PB.26 */
+# define STATUS_LED_PERIOD1 (1 * CFG_HZ)
+# define STATUS_LED_STATE1 STATUS_LED_OFF
+/* IDE LED usable for other purposes, too */
+# define STATUS_LED_BIT2 0x00000008 /* LED 2 is on PB.28 */
+# define STATUS_LED_PERIOD2 (1 * CFG_HZ)
+# define STATUS_LED_STATE2 STATUS_LED_OFF
+
+# define STATUS_LED_ACTIVE 1 /* LED on for bit == 1 */
+
+# define STATUS_ILOCK_SWITCH 0x00800000 /* ILOCK switch in IRQ4 */
+
+# define STATUS_ILOCK_PERIOD (CFG_HZ / 10) /* about every 100 ms */
+
+# define STATUS_LED_YELLOW 0
+# define STATUS_LED_GREEN 1
+# define STATUS_LED_BOOT 2 /* IDE LED used for boot status */
+
+/***** IVML24 *********************************************************/
+#elif defined(CONFIG_IVML24)
+
+# define STATUS_LED_PAR im_cpm.cp_pbpar
+# define STATUS_LED_DIR im_cpm.cp_pbdir
+# define STATUS_LED_ODR im_cpm.cp_pbodr
+# define STATUS_LED_DAT im_cpm.cp_pbdat
+
+# define STATUS_LED_BIT 0x00000010 /* LED 0 is on PB.27 */
+# define STATUS_LED_PERIOD (1 * CFG_HZ)
+# define STATUS_LED_STATE STATUS_LED_OFF
+# define STATUS_LED_BIT1 0x00000020 /* LED 1 is on PB.26 */
+# define STATUS_LED_PERIOD1 (1 * CFG_HZ)
+# define STATUS_LED_STATE1 STATUS_LED_OFF
+/* IDE LED usable for other purposes, too */
+# define STATUS_LED_BIT2 0x00000008 /* LED 2 is on PB.28 */
+# define STATUS_LED_PERIOD2 (1 * CFG_HZ)
+# define STATUS_LED_STATE2 STATUS_LED_OFF
+
+# define STATUS_LED_ACTIVE 1 /* LED on for bit == 1 */
+
+# define STATUS_ILOCK_SWITCH 0x00004000 /* ILOCK is on PB.17 */
+
+# define STATUS_ILOCK_PERIOD (CFG_HZ / 10) /* about every 100 ms */
+
+# define STATUS_LED_YELLOW 0
+# define STATUS_LED_GREEN 1
+# define STATUS_LED_BOOT 2 /* IDE LED used for boot status */
+
+/***** LANTEC *********************************************************/
+#elif defined(CONFIG_LANTEC)
+
+# define STATUS_LED_PAR im_ioport.iop_pdpar
+# define STATUS_LED_DIR im_ioport.iop_pddir
+# undef STATUS_LED_ODR
+# define STATUS_LED_DAT im_ioport.iop_pddat
+
+# if CONFIG_LATEC < 2
+# define STATUS_LED_BIT 0x1000
+# else
+# define STATUS_LED_BIT 0x0800
+# endif
+# define STATUS_LED_PERIOD (CFG_HZ / 2)
+# define STATUS_LED_STATE STATUS_LED_BLINKING
+
+# define STATUS_LED_ACTIVE 0 /* LED on for bit == 0 */
+
+# define STATUS_LED_BOOT 0 /* LED 0 used for boot status */
+
+/***** PCU E and CCM ************************************************/
+#elif (defined(CONFIG_PCU_E) || defined(CONFIG_CCM))
+
+# define STATUS_LED_PAR im_cpm.cp_pbpar
+# define STATUS_LED_DIR im_cpm.cp_pbdir
+# define STATUS_LED_ODR im_cpm.cp_pbodr
+# define STATUS_LED_DAT im_cpm.cp_pbdat
+
+# define STATUS_LED_BIT 0x00010000 /* green LED is on PB.15 */
+# define STATUS_LED_PERIOD (CFG_HZ / 2)
+# define STATUS_LED_STATE STATUS_LED_BLINKING
+
+# define STATUS_LED_ACTIVE 1 /* LED on for bit == 1 */
+
+# define STATUS_LED_BOOT 0 /* LED 0 used for boot status */
+
+/***** ICU862 ********************************************************/
+#elif defined(CONFIG_ICU862)
+
+# define STATUS_LED_PAR im_ioport.iop_papar
+# define STATUS_LED_DIR im_ioport.iop_padir
+# define STATUS_LED_ODR im_ioport.iop_paodr
+# define STATUS_LED_DAT im_ioport.iop_padat
+
+# define STATUS_LED_BIT 0x4000 /* LED 0 is on PA.1 */
+# define STATUS_LED_PERIOD (CFG_HZ / 2)
+# define STATUS_LED_STATE STATUS_LED_BLINKING
+# define STATUS_LED_BIT1 0x1000 /* LED 1 is on PA.3 */
+# define STATUS_LED_PERIOD1 (CFG_HZ)
+# define STATUS_LED_STATE1 STATUS_LED_OFF
+
+# define STATUS_LED_ACTIVE 1 /* LED on for bit == 1 */
+
+# define STATUS_LED_BOOT 0 /* LED 0 used for boot status */
+
+/***** Someone else defines these *************************************/
+#elif defined(STATUS_LED_PAR)
+
+ /*
+ * ADVICE: Define in your board configuration file rather than
+ * filling this file up with lots of custom board stuff.
+ */
+
+/***** NetVia ********************************************************/
+#elif defined(CONFIG_NETVIA)
+
+#define STATUS_LED_PAR im_ioport.iop_pdpar
+#define STATUS_LED_DIR im_ioport.iop_pddir
+#undef STATUS_LED_ODR
+#define STATUS_LED_DAT im_ioport.iop_pddat
+
+# define STATUS_LED_BIT 0x0080 /* PD.8 */
+# define STATUS_LED_PERIOD (CFG_HZ / 2)
+# define STATUS_LED_STATE STATUS_LED_BLINKING
+
+# define STATUS_LED_BIT1 0x0040 /* PD.9 */
+# define STATUS_LED_PERIOD1 (CFG_HZ / 2)
+# define STATUS_LED_STATE1 STATUS_LED_OFF
+
+# define STATUS_LED_ACTIVE 0 /* LED on for bit == 0 */
+# define STATUS_LED_BOOT 0 /* LED 0 used for boot status */
+
+/************************************************************************/
+#else
+# error Status LED configuration missing
+#endif
+/************************************************************************/
+
+#endif /* CONFIG_STATUS_LED */
+
+#endif /* _STATUS_LED_H_ */
--- /dev/null
+ /*
+ * (C) Copyright 1997-2002 ELTEC Elektronik AG
+ * Frank Gottschling <fgottschling@eltec.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
+ */
+
+/*
+ * smiLynxEM.h
+ * Silicon Motion graphic interface for sm810/sm710/sm712 accelerator
+ *
+ *
+ * modification history
+ * --------------------
+ * 04-18-2002 Rewritten for U-Boot <fgottschling@eltec.de>.
+ */
+
+#ifndef _VIDEO_FB_H_
+#define _VIDEO_FB_H_
+
+#define CONSOLE_BG_COL 0x00
+#define CONSOLE_FG_COL 0xa0
+
+/*
+ * Graphic Data Format (GDF) bits for VIDEO_DATA_FORMAT
+ */
+#define GDF__8BIT_INDEX 0
+#define GDF_15BIT_555RGB 1
+#define GDF_16BIT_565RGB 2
+#define GDF_32BIT_X888RGB 3
+#define GDF_24BIT_888RGB 4
+#define GDF__8BIT_332RGB 5
+
+/******************************************************************************/
+/* Export Graphic Driver Control */
+/******************************************************************************/
+
+typedef struct {
+ unsigned int isaBase;
+ unsigned int pciBase;
+ unsigned int dprBase;
+ unsigned int vprBase;
+ unsigned int cprBase;
+ unsigned int frameAdrs;
+ unsigned int memSize;
+ unsigned int mode;
+ unsigned int gdfIndex;
+ unsigned int gdfBytesPP;
+ unsigned int fg;
+ unsigned int bg;
+ unsigned int plnSizeX;
+ unsigned int plnSizeY;
+ unsigned int winSizeX;
+ unsigned int winSizeY;
+ char modeIdent[80];
+} GraphicDevice;
+
+
+/******************************************************************************/
+/* Export Graphic Functions */
+/******************************************************************************/
+
+void *video_hw_init (void); /* returns GraphicDevice struct or NULL */
+
+#ifdef VIDEO_HW_BITBLT
+void video_hw_bitblt (
+ unsigned int bpp, /* bytes per pixel */
+ unsigned int src_x, /* source pos x */
+ unsigned int src_y, /* source pos y */
+ unsigned int dst_x, /* dest pos x */
+ unsigned int dst_y, /* dest pos y */
+ unsigned int dim_x, /* frame width */
+ unsigned int dim_y /* frame height */
+ );
+#endif
+
+#ifdef VIDEO_HW_RECTFILL
+void video_hw_rectfill (
+ unsigned int bpp, /* bytes per pixel */
+ unsigned int dst_x, /* dest pos x */
+ unsigned int dst_y, /* dest pos y */
+ unsigned int dim_x, /* frame width */
+ unsigned int dim_y, /* frame height */
+ unsigned int color /* fill color */
+ );
+#endif
+
+void video_set_lut (
+ unsigned int index, /* color number */
+ unsigned char r, /* red */
+ unsigned char g, /* green */
+ unsigned char b /* blue */
+ );
+#ifdef CONFIG_VIDEO_HW_CURSOR
+void video_set_hw_cursor(int x, int y); /* x y in pixel */
+void video_init_hw_cursor(int font_width, int font_height);
+#endif
+
+#endif /*_VIDEO_FB_H_ */
--- /dev/null
+/*
+ * (C) Copyright 2002
+ * Rich Ireland, Enterasys Networks, rireland@enterasys.com.
+ * Keith Outwater, keith_outwater@mvis.com
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ */
+
+#ifndef _VIRTEX2_H_
+#define _VIRTEX2_H_
+
+#include <xilinx.h>
+
+extern int Virtex2_load( Xilinx_desc *desc, void *image, size_t size );
+extern int Virtex2_dump( Xilinx_desc *desc, void *buf, size_t bsize );
+extern int Virtex2_info( Xilinx_desc *desc );
+extern int Virtex2_reloc( Xilinx_desc *desc, ulong reloc_off );
+
+/*
+ * Slave SelectMap Implementation function table.
+ */
+typedef struct {
+ Xilinx_pre_fn pre;
+ Xilinx_pgm_fn pgm;
+ Xilinx_init_fn init;
+ Xilinx_err_fn err;
+ Xilinx_done_fn done;
+ Xilinx_clk_fn clk;
+ Xilinx_cs_fn cs;
+ Xilinx_wr_fn wr;
+ Xilinx_rdata_fn rdata;
+ Xilinx_wdata_fn wdata;
+ Xilinx_busy_fn busy;
+ Xilinx_abort_fn abort;
+ Xilinx_post_fn post;
+ int relocated;
+} Xilinx_Virtex2_Slave_SelectMap_fns;
+
+/* Slave Serial Implementation function table */
+typedef struct {
+ Xilinx_pgm_fn pgm;
+ Xilinx_clk_fn clk;
+ Xilinx_rdata_fn rdata;
+ Xilinx_wdata_fn wdata;
+ int relocated;
+} Xilinx_Virtex2_Slave_Serial_fns;
+
+/* Device Image Sizes (in bytes)
+ *********************************************************************/
+#define XILINX_XC2V40_SIZE (338208 / 8)
+#define XILINX_XC2V80_SIZE (597408 / 8)
+#define XILINX_XC2V250_SIZE (1591584 / 8)
+#define XILINX_XC2V500_SIZE (2557857 / 8)
+#define XILINX_XC2V1000_SIZE (3749408 / 8)
+#define XILINX_XC2V1500_SIZE (5166240 / 8)
+#define XILINX_XC2V2000_SIZE (6808352 / 8)
+#define XILINX_XC2V3000_SIZE (9589408 / 8)
+#define XILINX_XC2V4000_SIZE (14220192 / 8)
+#define XILINX_XC2V6000_SIZE (19752096 / 8)
+#define XILINX_XC2V8000_SIZE (26185120 / 8)
+#define XILINX_XC2V10000_SIZE (33519264 / 8)
+
+/* Descriptor Macros
+ *********************************************************************/
+#define XILINX_XC2V40_DESC(iface, fn_table, cookie) \
+{ Xilinx_Virtex2, iface, XILINX_XC2V40_SIZE, fn_table, cookie }
+
+#define XILINX_XC2V80_DESC(iface, fn_table, cookie) \
+{ Xilinx_Virtex2, iface, XILINX_XC2V80_SIZE, fn_table, cookie }
+
+#define XILINX_XC2V250_DESC(iface, fn_table, cookie) \
+{ Xilinx_Virtex2, iface, XILINX_XC2V250_SIZE, fn_table, cookie }
+
+#define XILINX_XC2V500_DESC(iface, fn_table, cookie) \
+{ Xilinx_Virtex2, iface, XILINX_XC2V500_SIZE, fn_table, cookie }
+
+#define XILINX_XC2V1000_DESC(iface, fn_table, cookie) \
+{ Xilinx_Virtex2, iface, XILINX_XC2V1000_SIZE, fn_table, cookie }
+
+#define XILINX_XC2V1500_DESC(iface, fn_table, cookie) \
+{ Xilinx_Virtex2, iface, XILINX_XC2V1500_SIZE, fn_table, cookie }
+
+#define XILINX_XC2V2000_DESC(iface, fn_table, cookie) \
+{ Xilinx_Virtex2, iface, XILINX_XC2V2000_SIZE, fn_table, cookie }
+
+#define XILINX_XC2V3000_DESC(iface, fn_table, cookie) \
+{ Xilinx_Virtex2, iface, XILINX_XC2V3000_SIZE, fn_table, cookie }
+
+#define XILINX_XC2V4000_DESC(iface, fn_table, cookie) \
+{ Xilinx_Virtex2, iface, XILINX_XC2V4000_SIZE, fn_table, cookie }
+
+#define XILINX_XC2V6000_DESC(iface, fn_table, cookie) \
+{ Xilinx_Virtex2, iface, XILINX_XC2V6000_SIZE, fn_table, cookie }
+
+#define XILINX_XC2V8000_DESC(iface, fn_table, cookie) \
+{ Xilinx_Virtex2, iface, XILINX_XC2V8000_SIZE, fn_table, cookie }
+
+#define XILINX_XC2V10000_DESC(iface, fn_table, cookie) \
+{ Xilinx_Virtex2, iface, XILINX_XC2V10000_SIZE, fn_table, cookie }
+
+#endif /* _VIRTEX2_H_ */
+
+/* vim: set ts=4 tw=78: */
--- /dev/null
+/*
+ * (C) Copyright 2002
+ * Rich Ireland, Enterasys Networks, rireland@enterasys.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 <fpga.h>
+
+#ifndef _XILINX_H_
+#define _XILINX_H_
+
+/* Xilinx Model definitions
+ *********************************************************************/
+#define CFG_SPARTAN2 CFG_FPGA_DEV( 0x1 )
+#define CFG_VIRTEX_E CFG_FPGA_DEV( 0x2 )
+#define CFG_VIRTEX2 CFG_FPGA_DEV( 0x4 )
+#define CFG_XILINX_SPARTAN2 (CFG_FPGA_XILINX | CFG_SPARTAN2)
+#define CFG_XILINX_VIRTEX_E (CFG_FPGA_XILINX | CFG_VIRTEX_E)
+#define CFG_XILINX_VIRTEX2 (CFG_FPGA_XILINX | CFG_VIRTEX2)
+/* XXX - Add new models here */
+
+
+/* Xilinx Interface definitions
+ *********************************************************************/
+#define CFG_XILINX_IF_SS CFG_FPGA_IF( 0x1 ) /* slave serial */
+#define CFG_XILINX_IF_MS CFG_FPGA_IF( 0x2 ) /* master serial */
+#define CFG_XILINX_IF_SP CFG_FPGA_IF( 0x4 ) /* slave parallel */
+#define CFG_XILINX_IF_JTAG CFG_FPGA_IF( 0x8 ) /* jtag */
+#define CFG_XILINX_IF_MSM CFG_FPGA_IF( 0x10 ) /* master selectmap */
+#define CFG_XILINX_IF_SSM CFG_FPGA_IF( 0x20 ) /* slave selectmap */
+
+/* Xilinx types
+ *********************************************************************/
+typedef enum { /* typedef Xilinx_iface */
+ min_xilinx_iface_type, /* low range check value */
+ slave_serial, /* serial data and external clock */
+ master_serial, /* serial data w/ internal clock (not used) */
+ slave_parallel, /* parallel data w/ external latch */
+ jtag_mode, /* jtag/tap serial (not used ) */
+ master_selectmap, /* master SelectMap (virtex2) */
+ slave_selectmap, /* slave SelectMap (virtex2) */
+ max_xilinx_iface_type /* insert all new types before this */
+} Xilinx_iface; /* end, typedef Xilinx_iface */
+
+typedef enum { /* typedef Xilinx_Family */
+ min_xilinx_type, /* low range check value */
+ Xilinx_Spartan2, /* Spartan-II Family */
+ Xilinx_VirtexE, /* Virtex-E Family */
+ Xilinx_Virtex2, /* Virtex2 Family */
+ max_xilinx_type /* insert all new types before this */
+} Xilinx_Family; /* end, typedef Xilinx_Family */
+
+typedef struct { /* typedef Xilinx_desc */
+ Xilinx_Family family; /* part type */
+ Xilinx_iface iface; /* interface type */
+ size_t size; /* bytes of data part can accept */
+ void * iface_fns; /* interface function table */
+ int cookie; /* implementation specific cookie */
+} Xilinx_desc; /* end, typedef Xilinx_desc */
+
+/* Generic Xilinx Functions
+ *********************************************************************/
+extern int xilinx_load( Xilinx_desc *desc, void *image, size_t size );
+extern int xilinx_dump( Xilinx_desc *desc, void *buf, size_t bsize );
+extern int xilinx_info( Xilinx_desc *desc );
+extern int xilinx_reloc( Xilinx_desc *desc, ulong reloc_offset );
+
+/* Board specific implementation specific function types
+ *********************************************************************/
+typedef int (*Xilinx_pgm_fn)( int assert_pgm, int flush, int cookie );
+typedef int (*Xilinx_init_fn)( int cookie );
+typedef int (*Xilinx_err_fn)( int cookie );
+typedef int (*Xilinx_done_fn)( int cookie );
+typedef int (*Xilinx_clk_fn)( int assert_clk, int flush, int cookie );
+typedef int (*Xilinx_cs_fn)( int assert_cs, int flush, int cookie );
+typedef int (*Xilinx_wr_fn)( int assert_write, int flush, int cookie );
+typedef int (*Xilinx_rdata_fn)( unsigned char *data, int cookie );
+typedef int (*Xilinx_wdata_fn)( unsigned char data, int flush, int cookie );
+typedef int (*Xilinx_busy_fn)( int cookie );
+typedef int (*Xilinx_abort_fn)( int cookie );
+typedef int (*Xilinx_pre_fn)( int cookie );
+typedef int (*Xilinx_post_fn)( int cookie );
+
+#endif /* _XILINX_H_ */
--- /dev/null
+/* # 1 "libgcc1.S" */
+@ libgcc1 routines for ARM cpu.
+@ Division routines, written by Richard Earnshaw, (rearnsha@armltd.co.uk)
+dividend .req r0
+divisor .req r1
+result .req r2
+curbit .req r3
+ip .req r12
+sp .req r13
+lr .req r14
+pc .req r15
+ .text
+ .globl __udivsi3
+ .type __udivsi3 ,function
+ .align 0
+ __udivsi3 :
+ cmp divisor, #0
+ beq Ldiv0
+ mov curbit, #1
+ mov result, #0
+ cmp dividend, divisor
+ bcc Lgot_result
+Loop1:
+ @ Unless the divisor is very big, shift it up in multiples of
+ @ four bits, since this is the amount of unwinding in the main
+ @ division loop. Continue shifting until the divisor is
+ @ larger than the dividend.
+ cmp divisor, #0x10000000
+ cmpcc divisor, dividend
+ movcc divisor, divisor, lsl #4
+ movcc curbit, curbit, lsl #4
+ bcc Loop1
+Lbignum:
+ @ For very big divisors, we must shift it a bit at a time, or
+ @ we will be in danger of overflowing.
+ cmp divisor, #0x80000000
+ cmpcc divisor, dividend
+ movcc divisor, divisor, lsl #1
+ movcc curbit, curbit, lsl #1
+ bcc Lbignum
+Loop3:
+ @ Test for possible subtractions, and note which bits
+ @ are done in the result. On the final pass, this may subtract
+ @ too much from the dividend, but the result will be ok, since the
+ @ "bit" will have been shifted out at the bottom.
+ cmp dividend, divisor
+ subcs dividend, dividend, divisor
+ orrcs result, result, curbit
+ cmp dividend, divisor, lsr #1
+ subcs dividend, dividend, divisor, lsr #1
+ orrcs result, result, curbit, lsr #1
+ cmp dividend, divisor, lsr #2
+ subcs dividend, dividend, divisor, lsr #2
+ orrcs result, result, curbit, lsr #2
+ cmp dividend, divisor, lsr #3
+ subcs dividend, dividend, divisor, lsr #3
+ orrcs result, result, curbit, lsr #3
+ cmp dividend, #0 @ Early termination?
+ movnes curbit, curbit, lsr #4 @ No, any more bits to do?
+ movne divisor, divisor, lsr #4
+ bne Loop3
+Lgot_result:
+ mov r0, result
+ mov pc, lr
+Ldiv0:
+ str lr, [sp, #-4]!
+ bl __div0 (PLT)
+ mov r0, #0 @ about as wrong as it could be
+ ldmia sp!, {pc}
+ .size __udivsi3 , . - __udivsi3
+/* # 235 "libgcc1.S" */
+/* # 320 "libgcc1.S" */
+/* # 421 "libgcc1.S" */
+/* # 433 "libgcc1.S" */
+/* # 456 "libgcc1.S" */
+/* # 500 "libgcc1.S" */
+/* # 580 "libgcc1.S" */
--- /dev/null
+/* # 1 "libgcc1.S" */
+@ libgcc1 routines for ARM cpu.
+@ Division routines, written by Richard Earnshaw, (rearnsha@armltd.co.uk)
+/* # 145 "libgcc1.S" */
+dividend .req r0
+divisor .req r1
+overdone .req r2
+curbit .req r3
+ip .req r12
+sp .req r13
+lr .req r14
+pc .req r15
+ .text
+ .globl __umodsi3
+ .type __umodsi3 ,function
+ .align 0
+ __umodsi3 :
+ cmp divisor, #0
+ beq Ldiv0
+ mov curbit, #1
+ cmp dividend, divisor
+ movcc pc, lr
+Loop1:
+ @ Unless the divisor is very big, shift it up in multiples of
+ @ four bits, since this is the amount of unwinding in the main
+ @ division loop. Continue shifting until the divisor is
+ @ larger than the dividend.
+ cmp divisor, #0x10000000
+ cmpcc divisor, dividend
+ movcc divisor, divisor, lsl #4
+ movcc curbit, curbit, lsl #4
+ bcc Loop1
+Lbignum:
+ @ For very big divisors, we must shift it a bit at a time, or
+ @ we will be in danger of overflowing.
+ cmp divisor, #0x80000000
+ cmpcc divisor, dividend
+ movcc divisor, divisor, lsl #1
+ movcc curbit, curbit, lsl #1
+ bcc Lbignum
+Loop3:
+ @ Test for possible subtractions. On the final pass, this may
+ @ subtract too much from the dividend, so keep track of which
+ @ subtractions are done, we can fix them up afterwards...
+ mov overdone, #0
+ cmp dividend, divisor
+ subcs dividend, dividend, divisor
+ cmp dividend, divisor, lsr #1
+ subcs dividend, dividend, divisor, lsr #1
+ orrcs overdone, overdone, curbit, ror #1
+ cmp dividend, divisor, lsr #2
+ subcs dividend, dividend, divisor, lsr #2
+ orrcs overdone, overdone, curbit, ror #2
+ cmp dividend, divisor, lsr #3
+ subcs dividend, dividend, divisor, lsr #3
+ orrcs overdone, overdone, curbit, ror #3
+ mov ip, curbit
+ cmp dividend, #0 @ Early termination?
+ movnes curbit, curbit, lsr #4 @ No, any more bits to do?
+ movne divisor, divisor, lsr #4
+ bne Loop3
+ @ Any subtractions that we should not have done will be recorded in
+ @ the top three bits of "overdone". Exactly which were not needed
+ @ are governed by the position of the bit, stored in ip.
+ @ If we terminated early, because dividend became zero,
+ @ then none of the below will match, since the bit in ip will not be
+ @ in the bottom nibble.
+ ands overdone, overdone, #0xe0000000
+ moveq pc, lr @ No fixups needed
+ tst overdone, ip, ror #3
+ addne dividend, dividend, divisor, lsr #3
+ tst overdone, ip, ror #2
+ addne dividend, dividend, divisor, lsr #2
+ tst overdone, ip, ror #1
+ addne dividend, dividend, divisor, lsr #1
+ mov pc, lr
+Ldiv0:
+ str lr, [sp, #-4]!
+ bl __div0 (PLT)
+ mov r0, #0 @ about as wrong as it could be
+ ldmia sp!, {pc}
+ .size __umodsi3 , . - __umodsi3
+/* # 320 "libgcc1.S" */
+/* # 421 "libgcc1.S" */
+/* # 433 "libgcc1.S" */
+/* # 456 "libgcc1.S" */
+/* # 500 "libgcc1.S" */
+/* # 580 "libgcc1.S" */
--- /dev/null
+/*
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Marius Groeger <mgroeger@sysgo.de>
+ *
+ * Copyright (C) 2001 Erik Mouw (J.A.K.Mouw@its.tudelft.nl)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <common.h>
+#include <command.h>
+#include <cmd_boot.h>
+#include <image.h>
+#include <zlib.h>
+#include <asm/byteorder.h>
+
+#include <asm/setup.h>
+#define tag_size(type) ((sizeof(struct tag_header) + sizeof(struct type)) >> 2)
+#define tag_next(t) ((struct tag *)((u32 *)(t) + (t)->hdr.size))
+
+#if defined (CONFIG_SETUP_MEMORY_TAGS) || \
+ defined (CONFIG_CMDLINE_TAG) || \
+ defined (CONFIG_INITRD_TAG) || \
+ defined (CONFIG_VFD)
+static void setup_start_tag(bd_t *bd);
+static void setup_memory_tags(bd_t *bd);
+static void setup_commandline_tag(bd_t *bd, char *commandline);
+#if 0
+static void setup_ramdisk_tag(bd_t *bd);
+#endif
+static void setup_initrd_tag(bd_t *bd, ulong initrd_start, ulong initrd_end);
+static void setup_end_tag(bd_t *bd);
+#if defined (CONFIG_VFD)
+static void setup_videolfb_tag(gd_t *gd);
+#endif
+
+
+static struct tag *params;
+#endif /* CONFIG_SETUP_MEMORY_TAGS || CONFIG_CMDLINE_TAG || CONFIG_INITRD_TAG */
+
+extern image_header_t header; /* from cmd_bootm.c */
+
+
+void do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],
+ ulong addr, ulong *len_ptr, int verify)
+{
+ DECLARE_GLOBAL_DATA_PTR;
+
+ ulong len = 0, checksum;
+ ulong initrd_start, initrd_end;
+ ulong data;
+ void (*theKernel)(int zero, int arch);
+ image_header_t *hdr = &header;
+ bd_t *bd = gd->bd;
+#ifdef CONFIG_CMDLINE_TAG
+ char *commandline = getenv("bootargs");
+#endif
+
+ theKernel = (void (*)(int, int))ntohl(hdr->ih_ep);
+
+ /*
+ * Check if there is an initrd image
+ */
+ if (argc >= 3) {
+ addr = simple_strtoul(argv[2], NULL, 16);
+
+ printf ("## Loading Ramdisk Image at %08lx ...\n", addr);
+
+ /* Copy header so we can blank CRC field for re-calculation */
+ memcpy (&header, (char *)addr, sizeof(image_header_t));
+
+ if (ntohl(hdr->ih_magic) != IH_MAGIC) {
+ printf ("Bad Magic Number\n");
+ do_reset (cmdtp, flag, argc, argv);
+ }
+
+ data = (ulong)&header;
+ len = sizeof(image_header_t);
+
+ checksum = ntohl(hdr->ih_hcrc);
+ hdr->ih_hcrc = 0;
+
+ if (crc32 (0, (char *)data, len) != checksum) {
+ printf ("Bad Header Checksum\n");
+ do_reset (cmdtp, flag, argc, argv);
+ }
+
+ print_image_hdr (hdr);
+
+ data = addr + sizeof(image_header_t);
+ len = ntohl(hdr->ih_size);
+
+ if (verify) {
+ ulong csum = 0;
+
+ printf (" Verifying Checksum ... ");
+ csum = crc32 (0, (char *)data, len);
+ if (csum != ntohl(hdr->ih_dcrc)) {
+ printf ("Bad Data CRC\n");
+ do_reset (cmdtp, flag, argc, argv);
+ }
+ printf ("OK\n");
+ }
+
+ if ((hdr->ih_os != IH_OS_LINUX) ||
+ (hdr->ih_arch != IH_CPU_ARM) ||
+ (hdr->ih_type != IH_TYPE_RAMDISK) ) {
+ printf ("No Linux ARM Ramdisk Image\n");
+ do_reset (cmdtp, flag, argc, argv);
+ }
+
+ /*
+ * Now check if we have a multifile image
+ */
+ } else if ((hdr->ih_type==IH_TYPE_MULTI) && (len_ptr[1])) {
+ ulong tail = ntohl(len_ptr[0]) % 4;
+ int i;
+
+ /* skip kernel length and terminator */
+ data = (ulong)(&len_ptr[2]);
+ /* skip any additional image length fields */
+ for (i=1; len_ptr[i]; ++i)
+ data += 4;
+ /* add kernel length, and align */
+ data += ntohl(len_ptr[0]);
+ if (tail) {
+ data += 4 - tail;
+ }
+
+ len = ntohl(len_ptr[1]);
+
+ } else {
+ /*
+ * no initrd image
+ */
+ data = 0;
+ }
+
+#ifdef DEBUG
+ if (!data) {
+ printf ("No initrd\n");
+ }
+#endif
+
+ if (data) {
+ initrd_start = data;
+ initrd_end = initrd_start + len;
+ } else {
+ initrd_start = 0;
+ initrd_end = 0;
+ }
+
+#ifdef DEBUG
+ printf ("## Transferring control to Linux (at address %08lx) ...\n",
+ (ulong)theKernel);
+#endif
+
+#if defined (CONFIG_SETUP_MEMORY_TAGS) || \
+ defined (CONFIG_CMDLINE_TAG) || \
+ defined (CONFIG_INITRD_TAG) || \
+ defined (CONFIG_VFD)
+ setup_start_tag(bd);
+#ifdef CONFIG_SETUP_MEMORY_TAGS
+ setup_memory_tags(bd);
+#endif
+#ifdef CONFIG_CMDLINE_TAG
+ setup_commandline_tag(bd, commandline);
+#endif
+#ifdef CONFIG_INITRD_TAG
+ setup_initrd_tag(bd, initrd_start, initrd_end);
+#endif
+#if 0
+ setup_ramdisk_tag(bd);
+#endif
+#if defined (CONFIG_VFD)
+ setup_videolfb_tag(gd);
+#endif
+ setup_end_tag(bd);
+#endif
+
+ /* we assume that the kernel is in place */
+ printf("\nStarting kernel ...\n\n");
+
+ cleanup_before_linux();
+
+ theKernel(0, bd->bi_arch_number);
+}
+
+
+#if defined (CONFIG_SETUP_MEMORY_TAGS) || \
+ defined (CONFIG_CMDLINE_TAG) || \
+ defined (CONFIG_INITRD_TAG) || \
+ defined (CONFIG_VFD)
+static void setup_start_tag(bd_t *bd)
+{
+ params = (struct tag *)bd->bi_boot_params;
+
+ params->hdr.tag = ATAG_CORE;
+ params->hdr.size = tag_size(tag_core);
+
+ params->u.core.flags = 0;
+ params->u.core.pagesize = 0;
+ params->u.core.rootdev = 0;
+
+ params = tag_next(params);
+}
+
+
+static void setup_memory_tags(bd_t *bd)
+{
+ int i;
+
+ for(i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
+ params->hdr.tag = ATAG_MEM;
+ params->hdr.size = tag_size(tag_mem32);
+
+ params->u.mem.start = bd->bi_dram[i].start;
+ params->u.mem.size = bd->bi_dram[i].size;
+
+ params = tag_next(params);
+ }
+}
+
+
+static void setup_commandline_tag(bd_t *bd, char *commandline)
+{
+ char *p;
+
+ /* eat leading white space */
+ for(p = commandline; *p == ' '; p++)
+ ;
+
+ /* skip non-existent command lines so the kernel will still
+ * use its default command line.
+ */
+ if(*p == '\0')
+ return;
+
+ params->hdr.tag = ATAG_CMDLINE;
+ params->hdr.size = (sizeof(struct tag_header) + strlen(p) + 1 + 4) >> 2;
+
+ strcpy(params->u.cmdline.cmdline, p);
+
+ params = tag_next(params);
+}
+
+
+#ifndef ATAG_INITRD2
+#define ATAG_INITRD2 0x54420005
+#endif
+static void setup_initrd_tag(bd_t *bd, ulong initrd_start, ulong initrd_end)
+{
+ /* an ATAG_INITRD node tells the kernel where the compressed
+ * ramdisk can be found. ATAG_RDIMG is a better name, actually.
+ */
+ params->hdr.tag = ATAG_INITRD2;
+ params->hdr.size = tag_size(tag_initrd);
+
+ params->u.initrd.start = initrd_start;
+ params->u.initrd.size = initrd_end - initrd_start;
+
+ params = tag_next(params);
+}
+
+
+#if 0
+static void setup_ramdisk_tag(bd_t *bd)
+{
+ /* an ATAG_RAMDISK node tells the kernel how large the
+ * decompressed ramdisk will become.
+ */
+ params->hdr.tag = ATAG_RAMDISK;
+ params->hdr.size = tag_size(tag_ramdisk);
+
+ params->u.ramdisk.start = 0;
+ /*params->u.ramdisk.size = RAMDISK_SIZE; */
+ params->u.ramdisk.flags = 1; /* automatically load ramdisk */
+
+ params = tag_next(params);
+}
+#endif /* 0 */
+
+#if defined (CONFIG_VFD)
+static void setup_videolfb_tag(gd_t *gd)
+{
+ /* An ATAG_VIDEOLFB node tells the kernel where and how large
+ * the framebuffer for video was allocated (among other things).
+ * Note that a _physical_ address is passed !
+ *
+ * We only use it to pass the address and size, the other entries
+ * in the tag_videolfb are not of interest.
+ */
+ params->hdr.tag = ATAG_VIDEOLFB;
+ params->hdr.size = tag_size(tag_videolfb);
+
+ params->u.videolfb.lfb_base = (u32)gd->fb_base;
+ /* 7168 = 256*4*56/8 - actually 2 pages (8192 bytes) are allocated */
+ params->u.videolfb.lfb_size = 7168;
+
+ params = tag_next(params);
+}
+#endif
+
+static void setup_end_tag(bd_t *bd)
+{
+ params->hdr.tag = ATAG_NONE;
+ params->hdr.size = 0;
+}
+
+#endif /* CONFIG_SETUP_MEMORY_TAGS || CONFIG_CMDLINE_TAG || CONFIG_INITRD_TAG */
--- /dev/null
+/*
+ * (C) Copyright 2002
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Marius Groeger <mgroeger@sysgo.de>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <command.h>
+#include <devices.h>
+#include <version.h>
+#include <net.h>
+
+
+const char version_string[] =
+ U_BOOT_VERSION" (" __DATE__ " - " __TIME__ ")";
+
+#ifdef CONFIG_DRIVER_CS8900
+extern void cs8900_get_enetaddr (uchar * addr);
+#endif
+
+/*
+ * Begin and End of memory area for malloc(), and current "brk"
+ */
+static ulong mem_malloc_start = 0;
+static ulong mem_malloc_end = 0;
+static ulong mem_malloc_brk = 0;
+
+static void mem_malloc_init (ulong dest_addr)
+{
+ mem_malloc_start = dest_addr;
+ mem_malloc_end = dest_addr + CONFIG_MALLOC_SIZE;
+ mem_malloc_brk = mem_malloc_start;
+
+ memset ((void *) mem_malloc_start, 0,
+ mem_malloc_end - mem_malloc_start);
+}
+
+void *sbrk (ptrdiff_t increment)
+{
+ ulong old = mem_malloc_brk;
+ ulong new = old + increment;
+
+ if ((new < mem_malloc_start) || (new > mem_malloc_end)) {
+ return (NULL);
+ }
+ mem_malloc_brk = new;
+
+ return ((void *) old);
+}
+
+/************************************************************************
+ * Init Utilities *
+ ************************************************************************
+ * Some of this code should be moved into the core functions,
+ * or dropped completely,
+ * but let's get it working (again) first...
+ */
+
+static int init_baudrate (void)
+{
+ DECLARE_GLOBAL_DATA_PTR;
+
+ uchar tmp[64]; /* long enough for environment variables */
+ int i = getenv_r ("baudrate", tmp, sizeof (tmp));
+
+ gd->baudrate = (i > 0)
+ ? (int) simple_strtoul (tmp, NULL, 10)
+ : CONFIG_BAUDRATE;
+
+ return (0);
+}
+
+static int display_banner (void)
+{
+
+ printf ("\n\n%s\n\n", version_string);
+ printf ("U-Boot code: %08lX -> %08lX BSS: -> %08lX\n",
+ _armboot_start, _armboot_end_data, _armboot_end);
+#ifdef CONFIG_MODEM_SUPPORT
+ puts ("Modem Support enabled\n");
+#endif
+#ifdef CONFIG_USE_IRQ
+ printf ("IRQ Stack: %08lx\n", IRQ_STACK_START);
+ printf ("FIQ Stack: %08lx\n", FIQ_STACK_START);
+#endif
+ return (0);
+}
+
+/*
+ * WARNING: this code looks "cleaner" than the PowerPC version, but
+ * has the disadvantage that you either get nothing, or everything.
+ * On PowerPC, you might see "DRAM: " before the system hangs - which
+ * gives a simple yet clear indication which part of the
+ * initialization if failing.
+ */
+static int display_dram_config (void)
+{
+ DECLARE_GLOBAL_DATA_PTR;
+ int i;
+
+ puts ("DRAM Configuration:\n");
+
+ for(i=0; i<CONFIG_NR_DRAM_BANKS; i++) {
+ printf ("Bank #%d: %08lx ", i, gd->bd->bi_dram[i].start);
+ print_size (gd->bd->bi_dram[i].size, "\n");
+ }
+
+ return (0);
+}
+
+static void display_flash_config (ulong size)
+{
+ puts ("Flash: ");
+ print_size (size, "\n");
+}
+
+
+
+/*
+ * Breath some life into the board...
+ *
+ * Initialize an SMC for serial comms, and carry out some hardware
+ * tests.
+ *
+ * The first part of initialization is running from Flash memory;
+ * its main purpose is to initialize the RAM so that we
+ * can relocate the monitor code to RAM.
+ */
+
+/*
+ * All attempts to come up with a "common" initialization sequence
+ * that works for all boards and architectures failed: some of the
+ * requirements are just _too_ different. To get rid of the resulting
+ * mess of board dependend #ifdef'ed code we now make the whole
+ * initialization sequence configurable to the user.
+ *
+ * The requirements for any new initalization function is simple: it
+ * receives a pointer to the "global data" structure as it's only
+ * argument, and returns an integer return code, where 0 means
+ * "continue" and != 0 means "fatal error, hang the system".
+ */
+typedef int (init_fnc_t) (void);
+
+init_fnc_t *init_sequence[] = {
+ cpu_init, /* basic cpu dependent setup */
+ board_init, /* basic board dependent setup */
+ interrupt_init, /* set up exceptions */
+ env_init, /* initialize environment */
+ init_baudrate, /* initialze baudrate settings */
+ serial_init, /* serial communications setup */
+ display_banner,
+ dram_init, /* configure available RAM banks */
+ display_dram_config,
+
+ NULL,
+};
+
+void start_armboot (void)
+{
+ DECLARE_GLOBAL_DATA_PTR;
+
+ ulong size;
+ gd_t gd_data;
+ bd_t bd_data;
+ init_fnc_t **init_fnc_ptr;
+#ifdef CONFIG_VFD
+ unsigned long addr;
+#endif
+
+ /* Pointer is writable since we allocated a register for it */
+ gd = &gd_data;
+ memset (gd, 0, sizeof (gd_t));
+ gd->bd = &bd_data;
+ memset (gd->bd, 0, sizeof (bd_t));
+
+ for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {
+ if ((*init_fnc_ptr)() != 0) {
+ hang ();
+ }
+ }
+
+ /* configure available FLASH banks */
+ size = flash_init ();
+ display_flash_config (size);
+
+#ifdef CONFIG_VFD
+#ifndef PAGE_SIZE
+#define PAGE_SIZE 4096
+#endif
+ /*
+ * reserve memory for VFD display (always full pages)
+ */
+ /* armboot_real_end is defined in the board-specific linker script */
+ addr = (_armboot_real_end + (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1);
+ size = vfd_setmem (addr);
+ gd->fb_base = addr;
+ /* round to the next page boundary */
+ addr += size;
+ addr = (addr + (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1);
+ mem_malloc_init (addr);
+#else
+ /* armboot_real_end is defined in the board-specific linker script */
+ mem_malloc_init (_armboot_real_end);
+#endif /* CONFIG_VFD */
+
+#ifdef CONFIG_VFD
+ /* must do this after the framebuffer is allocated */
+ drv_vfd_init();
+#endif
+ /* initialize environment */
+ env_relocate ();
+
+ /* IP Address */
+ bd_data.bi_ip_addr = getenv_IPaddr ("ipaddr");
+
+ /* MAC Address */
+ {
+ int i;
+ ulong reg;
+ char *s, *e;
+ uchar tmp[64];
+
+ i = getenv_r ("ethaddr", tmp, sizeof (tmp));
+ s = (i > 0) ? tmp : NULL;
+
+ for (reg = 0; reg < 6; ++reg) {
+ bd_data.bi_enetaddr[reg] = s ? simple_strtoul (s, &e, 16) : 0;
+ if (s)
+ s = (*e) ? e + 1 : e;
+ }
+ }
+
+#if defined(CONFIG_MISC_INIT_R)
+ /* miscellaneous platform dependent initialisations */
+ misc_init_r ();
+#endif
+
+ /* enable exceptions */
+ enable_interrupts ();
+
+#ifdef CONFIG_DRIVER_CS8900
+ if (!getenv ("ethaddr")) {
+ cs8900_get_enetaddr (gd->bd->bi_enetaddr);
+ }
+#endif
+
+#ifdef BOARD_POST_INIT
+ board_post_init ();
+#endif
+
+ /* main_loop() can return to retry autoboot, if so just run it again. */
+ for (;;) {
+ main_loop ();
+ }
+
+ /* NOTREACHED - no way out of command loop except booting */
+}
+
+void hang (void)
+{
+ puts ("### ERROR ### Please RESET the board ###\n");
+ for (;;);
+}
+
+#ifdef CONFIG_MODEM_SUPPORT
+/* called from main loop (common/main.c) */
+extern void dbg(const char *fmt, ...);
+int mdm_init (void)
+{
+ char env_str[16];
+ char *init_str;
+ int i;
+ extern char console_buffer[];
+ static inline void mdm_readline(char *buf, int bufsiz);
+ extern void enable_putc(void);
+ extern int hwflow_onoff(int);
+
+ enable_putc(); /* enable serial_putc() */
+
+#ifdef CONFIG_HWFLOW
+ init_str = getenv("mdm_flow_control");
+ if (init_str && (strcmp(init_str, "rts/cts") == 0))
+ hwflow_onoff (1);
+ else
+ hwflow_onoff(-1);
+#endif
+
+ for (i = 1;;i++) {
+ sprintf(env_str, "mdm_init%d", i);
+ if ((init_str = getenv(env_str)) != NULL) {
+ serial_puts(init_str);
+ serial_puts("\n");
+ for(;;) {
+ mdm_readline(console_buffer, CFG_CBSIZE);
+ dbg("ini%d: [%s]", i, console_buffer);
+
+ if ((strcmp(console_buffer, "OK") == 0) ||
+ (strcmp(console_buffer, "ERROR") == 0)) {
+ dbg("ini%d: cmd done", i);
+ break;
+ } else /* in case we are originating call ... */
+ if (strncmp(console_buffer, "CONNECT", 7) == 0) {
+ dbg("ini%d: connect", i);
+ return 0;
+ }
+ }
+ } else
+ break; /* no init string - stop modem init */
+
+ udelay(100000);
+ }
+
+ udelay(100000);
+
+ /* final stage - wait for connect */
+ for(;i > 1;) { /* if 'i' > 1 - wait for connection
+ message from modem */
+ mdm_readline(console_buffer, CFG_CBSIZE);
+ dbg("ini_f: [%s]", console_buffer);
+ if (strncmp(console_buffer, "CONNECT", 7) == 0) {
+ dbg("ini_f: connected");
+ return 0;
+ }
+ }
+
+ return 0;
+}
+
+/* 'inline' - We have to do it fast */
+static inline void mdm_readline(char *buf, int bufsiz)
+{
+ char c;
+ char *p;
+ int n;
+
+ n = 0;
+ p = buf;
+ for(;;) {
+ c = serial_getc();
+
+ /* dbg("(%c)", c); */
+
+ switch(c) {
+ case '\r':
+ break;
+ case '\n':
+ *p = '\0';
+ return;
+
+ default:
+ if(n++ > bufsiz) {
+ *p = '\0';
+ return; /* sanity check */
+ }
+ *p = c;
+ p++;
+ break;
+ }
+ }
+}
+#endif /* CONFIG_MODEM_SUPPORT */
--- /dev/null
+/*
+ * linux/lib/string.c
+ *
+ * Copyright (C) 1991, 1992 Linus Torvalds
+ */
+
+/*
+ * stupid library routines.. The optimized versions should generally be found
+ * as inline code in <asm-xx/string.h>
+ *
+ * These are buggy as well..
+ *
+ * * Fri Jun 25 1999, Ingo Oeser <ioe@informatik.tu-chemnitz.de>
+ * - Added strsep() which will replace strtok() soon (because strsep() is
+ * reentrant and should be faster). Use only strsep() in new code, please.
+ */
+
+#include <linux/types.h>
+#include <linux/string.h>
+#include <linux/ctype.h>
+#include <malloc.h>
+
+#ifdef CONFIG_ARM
+#undef __HAVE_ARCH_MEMCMP
+#undef __HAVE_ARCH_MEMCPY
+#undef __HAVE_ARCH_MEMMOVE
+#undef __HAVE_ARCH_MEMSET
+#undef __HAVE_ARCH_BCOPY
+#undef __HAVE_ARCH_STRCAT
+#undef __HAVE_ARCH_STRCHR
+#undef __HAVE_ARCH_STRCMP
+#undef __HAVE_ARCH_STRCPY
+#undef __HAVE_ARCH_STRLEN
+#undef __HAVE_ARCH_STRNCPY
+#else
+#define __HAVE_ARCH_MEMCMP
+#define __HAVE_ARCH_MEMCPY
+#define __HAVE_ARCH_MEMMOVE
+#define __HAVE_ARCH_MEMSET
+#define __HAVE_ARCH_BCOPY
+#define __HAVE_ARCH_STRCAT
+#define __HAVE_ARCH_STRCMP
+#define __HAVE_ARCH_STRCPY
+#define __HAVE_ARCH_STRLEN
+#define __HAVE_ARCH_STRNCPY
+#endif
+
+#ifndef __HAVE_ARCH_STRNICMP
+/**
+ * strnicmp - Case insensitive, length-limited string comparison
+ * @s1: One string
+ * @s2: The other string
+ * @len: the maximum number of characters to compare
+ */
+int strnicmp(const char *s1, const char *s2, size_t len)
+{
+ /* Yes, Virginia, it had better be unsigned */
+ unsigned char c1, c2;
+
+ c1 = 0; c2 = 0;
+ if (len) {
+ do {
+ c1 = *s1; c2 = *s2;
+ s1++; s2++;
+ if (!c1)
+ break;
+ if (!c2)
+ break;
+ if (c1 == c2)
+ continue;
+ c1 = tolower(c1);
+ c2 = tolower(c2);
+ if (c1 != c2)
+ break;
+ } while (--len);
+ }
+ return (int)c1 - (int)c2;
+}
+#endif
+
+char * ___strtok;
+
+#ifndef __HAVE_ARCH_STRCPY
+/**
+ * strcpy - Copy a %NUL terminated string
+ * @dest: Where to copy the string to
+ * @src: Where to copy the string from
+ */
+char * strcpy(char * dest,const char *src)
+{
+ char *tmp = dest;
+
+ while ((*dest++ = *src++) != '\0')
+ /* nothing */;
+ return tmp;
+}
+#endif
+
+#ifndef __HAVE_ARCH_STRNCPY
+/**
+ * strncpy - Copy a length-limited, %NUL-terminated string
+ * @dest: Where to copy the string to
+ * @src: Where to copy the string from
+ * @count: The maximum number of bytes to copy
+ *
+ * Note that unlike userspace strncpy, this does not %NUL-pad the buffer.
+ * However, the result is not %NUL-terminated if the source exceeds
+ * @count bytes.
+ */
+char * strncpy(char * dest,const char *src,size_t count)
+{
+ char *tmp = dest;
+
+ while (count-- && (*dest++ = *src++) != '\0')
+ /* nothing */;
+
+ return tmp;
+}
+#endif
+
+#ifndef __HAVE_ARCH_STRCAT
+/**
+ * strcat - Append one %NUL-terminated string to another
+ * @dest: The string to be appended to
+ * @src: The string to append to it
+ */
+char * strcat(char * dest, const char * src)
+{
+ char *tmp = dest;
+
+ while (*dest)
+ dest++;
+ while ((*dest++ = *src++) != '\0')
+ ;
+
+ return tmp;
+}
+#endif
+
+#ifndef __HAVE_ARCH_STRNCAT
+/**
+ * strncat - Append a length-limited, %NUL-terminated string to another
+ * @dest: The string to be appended to
+ * @src: The string to append to it
+ * @count: The maximum numbers of bytes to copy
+ *
+ * Note that in contrast to strncpy, strncat ensures the result is
+ * terminated.
+ */
+char * strncat(char *dest, const char *src, size_t count)
+{
+ char *tmp = dest;
+
+ if (count) {
+ while (*dest)
+ dest++;
+ while ((*dest++ = *src++)) {
+ if (--count == 0) {
+ *dest = '\0';
+ break;
+ }
+ }
+ }
+
+ return tmp;
+}
+#endif
+
+#ifndef __HAVE_ARCH_STRCMP
+/**
+ * strcmp - Compare two strings
+ * @cs: One string
+ * @ct: Another string
+ */
+int strcmp(const char * cs,const char * ct)
+{
+ register signed char __res;
+
+ while (1) {
+ if ((__res = *cs - *ct++) != 0 || !*cs++)
+ break;
+ }
+
+ return __res;
+}
+#endif
+
+#ifndef __HAVE_ARCH_STRNCMP
+/**
+ * strncmp - Compare two length-limited strings
+ * @cs: One string
+ * @ct: Another string
+ * @count: The maximum number of bytes to compare
+ */
+int strncmp(const char * cs,const char * ct,size_t count)
+{
+ register signed char __res = 0;
+
+ while (count) {
+ if ((__res = *cs - *ct++) != 0 || !*cs++)
+ break;
+ count--;
+ }
+
+ return __res;
+}
+#endif
+
+#ifndef __HAVE_ARCH_STRCHR
+/**
+ * strchr - Find the first occurrence of a character in a string
+ * @s: The string to be searched
+ * @c: The character to search for
+ */
+char * strchr(const char * s, int c)
+{
+ for(; *s != (char) c; ++s)
+ if (*s == '\0')
+ return NULL;
+ return (char *) s;
+}
+#endif
+
+#ifndef __HAVE_ARCH_STRRCHR
+/**
+ * strrchr - Find the last occurrence of a character in a string
+ * @s: The string to be searched
+ * @c: The character to search for
+ */
+char * strrchr(const char * s, int c)
+{
+ const char *p = s + strlen(s);
+ do {
+ if (*p == (char)c)
+ return (char *)p;
+ } while (--p >= s);
+ return NULL;
+}
+#endif
+
+#ifndef __HAVE_ARCH_STRLEN
+/**
+ * strlen - Find the length of a string
+ * @s: The string to be sized
+ */
+size_t strlen(const char * s)
+{
+ const char *sc;
+
+ for (sc = s; *sc != '\0'; ++sc)
+ /* nothing */;
+ return sc - s;
+}
+#endif
+
+#ifndef __HAVE_ARCH_STRNLEN
+/**
+ * strnlen - Find the length of a length-limited string
+ * @s: The string to be sized
+ * @count: The maximum number of bytes to search
+ */
+size_t strnlen(const char * s, size_t count)
+{
+ const char *sc;
+
+ for (sc = s; count-- && *sc != '\0'; ++sc)
+ /* nothing */;
+ return sc - s;
+}
+#endif
+
+#ifndef __HAVE_ARCH_STRDUP
+char * strdup(const char *s)
+{
+ char *new;
+
+ if ((s == NULL) ||
+ ((new = malloc (strlen(s) + 1)) == NULL) ) {
+ return NULL;
+ }
+
+ strcpy (new, s);
+ return new;
+}
+#endif
+
+#ifndef __HAVE_ARCH_STRSPN
+/**
+ * strspn - Calculate the length of the initial substring of @s which only
+ * contain letters in @accept
+ * @s: The string to be searched
+ * @accept: The string to search for
+ */
+size_t strspn(const char *s, const char *accept)
+{
+ const char *p;
+ const char *a;
+ size_t count = 0;
+
+ for (p = s; *p != '\0'; ++p) {
+ for (a = accept; *a != '\0'; ++a) {
+ if (*p == *a)
+ break;
+ }
+ if (*a == '\0')
+ return count;
+ ++count;
+ }
+
+ return count;
+}
+#endif
+
+#ifndef __HAVE_ARCH_STRPBRK
+/**
+ * strpbrk - Find the first occurrence of a set of characters
+ * @cs: The string to be searched
+ * @ct: The characters to search for
+ */
+char * strpbrk(const char * cs,const char * ct)
+{
+ const char *sc1,*sc2;
+
+ for( sc1 = cs; *sc1 != '\0'; ++sc1) {
+ for( sc2 = ct; *sc2 != '\0'; ++sc2) {
+ if (*sc1 == *sc2)
+ return (char *) sc1;
+ }
+ }
+ return NULL;
+}
+#endif
+
+#ifndef __HAVE_ARCH_STRTOK
+/**
+ * strtok - Split a string into tokens
+ * @s: The string to be searched
+ * @ct: The characters to search for
+ *
+ * WARNING: strtok is deprecated, use strsep instead.
+ */
+char * strtok(char * s,const char * ct)
+{
+ char *sbegin, *send;
+
+ sbegin = s ? s : ___strtok;
+ if (!sbegin) {
+ return NULL;
+ }
+ sbegin += strspn(sbegin,ct);
+ if (*sbegin == '\0') {
+ ___strtok = NULL;
+ return( NULL );
+ }
+ send = strpbrk( sbegin, ct);
+ if (send && *send != '\0')
+ *send++ = '\0';
+ ___strtok = send;
+ return (sbegin);
+}
+#endif
+
+#ifndef __HAVE_ARCH_STRSEP
+/**
+ * strsep - Split a string into tokens
+ * @s: The string to be searched
+ * @ct: The characters to search for
+ *
+ * strsep() updates @s to point after the token, ready for the next call.
+ *
+ * It returns empty tokens, too, behaving exactly like the libc function
+ * of that name. In fact, it was stolen from glibc2 and de-fancy-fied.
+ * Same semantics, slimmer shape. ;)
+ */
+char * strsep(char **s, const char *ct)
+{
+ char *sbegin = *s, *end;
+
+ if (sbegin == NULL)
+ return NULL;
+
+ end = strpbrk(sbegin, ct);
+ if (end)
+ *end++ = '\0';
+ *s = end;
+
+ return sbegin;
+}
+#endif
+
+#ifndef __HAVE_ARCH_MEMSET
+/**
+ * memset - Fill a region of memory with the given value
+ * @s: Pointer to the start of the area.
+ * @c: The byte to fill the area with
+ * @count: The size of the area.
+ *
+ * Do not use memset() to access IO space, use memset_io() instead.
+ */
+void * memset(void * s,int c,size_t count)
+{
+ char *xs = (char *) s;
+
+ while (count--)
+ *xs++ = c;
+
+ return s;
+}
+#endif
+
+#ifndef __HAVE_ARCH_BCOPY
+/**
+ * bcopy - Copy one area of memory to another
+ * @src: Where to copy from
+ * @dest: Where to copy to
+ * @count: The size of the area.
+ *
+ * Note that this is the same as memcpy(), with the arguments reversed.
+ * memcpy() is the standard, bcopy() is a legacy BSD function.
+ *
+ * You should not use this function to access IO space, use memcpy_toio()
+ * or memcpy_fromio() instead.
+ */
+char * bcopy(const char * src, char * dest, int count)
+{
+ char *tmp = dest;
+
+ while (count--)
+ *tmp++ = *src++;
+
+ return dest;
+}
+#endif
+
+#ifndef __HAVE_ARCH_MEMCPY
+/**
+ * memcpy - Copy one area of memory to another
+ * @dest: Where to copy to
+ * @src: Where to copy from
+ * @count: The size of the area.
+ *
+ * You should not use this function to access IO space, use memcpy_toio()
+ * or memcpy_fromio() instead.
+ */
+void * memcpy(void * dest,const void *src,size_t count)
+{
+ char *tmp = (char *) dest, *s = (char *) src;
+
+ while (count--)
+ *tmp++ = *s++;
+
+ return dest;
+}
+#endif
+
+#ifndef __HAVE_ARCH_MEMMOVE
+/**
+ * memmove - Copy one area of memory to another
+ * @dest: Where to copy to
+ * @src: Where to copy from
+ * @count: The size of the area.
+ *
+ * Unlike memcpy(), memmove() copes with overlapping areas.
+ */
+void * memmove(void * dest,const void *src,size_t count)
+{
+ char *tmp, *s;
+
+ if (dest <= src) {
+ tmp = (char *) dest;
+ s = (char *) src;
+ while (count--)
+ *tmp++ = *s++;
+ }
+ else {
+ tmp = (char *) dest + count;
+ s = (char *) src + count;
+ while (count--)
+ *--tmp = *--s;
+ }
+
+ return dest;
+}
+#endif
+
+#ifndef __HAVE_ARCH_MEMCMP
+/**
+ * memcmp - Compare two areas of memory
+ * @cs: One area of memory
+ * @ct: Another area of memory
+ * @count: The size of the area.
+ */
+int memcmp(const void * cs,const void * ct,size_t count)
+{
+ const unsigned char *su1, *su2;
+ int res = 0;
+
+ for( su1 = cs, su2 = ct; 0 < count; ++su1, ++su2, count--)
+ if ((res = *su1 - *su2) != 0)
+ break;
+ return res;
+}
+#endif
+
+#ifndef __HAVE_ARCH_MEMSCAN
+/**
+ * memscan - Find a character in an area of memory.
+ * @addr: The memory area
+ * @c: The byte to search for
+ * @size: The size of the area.
+ *
+ * returns the address of the first occurrence of @c, or 1 byte past
+ * the area if @c is not found
+ */
+void * memscan(void * addr, int c, size_t size)
+{
+ unsigned char * p = (unsigned char *) addr;
+
+ while (size) {
+ if (*p == c)
+ return (void *) p;
+ p++;
+ size--;
+ }
+ return (void *) p;
+}
+#endif
+
+#ifndef __HAVE_ARCH_STRSTR
+/**
+ * strstr - Find the first substring in a %NUL terminated string
+ * @s1: The string to be searched
+ * @s2: The string to search for
+ */
+char * strstr(const char * s1,const char * s2)
+{
+ int l1, l2;
+
+ l2 = strlen(s2);
+ if (!l2)
+ return (char *) s1;
+ l1 = strlen(s1);
+ while (l1 >= l2) {
+ l1--;
+ if (!memcmp(s1,s2,l2))
+ return (char *) s1;
+ s1++;
+ }
+ return NULL;
+}
+#endif
+
+#ifndef __HAVE_ARCH_MEMCHR
+/**
+ * memchr - Find a character in an area of memory.
+ * @s: The memory area
+ * @c: The byte to search for
+ * @n: The size of the area.
+ *
+ * returns the address of the first occurrence of @c, or %NULL
+ * if @c is not found
+ */
+void *memchr(const void *s, int c, size_t n)
+{
+ const unsigned char *p = s;
+ while (n-- != 0) {
+ if ((unsigned char)c == *p++) {
+ return (void *)(p-1);
+ }
+ }
+ return NULL;
+}
+
+#endif
--- /dev/null
+/*
+ * (C) Copyright 2001, 2002
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <command.h>
+#include <net.h>
+
+#if (CONFIG_COMMANDS & CFG_CMD_NET) && defined(CONFIG_NET_MULTI)
+
+#ifdef CFG_GT_6426x
+extern int gt6426x_eth_initialize(bd_t *bis);
+#endif
+
+extern int eepro100_initialize(bd_t*);
+extern int natsemi_initialize(bd_t*);
+extern int ns8382x_initialize(bd_t*);
+extern int dc21x4x_initialize(bd_t*);
+extern int pcnet_initialize(bd_t*);
+extern int fec_initialize(bd_t*);
+extern int scc_initialize(bd_t*);
+
+static struct eth_device *eth_devices, *eth_current;
+
+struct eth_device *eth_get_dev(void)
+{
+ return eth_current;
+}
+
+int eth_get_dev_index (void)
+{
+ struct eth_device *dev;
+ int num = 0;
+
+ if (!eth_devices) {
+ return (-1);
+ }
+
+ for (dev = eth_devices; dev; dev = dev->next) {
+ if (dev == eth_current)
+ break;
+ ++num;
+ }
+
+ if (dev) {
+ return (num);
+ }
+
+ return (0);
+}
+
+int eth_register(struct eth_device* dev)
+{
+ struct eth_device *d;
+
+ if (!eth_devices) {
+ eth_current = eth_devices = dev;
+ } else {
+ for (d=eth_devices; d->next!=eth_devices; d=d->next);
+ d->next = dev;
+ }
+
+ dev->state = ETH_STATE_INIT;
+ dev->next = eth_devices;
+
+ return 0;
+}
+
+int eth_initialize(bd_t *bis)
+{
+ unsigned char enetvar[32], env_enetaddr[6];
+ int i, eth_number = 0;
+ char *tmp, *end;
+
+ eth_devices = NULL;
+ eth_current = NULL;
+
+#ifdef CONFIG_EEPRO100
+ eepro100_initialize(bis);
+#endif
+#ifdef CONFIG_TULIP
+ dc21x4x_initialize(bis);
+#endif
+#ifdef CONFIG_PCNET
+ pcnet_initialize(bis);
+#endif
+#ifdef CFG_GT_6426x
+ gt6426x_eth_initialize(bis);
+#endif
+#ifdef CONFIG_NATSEMI
+ natsemi_initialize(bis);
+#endif
+#ifdef CONFIG_NS8382X
+ ns8382x_initialize(bis);
+#endif
+#ifdef SCC_ENET
+ scc_initialize(bis);
+#endif
+#ifdef FEC_ENET
+ fec_initialize(bis);
+#endif
+
+ if (!eth_devices) {
+ puts ("No ethernet found.\n");
+ } else {
+ struct eth_device *dev = eth_devices;
+ char *ethprime = getenv ("ethprime");
+
+ do {
+ if (eth_number)
+ puts (", ");
+
+ printf("%s", dev->name);
+
+ if (ethprime && strcmp (dev->name, ethprime) == 0) {
+ eth_current = dev;
+ puts (" [PRIME]");
+ }
+
+ sprintf(enetvar, eth_number ? "eth%daddr" : "ethaddr", eth_number);
+ tmp = getenv (enetvar);
+
+ for (i=0; i<6; i++) {
+ env_enetaddr[i] = tmp ? simple_strtoul(tmp, &end, 16) : 0;
+ if (tmp)
+ tmp = (*end) ? end+1 : end;
+ }
+
+ if (memcmp(env_enetaddr, "\0\0\0\0\0\0", 6)) {
+ if (memcmp(dev->enetaddr, "\0\0\0\0\0\0", 6) &&
+ memcmp(dev->enetaddr, env_enetaddr, 6))
+ {
+ printf("\nWarning: %s HW address don't match:\n", dev->name);
+ printf("Address in SROM is "
+ "%02X:%02X:%02X:%02X:%02X:%02X\n",
+ dev->enetaddr[0], dev->enetaddr[1],
+ dev->enetaddr[2], dev->enetaddr[3],
+ dev->enetaddr[4], dev->enetaddr[5]);
+ printf("Address in environment is "
+ "%02X:%02X:%02X:%02X:%02X:%02X\n",
+ env_enetaddr[0], env_enetaddr[1],
+ env_enetaddr[2], env_enetaddr[3],
+ env_enetaddr[4], env_enetaddr[5]);
+ }
+
+ memcpy(dev->enetaddr, env_enetaddr, 6);
+ }
+
+ eth_number++;
+ dev = dev->next;
+ } while(dev != eth_devices);
+
+ putc ('\n');
+ }
+
+ return eth_number;
+}
+
+void eth_set_enetaddr(int num, char *addr) {
+ struct eth_device *dev;
+ unsigned char enetaddr[6];
+ char *end;
+ int i;
+
+#ifdef DEBUG
+ printf("eth_set_enetaddr(num=%d, addr=%s)\n", num, addr);
+#endif
+ if (!eth_devices)
+ return;
+
+ for (i=0; i<6; i++) {
+ enetaddr[i] = addr ? simple_strtoul(addr, &end, 16) : 0;
+ if (addr)
+ addr = (*end) ? end+1 : end;
+ }
+
+ dev = eth_devices;
+ while(num-- > 0) {
+ dev = dev->next;
+
+ if (dev == eth_devices)
+ return;
+ }
+
+#ifdef DEBUG
+ printf("Setting new HW address on %s\n", dev->name);
+ printf("New Address is "
+ "%02X:%02X:%02X:%02X:%02X:%02X\n",
+ dev->enetaddr[0], dev->enetaddr[1],
+ dev->enetaddr[2], dev->enetaddr[3],
+ dev->enetaddr[4], dev->enetaddr[5]);
+#endif
+
+ memcpy(dev->enetaddr, enetaddr, 6);
+}
+
+int eth_init(bd_t *bis)
+{
+ struct eth_device* old_current;
+
+ if (!eth_current)
+ return 0;
+
+ old_current = eth_current;
+ do {
+#ifdef DEBUG
+ printf("Trying %s\n", eth_current->name);
+#endif
+
+ if (eth_current->init(eth_current, bis)) {
+ eth_current->state = ETH_STATE_ACTIVE;
+
+ printf("%s configured\n", eth_current->name);
+ return 1;
+ }
+
+#ifdef DEBUG
+ puts ("FAIL\n");
+#endif
+
+ eth_try_another(0);
+ } while (old_current != eth_current);
+
+ return 0;
+}
+
+void eth_halt(void)
+{
+ if (!eth_current)
+ return;
+
+ eth_current->halt(eth_current);
+
+ eth_current->state = ETH_STATE_PASSIVE;
+}
+
+int eth_send(volatile void *packet, int length)
+{
+ if (!eth_current)
+ return -1;
+
+ return eth_current->send(eth_current, packet, length);
+}
+
+int eth_rx(void)
+{
+ if (!eth_current)
+ return -1;
+
+ return eth_current->recv(eth_current);
+}
+
+void eth_try_another(int first_restart)
+{
+ static struct eth_device *first_failed = NULL;
+
+ if (!eth_current)
+ return;
+
+ if (first_restart)
+ {
+ first_failed = eth_current;
+ }
+
+ eth_current = eth_current->next;
+
+ if (first_failed == eth_current)
+ {
+ NetRestartWrap = 1;
+ }
+}
+
+#endif
--- /dev/null
+/*
+ * Copyright (C) 2002 Wolfgang Denk <wd@denx.de>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <config.h>
+
+#ifdef CONFIG_POST
+#if defined(CONFIG_MPC823) || \
+ defined(CONFIG_MPC850) || \
+ defined(CONFIG_MPC855) || \
+ defined(CONFIG_MPC860) || \
+ defined(CONFIG_MPC824X)
+
+#include <post.h>
+#include <ppc_asm.tmpl>
+#include <ppc_defs.h>
+#include <asm/cache.h>
+
+#if CONFIG_POST & CFG_POST_CACHE
+
+ .text
+
+cache_post_dinvalidate:
+ lis r10, IDC_INVALL@h
+ mtspr DC_CST, r10
+ blr
+
+cache_post_iinvalidate:
+ lis r10, IDC_INVALL@h
+ mtspr IC_CST, r10
+ isync
+ blr
+
+cache_post_ddisable:
+ lis r10, IDC_DISABLE@h
+ mtspr DC_CST, r10
+ blr
+
+cache_post_dwb:
+ lis r10, IDC_ENABLE@h
+ mtspr DC_CST, r10
+ lis r10, DC_CFWT@h
+ mtspr DC_CST, r10
+ blr
+
+cache_post_dwt:
+ lis r10, IDC_ENABLE@h
+ mtspr DC_CST, r10
+ lis r10, DC_SFWT@h
+ mtspr DC_CST, r10
+ blr
+
+cache_post_idisable:
+ lis r10, IDC_DISABLE@h
+ mtspr IC_CST, r10
+ isync
+ blr
+
+cache_post_ienable:
+ lis r10, IDC_ENABLE@h
+ mtspr IC_CST, r10
+ isync
+ blr
+
+cache_post_iunlock:
+ lis r10, IDC_UNALL@h
+ mtspr IC_CST, r10
+ isync
+ blr
+
+cache_post_ilock:
+ mtspr IC_ADR, r3
+ lis r10, IDC_LDLCK@h
+ mtspr IC_CST, r10
+ isync
+ blr
+
+/*
+ * turn on the data cache
+ * switch the data cache to write-back or write-through mode
+ * invalidate the data cache
+ * write the negative pattern to a cached area
+ * read the area
+ *
+ * The negative pattern must be read at the last step
+ */
+ .global cache_post_test1
+cache_post_test1:
+ mflr r0
+ stw r0, 4(r1)
+
+ stwu r3, -4(r1)
+ stwu r4, -4(r1)
+
+ bl cache_post_dwb
+ bl cache_post_dinvalidate
+
+ /* Write the negative pattern to the test area */
+ lwz r0, 0(r1)
+ mtctr r0
+ li r0, 0xff
+ lwz r3, 4(r1)
+ subi r3, r3, 1
+1:
+ stbu r0, 1(r3)
+ bdnz 1b
+
+ /* Read the test area */
+ lwz r0, 0(r1)
+ mtctr r0
+ lwz r4, 4(r1)
+ subi r4, r4, 1
+ li r3, 0
+1:
+ lbzu r0, 1(r4)
+ cmpli cr0, r0, 0xff
+ beq 2f
+ li r3, -1
+ b 3f
+2:
+ bdnz 1b
+3:
+
+ bl cache_post_ddisable
+ bl cache_post_dinvalidate
+
+ addi r1, r1, 8
+
+ lwz r0, 4(r1)
+ mtlr r0
+ blr
+
+/*
+ * turn on the data cache
+ * switch the data cache to write-back or write-through mode
+ * invalidate the data cache
+ * write the zero pattern to a cached area
+ * turn off the data cache
+ * write the negative pattern to the area
+ * turn on the data cache
+ * read the area
+ *
+ * The negative pattern must be read at the last step
+ */
+ .global cache_post_test2
+cache_post_test2:
+ mflr r0
+ stw r0, 4(r1)
+
+ stwu r3, -4(r1)
+ stwu r4, -4(r1)
+
+ bl cache_post_dwb
+ bl cache_post_dinvalidate
+
+ /* Write the zero pattern to the test area */
+ lwz r0, 0(r1)
+ mtctr r0
+ li r0, 0
+ lwz r3, 4(r1)
+ subi r3, r3, 1
+1:
+ stbu r0, 1(r3)
+ bdnz 1b
+
+ bl cache_post_ddisable
+
+ /* Write the negative pattern to the test area */
+ lwz r0, 0(r1)
+ mtctr r0
+ li r0, 0xff
+ lwz r3, 4(r1)
+ subi r3, r3, 1
+1:
+ stbu r0, 1(r3)
+ bdnz 1b
+
+ bl cache_post_dwb
+
+ /* Read the test area */
+ lwz r0, 0(r1)
+ mtctr r0
+ lwz r4, 4(r1)
+ subi r4, r4, 1
+ li r3, 0
+1:
+ lbzu r0, 1(r4)
+ cmpli cr0, r0, 0xff
+ beq 2f
+ li r3, -1
+ b 3f
+2:
+ bdnz 1b
+3:
+
+ bl cache_post_ddisable
+ bl cache_post_dinvalidate
+
+ addi r1, r1, 8
+
+ lwz r0, 4(r1)
+ mtlr r0
+ blr
+
+/*
+ * turn on the data cache
+ * switch the data cache to write-through mode
+ * invalidate the data cache
+ * write the zero pattern to a cached area
+ * flush the data cache
+ * write the negative pattern to the area
+ * turn off the data cache
+ * read the area
+ *
+ * The negative pattern must be read at the last step
+ */
+ .global cache_post_test3
+cache_post_test3:
+ mflr r0
+ stw r0, 4(r1)
+
+ stwu r3, -4(r1)
+ stwu r4, -4(r1)
+
+ bl cache_post_ddisable
+ bl cache_post_dinvalidate
+
+ /* Write the zero pattern to the test area */
+ lwz r0, 0(r1)
+ mtctr r0
+ li r0, 0
+ lwz r3, 4(r1)
+ subi r3, r3, 1
+1:
+ stbu r0, 1(r3)
+ bdnz 1b
+
+ bl cache_post_dwt
+ bl cache_post_dinvalidate
+
+ /* Write the negative pattern to the test area */
+ lwz r0, 0(r1)
+ mtctr r0
+ li r0, 0xff
+ lwz r3, 4(r1)
+ subi r3, r3, 1
+1:
+ stbu r0, 1(r3)
+ bdnz 1b
+
+ bl cache_post_ddisable
+ bl cache_post_dinvalidate
+
+ /* Read the test area */
+ lwz r0, 0(r1)
+ mtctr r0
+ lwz r4, 4(r1)
+ subi r4, r4, 1
+ li r3, 0
+1:
+ lbzu r0, 1(r4)
+ cmpli cr0, r0, 0xff
+ beq 2f
+ li r3, -1
+ b 3f
+2:
+ bdnz 1b
+3:
+
+ addi r1, r1, 8
+
+ lwz r0, 4(r1)
+ mtlr r0
+ blr
+
+/*
+ * turn on the data cache
+ * switch the data cache to write-back mode
+ * invalidate the data cache
+ * write the negative pattern to a cached area
+ * flush the data cache
+ * write the zero pattern to the area
+ * invalidate the data cache
+ * read the area
+ *
+ * The negative pattern must be read at the last step
+ */
+ .global cache_post_test4
+cache_post_test4:
+ mflr r0
+ stw r0, 4(r1)
+
+ stwu r3, -4(r1)
+ stwu r4, -4(r1)
+
+ bl cache_post_ddisable
+ bl cache_post_dinvalidate
+
+ /* Write the negative pattern to the test area */
+ lwz r0, 0(r1)
+ mtctr r0
+ li r0, 0xff
+ lwz r3, 4(r1)
+ subi r3, r3, 1
+1:
+ stbu r0, 1(r3)
+ bdnz 1b
+
+ bl cache_post_dwb
+ bl cache_post_dinvalidate
+
+ /* Write the zero pattern to the test area */
+ lwz r0, 0(r1)
+ mtctr r0
+ li r0, 0
+ lwz r3, 4(r1)
+ subi r3, r3, 1
+1:
+ stbu r0, 1(r3)
+ bdnz 1b
+
+ bl cache_post_ddisable
+ bl cache_post_dinvalidate
+
+ /* Read the test area */
+ lwz r0, 0(r1)
+ mtctr r0
+ lwz r4, 4(r1)
+ subi r4, r4, 1
+ li r3, 0
+1:
+ lbzu r0, 1(r4)
+ cmpli cr0, r0, 0xff
+ beq 2f
+ li r3, -1
+ b 3f
+2:
+ bdnz 1b
+3:
+
+ addi r1, r1, 8
+
+ lwz r0, 4(r1)
+ mtlr r0
+ blr
+
+cache_post_test5_1:
+ li r3, 0
+cache_post_test5_2:
+ li r3, -1
+
+/*
+ * turn on the instruction cache
+ * unlock the entire instruction cache
+ * invalidate the instruction cache
+ * lock a branch instruction in the instruction cache
+ * replace the branch instruction with "nop"
+ * jump to the branch instruction
+ * check that the branch instruction was executed
+*/
+ .global cache_post_test5
+cache_post_test5:
+ mflr r0
+ stw r0, 4(r1)
+
+ bl cache_post_ienable
+ bl cache_post_iunlock
+ bl cache_post_iinvalidate
+
+ /* Compute r9 = cache_post_test5_reloc */
+ bl cache_post_test5_reloc
+cache_post_test5_reloc:
+ mflr r9
+
+ /* Copy the test instruction to cache_post_test5_data */
+ lis r3, (cache_post_test5_1 - cache_post_test5_reloc)@h
+ ori r3, r3, (cache_post_test5_1 - cache_post_test5_reloc)@l
+ add r3, r3, r9
+ lis r4, (cache_post_test5_data - cache_post_test5_reloc)@h
+ ori r4, r4, (cache_post_test5_data - cache_post_test5_reloc)@l
+ add r4, r4, r9
+ lwz r0, 0(r3)
+ stw r0, 0(r4)
+
+ bl cache_post_iinvalidate
+
+ /* Lock the branch instruction */
+ lis r3, (cache_post_test5_data - cache_post_test5_reloc)@h
+ ori r3, r3, (cache_post_test5_data - cache_post_test5_reloc)@l
+ add r3, r3, r9
+ bl cache_post_ilock
+
+ /* Replace the test instruction */
+ lis r3, (cache_post_test5_2 - cache_post_test5_reloc)@h
+ ori r3, r3, (cache_post_test5_2 - cache_post_test5_reloc)@l
+ add r3, r3, r9
+ lis r4, (cache_post_test5_data - cache_post_test5_reloc)@h
+ ori r4, r4, (cache_post_test5_data - cache_post_test5_reloc)@l
+ add r4, r4, r9
+ lwz r0, 0(r3)
+ stw r0, 0(r4)
+
+ bl cache_post_iinvalidate
+
+ /* Execute to the test instruction */
+cache_post_test5_data:
+ nop
+
+ bl cache_post_iunlock
+
+ lwz r0, 4(r1)
+ mtlr r0
+ blr
+
+cache_post_test6_1:
+ li r3, -1
+cache_post_test6_2:
+ li r3, 0
+
+/*
+ * turn on the instruction cache
+ * unlock the entire instruction cache
+ * invalidate the instruction cache
+ * lock a branch instruction in the instruction cache
+ * replace the branch instruction with "nop"
+ * jump to the branch instruction
+ * check that the branch instruction was executed
+ */
+ .global cache_post_test6
+cache_post_test6:
+ mflr r0
+ stw r0, 4(r1)
+
+ bl cache_post_ienable
+ bl cache_post_iunlock
+ bl cache_post_iinvalidate
+
+ /* Compute r9 = cache_post_test6_reloc */
+ bl cache_post_test6_reloc
+cache_post_test6_reloc:
+ mflr r9
+
+ /* Copy the test instruction to cache_post_test6_data */
+ lis r3, (cache_post_test6_1 - cache_post_test6_reloc)@h
+ ori r3, r3, (cache_post_test6_1 - cache_post_test6_reloc)@l
+ add r3, r3, r9
+ lis r4, (cache_post_test6_data - cache_post_test6_reloc)@h
+ ori r4, r4, (cache_post_test6_data - cache_post_test6_reloc)@l
+ add r4, r4, r9
+ lwz r0, 0(r3)
+ stw r0, 0(r4)
+
+ bl cache_post_iinvalidate
+
+ /* Replace the test instruction */
+ lis r3, (cache_post_test6_2 - cache_post_test6_reloc)@h
+ ori r3, r3, (cache_post_test6_2 - cache_post_test6_reloc)@l
+ add r3, r3, r9
+ lis r4, (cache_post_test6_data - cache_post_test6_reloc)@h
+ ori r4, r4, (cache_post_test6_data - cache_post_test6_reloc)@l
+ add r4, r4, r9
+ lwz r0, 0(r3)
+ stw r0, 0(r4)
+
+ bl cache_post_iinvalidate
+
+ /* Execute to the test instruction */
+cache_post_test6_data:
+ nop
+
+ lwz r0, 4(r1)
+ mtlr r0
+ blr
+
+#endif /* CONFIG_MPC823 || MPC850 || MPC855 || MPC860 || MPC824X */
+#endif /* CONFIG_POST & CFG_POST_CACHE */
+#endif /* CONFIG_POST */
--- /dev/null
+/*
+ * (C) Copyright 2002
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+
+/*
+ * CPU test
+ *
+ * This test checks the arithmetic logic unit (ALU) of CPU.
+ * It tests independently various groups of instructions using
+ * run-time modification of the code to reduce the memory footprint.
+ * For more details refer to post/cpu/ *.c files.
+ */
+
+#ifdef CONFIG_POST
+
+#include <watchdog.h>
+#include <post.h>
+
+#if CONFIG_POST & CFG_POST_CPU
+
+extern int cpu_post_test_cmp (void);
+extern int cpu_post_test_cmpi (void);
+extern int cpu_post_test_two (void);
+extern int cpu_post_test_twox (void);
+extern int cpu_post_test_three (void);
+extern int cpu_post_test_threex (void);
+extern int cpu_post_test_threei (void);
+extern int cpu_post_test_andi (void);
+extern int cpu_post_test_srawi (void);
+extern int cpu_post_test_rlwnm (void);
+extern int cpu_post_test_rlwinm (void);
+extern int cpu_post_test_rlwimi (void);
+extern int cpu_post_test_store (void);
+extern int cpu_post_test_load (void);
+extern int cpu_post_test_cr (void);
+extern int cpu_post_test_b (void);
+extern int cpu_post_test_multi (void);
+extern int cpu_post_test_string (void);
+extern int cpu_post_test_complex (void);
+
+ulong cpu_post_makecr (long v)
+{
+ ulong cr = 0;
+
+ if (v < 0)
+ cr |= 0x80000000;
+ if (v > 0)
+ cr |= 0x40000000;
+ if (v == 0)
+ cr |= 0x20000000;
+
+ return cr;
+}
+
+int cpu_post_test (int flags)
+{
+ int ic = icache_status ();
+ int ret = 0;
+
+ if (ic)
+ icache_disable ();
+
+ if (ret == 0)
+ ret = cpu_post_test_cmp ();
+ if (ret == 0)
+ ret = cpu_post_test_cmpi ();
+ if (ret == 0)
+ ret = cpu_post_test_two ();
+ if (ret == 0)
+ ret = cpu_post_test_twox ();
+ if (ret == 0)
+ ret = cpu_post_test_three ();
+ if (ret == 0)
+ ret = cpu_post_test_threex ();
+ if (ret == 0)
+ ret = cpu_post_test_threei ();
+ WATCHDOG_RESET();
+ if (ret == 0)
+ ret = cpu_post_test_andi ();
+ if (ret == 0)
+ ret = cpu_post_test_srawi ();
+ if (ret == 0)
+ ret = cpu_post_test_rlwnm ();
+ if (ret == 0)
+ ret = cpu_post_test_rlwinm ();
+ if (ret == 0)
+ ret = cpu_post_test_rlwimi ();
+ if (ret == 0)
+ ret = cpu_post_test_store ();
+ if (ret == 0)
+ ret = cpu_post_test_load ();
+ WATCHDOG_RESET();
+ if (ret == 0)
+ ret = cpu_post_test_cr ();
+ if (ret == 0)
+ ret = cpu_post_test_b ();
+ if (ret == 0)
+ ret = cpu_post_test_multi ();
+ if (ret == 0)
+ ret = cpu_post_test_string ();
+ if (ret == 0)
+ ret = cpu_post_test_complex ();
+
+ if (ic)
+ icache_enable ();
+
+ return ret;
+}
+
+#endif /* CONFIG_POST & CFG_POST_CPU */
+#endif /* CONFIG_POST */
--- /dev/null
+/*
+ * (C) Copyright 2002
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+
+/*
+ * CPU test
+ * Branch instructions: b, bl, bc
+ *
+ * The first 2 instructions (b, bl) are verified by jumping
+ * to a fixed address and checking whether control was transfered
+ * to that very point. For the bl instruction the value of the
+ * link register is checked as well (using mfspr).
+ * To verify the bc instruction various combinations of the BI/BO
+ * fields, the CTR and the condition register values are
+ * checked. The list of such combinations is pre-built and
+ * linked in U-Boot at build time.
+ */
+
+#ifdef CONFIG_POST
+
+#include <post.h>
+#include "cpu_asm.h"
+
+#if CONFIG_POST & CFG_POST_CPU
+
+extern void cpu_post_exec_11 (ulong *code, ulong *res, ulong op1);
+extern void cpu_post_exec_31 (ulong *code, ulong *ctr, ulong *lr, ulong *jump,
+ ulong cr);
+
+static int cpu_post_test_bc (ulong cmd, ulong bo, ulong bi,
+ int pjump, int dec, int link, ulong pctr, ulong cr)
+{
+ int ret = 0;
+ ulong lr = 0;
+ ulong ctr = pctr;
+ ulong jump;
+
+ unsigned long code[] =
+ {
+ ASM_MTCR(6),
+ ASM_MFLR(6),
+ ASM_MTCTR(3),
+ ASM_MTLR(4),
+ ASM_LI(5, 1),
+ ASM_3O(cmd, bo, bi, 8),
+ ASM_LI(5, 0),
+ ASM_MFCTR(3),
+ ASM_MFLR(4),
+ ASM_MTLR(6),
+ ASM_BLR,
+ };
+
+ cpu_post_exec_31 (code, &ctr, &lr, &jump, cr);
+
+ if (ret == 0)
+ ret = pjump == jump ? 0 : -1;
+ if (ret == 0)
+ {
+ if (dec)
+ ret = pctr == ctr + 1 ? 0 : -1;
+ else
+ ret = pctr == ctr ? 0 : -1;
+ }
+ if (ret == 0)
+ {
+ if (link)
+ ret = lr == (ulong) code + 24 ? 0 : -1;
+ else
+ ret = lr == 0 ? 0 : -1;
+ }
+
+ return ret;
+}
+
+int cpu_post_test_b (void)
+{
+ int ret = 0;
+ unsigned int i;
+
+ if (ret == 0)
+ {
+ ulong code[] =
+ {
+ ASM_MFLR(4),
+ ASM_MTLR(3),
+ ASM_B(4),
+ ASM_MFLR(3),
+ ASM_MTLR(4),
+ ASM_BLR,
+ };
+ ulong res;
+
+ cpu_post_exec_11 (code, &res, 0);
+
+ ret = res == 0 ? 0 : -1;
+
+ if (ret != 0)
+ {
+ post_log ("Error at b1 test !\n");
+ }
+ }
+
+ if (ret == 0)
+ {
+ ulong code[] =
+ {
+ ASM_MFLR(4),
+ ASM_MTLR(3),
+ ASM_BL(4),
+ ASM_MFLR(3),
+ ASM_MTLR(4),
+ ASM_BLR,
+ };
+ ulong res;
+
+ cpu_post_exec_11 (code, &res, 0);
+
+ ret = res == (ulong)code + 12 ? 0 : -1;
+
+ if (ret != 0)
+ {
+ post_log ("Error at b2 test !\n");
+ }
+ }
+
+ if (ret == 0)
+ {
+ ulong cc, cd;
+ int cond;
+ ulong ctr;
+ int link;
+
+ i = 0;
+
+ for (cc = 0; cc < 4 && ret == 0; cc++)
+ {
+ for (cd = 0; cd < 4 && ret == 0; cd++)
+ {
+ for (link = 0; link <= 1 && ret == 0; link++)
+ {
+ for (cond = 0; cond <= 1 && ret == 0; cond++)
+ {
+ for (ctr = 1; ctr <= 2 && ret == 0; ctr++)
+ {
+ int dec = cd < 2;
+ int cr = cond ? 0x80000000 : 0x00000000;
+ int jumpc = cc >= 2 ||
+ (cc == 0 && !cond) ||
+ (cc == 1 && cond);
+ int jumpd = cd >= 2 ||
+ (cd == 0 && ctr != 1) ||
+ (cd == 1 && ctr == 1);
+ int jump = jumpc && jumpd;
+
+ ret = cpu_post_test_bc (link ? OP_BCL : OP_BC,
+ (cc << 3) + (cd << 1), 0, jump, dec, link,
+ ctr, cr);
+
+ if (ret != 0)
+ {
+ post_log ("Error at b3 test %d !\n", i);
+ }
+
+ i++;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return ret;
+}
+
+#endif
+#endif
--- /dev/null
+/*
+ * (C) Copyright 2002
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+
+/*
+ * CPU test
+ * Integer compare instructions: cmpw, cmplw
+ *
+ * To verify these instructions the test runs them with
+ * different combinations of operands, reads the condition
+ * register value and compares it with the expected one.
+ * The test contains a pre-built table
+ * containing the description of each test case: the instruction,
+ * the values of the operands, the condition field to save
+ * the result in and the expected result.
+ */
+
+#ifdef CONFIG_POST
+
+#include <post.h>
+#include "cpu_asm.h"
+
+#if CONFIG_POST & CFG_POST_CPU
+
+extern void cpu_post_exec_12 (ulong *code, ulong *res, ulong op1, ulong op2);
+
+static struct cpu_post_cmp_s
+{
+ ulong cmd;
+ ulong op1;
+ ulong op2;
+ ulong cr;
+ ulong res;
+} cpu_post_cmp_table[] =
+{
+ {
+ OP_CMPW,
+ 123,
+ 123,
+ 2,
+ 0x02
+ },
+ {
+ OP_CMPW,
+ 123,
+ 133,
+ 3,
+ 0x08
+ },
+ {
+ OP_CMPW,
+ 123,
+ -133,
+ 4,
+ 0x04
+ },
+ {
+ OP_CMPLW,
+ 123,
+ 123,
+ 2,
+ 0x02
+ },
+ {
+ OP_CMPLW,
+ 123,
+ -133,
+ 3,
+ 0x08
+ },
+ {
+ OP_CMPLW,
+ 123,
+ 113,
+ 4,
+ 0x04
+ },
+};
+static unsigned int cpu_post_cmp_size =
+ sizeof (cpu_post_cmp_table) / sizeof (struct cpu_post_cmp_s);
+
+int cpu_post_test_cmp (void)
+{
+ int ret = 0;
+ unsigned int i;
+
+ for (i = 0; i < cpu_post_cmp_size && ret == 0; i++)
+ {
+ struct cpu_post_cmp_s *test = cpu_post_cmp_table + i;
+ unsigned long code[] =
+ {
+ ASM_2C(test->cmd, test->cr, 3, 4),
+ ASM_MFCR(3),
+ ASM_BLR
+ };
+ ulong res;
+
+ cpu_post_exec_12 (code, & res, test->op1, test->op2);
+
+ ret = ((res >> (28 - 4 * test->cr)) & 0xe) == test->res ? 0 : -1;
+
+ if (ret != 0)
+ {
+ post_log ("Error at cmp test %d !\n", i);
+ }
+ }
+
+ return ret;
+}
+
+#endif
+#endif
--- /dev/null
+/*
+ * (C) Copyright 2002
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+
+/*
+ * CPU test
+ * Integer compare instructions: cmpwi, cmplwi
+ *
+ * To verify these instructions the test runs them with
+ * different combinations of operands, reads the condition
+ * register value and compares it with the expected one.
+ * The test contains a pre-built table
+ * containing the description of each test case: the instruction,
+ * the values of the operands, the condition field to save
+ * the result in and the expected result.
+ */
+
+#ifdef CONFIG_POST
+
+#include <post.h>
+#include "cpu_asm.h"
+
+#if CONFIG_POST & CFG_POST_CPU
+
+extern void cpu_post_exec_11 (ulong *code, ulong *res, ulong op1);
+
+static struct cpu_post_cmpi_s
+{
+ ulong cmd;
+ ulong op1;
+ ushort op2;
+ ulong cr;
+ ulong res;
+} cpu_post_cmpi_table[] =
+{
+ {
+ OP_CMPWI,
+ 123,
+ 123,
+ 2,
+ 0x02
+ },
+ {
+ OP_CMPWI,
+ 123,
+ 133,
+ 3,
+ 0x08
+ },
+ {
+ OP_CMPWI,
+ 123,
+ -133,
+ 4,
+ 0x04
+ },
+ {
+ OP_CMPLWI,
+ 123,
+ 123,
+ 2,
+ 0x02
+ },
+ {
+ OP_CMPLWI,
+ 123,
+ -133,
+ 3,
+ 0x08
+ },
+ {
+ OP_CMPLWI,
+ 123,
+ 113,
+ 4,
+ 0x04
+ },
+};
+static unsigned int cpu_post_cmpi_size =
+ sizeof (cpu_post_cmpi_table) / sizeof (struct cpu_post_cmpi_s);
+
+int cpu_post_test_cmpi (void)
+{
+ int ret = 0;
+ unsigned int i;
+
+ for (i = 0; i < cpu_post_cmpi_size && ret == 0; i++)
+ {
+ struct cpu_post_cmpi_s *test = cpu_post_cmpi_table + i;
+ unsigned long code[] =
+ {
+ ASM_1IC(test->cmd, test->cr, 3, test->op2),
+ ASM_MFCR(3),
+ ASM_BLR
+ };
+ ulong res;
+
+ cpu_post_exec_11 (code, & res, test->op1);
+
+ ret = ((res >> (28 - 4 * test->cr)) & 0xe) == test->res ? 0 : -1;
+
+ if (ret != 0)
+ {
+ post_log ("Error at cmpi test %d !\n", i);
+ }
+ }
+
+ return ret;
+}
+
+#endif
+#endif
--- /dev/null
+/*
+ * (C) Copyright 2002
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+
+/*
+ * CPU test
+ * Condition register istructions: mtcr, mfcr, mcrxr,
+ * crand, crandc, cror, crorc, crxor,
+ * crnand, crnor, creqv, mcrf
+ *
+ * The mtcrf/mfcr instructions is tested by loading different
+ * values into the condition register (mtcrf), moving its value
+ * to a general-purpose register (mfcr) and comparing this value
+ * with the expected one.
+ * The mcrxr instruction is tested by loading a fixed value
+ * into the XER register (mtspr), moving XER value to the
+ * condition register (mcrxr), moving it to a general-purpose
+ * register (mfcr) and comparing the value of this register with
+ * the expected one.
+ * The rest of instructions is tested by loading a fixed
+ * value into the condition register (mtcrf), executing each
+ * instruction several times to modify all 4-bit condition
+ * fields, moving the value of the conditional register to a
+ * general-purpose register (mfcr) and comparing it with the
+ * expected one.
+ */
+
+#ifdef CONFIG_POST
+
+#include <post.h>
+#include "cpu_asm.h"
+
+#if CONFIG_POST & CFG_POST_CPU
+
+extern void cpu_post_exec_11 (ulong *code, ulong *res, ulong op1);
+extern void cpu_post_exec_21x (ulong *code, ulong *op1, ulong *op2, ulong op3);
+
+static ulong cpu_post_cr_table1[] =
+{
+ 0xaaaaaaaa,
+ 0x55555555,
+};
+static unsigned int cpu_post_cr_size1 =
+ sizeof (cpu_post_cr_table1) / sizeof (ulong);
+
+static struct cpu_post_cr_s2 {
+ ulong xer;
+ ulong cr;
+} cpu_post_cr_table2[] =
+{
+ {
+ 0xa0000000,
+ 1
+ },
+ {
+ 0x40000000,
+ 5
+ },
+};
+static unsigned int cpu_post_cr_size2 =
+ sizeof (cpu_post_cr_table2) / sizeof (struct cpu_post_cr_s2);
+
+static struct cpu_post_cr_s3 {
+ ulong cr;
+ ulong cs;
+ ulong cd;
+ ulong res;
+} cpu_post_cr_table3[] =
+{
+ {
+ 0x01234567,
+ 0,
+ 4,
+ 0x01230567
+ },
+ {
+ 0x01234567,
+ 7,
+ 0,
+ 0x71234567
+ },
+};
+static unsigned int cpu_post_cr_size3 =
+ sizeof (cpu_post_cr_table3) / sizeof (struct cpu_post_cr_s3);
+
+static struct cpu_post_cr_s4 {
+ ulong cmd;
+ ulong cr;
+ ulong op1;
+ ulong op2;
+ ulong op3;
+ ulong res;
+} cpu_post_cr_table4[] =
+{
+ {
+ OP_CRAND,
+ 0x0000ffff,
+ 0,
+ 16,
+ 0,
+ 0x0000ffff
+ },
+ {
+ OP_CRAND,
+ 0x0000ffff,
+ 16,
+ 17,
+ 0,
+ 0x8000ffff
+ },
+ {
+ OP_CRANDC,
+ 0x0000ffff,
+ 0,
+ 16,
+ 0,
+ 0x0000ffff
+ },
+ {
+ OP_CRANDC,
+ 0x0000ffff,
+ 16,
+ 0,
+ 0,
+ 0x8000ffff
+ },
+ {
+ OP_CROR,
+ 0x0000ffff,
+ 0,
+ 16,
+ 0,
+ 0x8000ffff
+ },
+ {
+ OP_CROR,
+ 0x0000ffff,
+ 0,
+ 1,
+ 0,
+ 0x0000ffff
+ },
+ {
+ OP_CRORC,
+ 0x0000ffff,
+ 0,
+ 16,
+ 0,
+ 0x0000ffff
+ },
+ {
+ OP_CRORC,
+ 0x0000ffff,
+ 0,
+ 0,
+ 0,
+ 0x8000ffff
+ },
+ {
+ OP_CRXOR,
+ 0x0000ffff,
+ 0,
+ 0,
+ 0,
+ 0x0000ffff
+ },
+ {
+ OP_CRXOR,
+ 0x0000ffff,
+ 0,
+ 16,
+ 0,
+ 0x8000ffff
+ },
+ {
+ OP_CRNAND,
+ 0x0000ffff,
+ 0,
+ 16,
+ 0,
+ 0x8000ffff
+ },
+ {
+ OP_CRNAND,
+ 0x0000ffff,
+ 16,
+ 17,
+ 0,
+ 0x0000ffff
+ },
+ {
+ OP_CRNOR,
+ 0x0000ffff,
+ 0,
+ 16,
+ 0,
+ 0x0000ffff
+ },
+ {
+ OP_CRNOR,
+ 0x0000ffff,
+ 0,
+ 1,
+ 0,
+ 0x8000ffff
+ },
+ {
+ OP_CREQV,
+ 0x0000ffff,
+ 0,
+ 0,
+ 0,
+ 0x8000ffff
+ },
+ {
+ OP_CREQV,
+ 0x0000ffff,
+ 0,
+ 16,
+ 0,
+ 0x0000ffff
+ },
+};
+static unsigned int cpu_post_cr_size4 =
+ sizeof (cpu_post_cr_table4) / sizeof (struct cpu_post_cr_s4);
+
+int cpu_post_test_cr (void)
+{
+ int ret = 0;
+ unsigned int i;
+ unsigned long cr_sav;
+
+ asm ( "mfcr %0" : "=r" (cr_sav) : );
+
+ for (i = 0; i < cpu_post_cr_size1 && ret == 0; i++)
+ {
+ ulong cr = cpu_post_cr_table1[i];
+ ulong res;
+
+ unsigned long code[] =
+ {
+ ASM_MTCR(3),
+ ASM_MFCR(3),
+ ASM_BLR,
+ };
+
+ cpu_post_exec_11 (code, &res, cr);
+
+ ret = res == cr ? 0 : -1;
+
+ if (ret != 0)
+ {
+ post_log ("Error at cr1 test %d !\n", i);
+ }
+ }
+
+ for (i = 0; i < cpu_post_cr_size2 && ret == 0; i++)
+ {
+ struct cpu_post_cr_s2 *test = cpu_post_cr_table2 + i;
+ ulong res;
+ ulong xer;
+
+ unsigned long code[] =
+ {
+ ASM_MTXER(3),
+ ASM_MCRXR(test->cr),
+ ASM_MFCR(3),
+ ASM_MFXER(4),
+ ASM_BLR,
+ };
+
+ cpu_post_exec_21x (code, &res, &xer, test->xer);
+
+ ret = xer == 0 && ((res << (4 * test->cr)) & 0xe0000000) == test->xer ?
+ 0 : -1;
+
+ if (ret != 0)
+ {
+ post_log ("Error at cr2 test %d !\n", i);
+ }
+ }
+
+ for (i = 0; i < cpu_post_cr_size3 && ret == 0; i++)
+ {
+ struct cpu_post_cr_s3 *test = cpu_post_cr_table3 + i;
+ ulong res;
+
+ unsigned long code[] =
+ {
+ ASM_MTCR(3),
+ ASM_MCRF(test->cd, test->cs),
+ ASM_MFCR(3),
+ ASM_BLR,
+ };
+
+ cpu_post_exec_11 (code, &res, test->cr);
+
+ ret = res == test->res ? 0 : -1;
+
+ if (ret != 0)
+ {
+ post_log ("Error at cr3 test %d !\n", i);
+ }
+ }
+
+ for (i = 0; i < cpu_post_cr_size4 && ret == 0; i++)
+ {
+ struct cpu_post_cr_s4 *test = cpu_post_cr_table4 + i;
+ ulong res;
+
+ unsigned long code[] =
+ {
+ ASM_MTCR(3),
+ ASM_12F(test->cmd, test->op3, test->op1, test->op2),
+ ASM_MFCR(3),
+ ASM_BLR,
+ };
+
+ cpu_post_exec_11 (code, &res, test->cr);
+
+ ret = res == test->res ? 0 : -1;
+
+ if (ret != 0)
+ {
+ post_log ("Error at cr4 test %d !\n", i);
+ }
+ }
+
+ asm ( "mtcr %0" : : "r" (cr_sav));
+
+ return ret;
+}
+
+#endif
+#endif
--- /dev/null
+/*
+ * (C) Copyright 2002
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+
+/*
+ * CPU test
+ * Ternary instructions instr rD,rA,rB
+ *
+ * Arithmetic instructions: add, addc, adde, subf, subfc, subfe,
+ * mullw, mulhw, mulhwu, divw, divwu
+ *
+ * The test contains a pre-built table of instructions, operands and
+ * expected results. For each table entry, the test will cyclically use
+ * different sets of operand registers and result registers.
+ */
+
+#ifdef CONFIG_POST
+
+#include <post.h>
+#include "cpu_asm.h"
+
+#if CONFIG_POST & CFG_POST_CPU
+
+extern void cpu_post_exec_22 (ulong *code, ulong *cr, ulong *res, ulong op1,
+ ulong op2);
+extern ulong cpu_post_makecr (long v);
+
+static struct cpu_post_three_s
+{
+ ulong cmd;
+ ulong op1;
+ ulong op2;
+ ulong res;
+} cpu_post_three_table[] =
+{
+ {
+ OP_ADD,
+ 100,
+ 200,
+ 300
+ },
+ {
+ OP_ADD,
+ 100,
+ -200,
+ -100
+ },
+ {
+ OP_ADDC,
+ 100,
+ 200,
+ 300
+ },
+ {
+ OP_ADDC,
+ 100,
+ -200,
+ -100
+ },
+ {
+ OP_ADDE,
+ 100,
+ 200,
+ 300
+ },
+ {
+ OP_ADDE,
+ 100,
+ -200,
+ -100
+ },
+ {
+ OP_SUBF,
+ 100,
+ 200,
+ 100
+ },
+ {
+ OP_SUBF,
+ 300,
+ 200,
+ -100
+ },
+ {
+ OP_SUBFC,
+ 100,
+ 200,
+ 100
+ },
+ {
+ OP_SUBFC,
+ 300,
+ 200,
+ -100
+ },
+ {
+ OP_SUBFE,
+ 100,
+ 200,
+ 200 + ~100
+ },
+ {
+ OP_SUBFE,
+ 300,
+ 200,
+ 200 + ~300
+ },
+ {
+ OP_MULLW,
+ 200,
+ 300,
+ 200 * 300
+ },
+ {
+ OP_MULHW,
+ 0x10000000,
+ 0x10000000,
+ 0x1000000
+ },
+ {
+ OP_MULHWU,
+ 0x80000000,
+ 0x80000000,
+ 0x40000000
+ },
+ {
+ OP_DIVW,
+ -20,
+ 5,
+ -4
+ },
+ {
+ OP_DIVWU,
+ 0x8000,
+ 0x200,
+ 0x40
+ },
+};
+static unsigned int cpu_post_three_size =
+ sizeof (cpu_post_three_table) / sizeof (struct cpu_post_three_s);
+
+int cpu_post_test_three (void)
+{
+ int ret = 0;
+ unsigned int i, reg;
+ int flag = disable_interrupts();
+
+ for (i = 0; i < cpu_post_three_size && ret == 0; i++)
+ {
+ struct cpu_post_three_s *test = cpu_post_three_table + i;
+
+ for (reg = 0; reg < 32 && ret == 0; reg++)
+ {
+ unsigned int reg0 = (reg + 0) % 32;
+ unsigned int reg1 = (reg + 1) % 32;
+ unsigned int reg2 = (reg + 2) % 32;
+ unsigned int stk = reg < 16 ? 31 : 15;
+ unsigned long code[] =
+ {
+ ASM_STW(stk, 1, -4),
+ ASM_ADDI(stk, 1, -24),
+ ASM_STW(3, stk, 12),
+ ASM_STW(4, stk, 16),
+ ASM_STW(reg0, stk, 8),
+ ASM_STW(reg1, stk, 4),
+ ASM_STW(reg2, stk, 0),
+ ASM_LWZ(reg1, stk, 12),
+ ASM_LWZ(reg0, stk, 16),
+ ASM_12(test->cmd, reg2, reg1, reg0),
+ ASM_STW(reg2, stk, 12),
+ ASM_LWZ(reg2, stk, 0),
+ ASM_LWZ(reg1, stk, 4),
+ ASM_LWZ(reg0, stk, 8),
+ ASM_LWZ(3, stk, 12),
+ ASM_ADDI(1, stk, 24),
+ ASM_LWZ(stk, 1, -4),
+ ASM_BLR,
+ };
+ unsigned long codecr[] =
+ {
+ ASM_STW(stk, 1, -4),
+ ASM_ADDI(stk, 1, -24),
+ ASM_STW(3, stk, 12),
+ ASM_STW(4, stk, 16),
+ ASM_STW(reg0, stk, 8),
+ ASM_STW(reg1, stk, 4),
+ ASM_STW(reg2, stk, 0),
+ ASM_LWZ(reg1, stk, 12),
+ ASM_LWZ(reg0, stk, 16),
+ ASM_12(test->cmd, reg2, reg1, reg0) | BIT_C,
+ ASM_STW(reg2, stk, 12),
+ ASM_LWZ(reg2, stk, 0),
+ ASM_LWZ(reg1, stk, 4),
+ ASM_LWZ(reg0, stk, 8),
+ ASM_LWZ(3, stk, 12),
+ ASM_ADDI(1, stk, 24),
+ ASM_LWZ(stk, 1, -4),
+ ASM_BLR,
+ };
+ ulong res;
+ ulong cr;
+
+ if (ret == 0)
+ {
+ cr = 0;
+ cpu_post_exec_22 (code, & cr, & res, test->op1, test->op2);
+
+ ret = res == test->res && cr == 0 ? 0 : -1;
+
+ if (ret != 0)
+ {
+ post_log ("Error at three test %d !\n", i);
+ }
+ }
+
+ if (ret == 0)
+ {
+ cpu_post_exec_22 (codecr, & cr, & res, test->op1, test->op2);
+
+ ret = res == test->res &&
+ (cr & 0xe0000000) == cpu_post_makecr (res) ? 0 : -1;
+
+ if (ret != 0)
+ {
+ post_log ("Error at three test %d !\n", i);
+ }
+ }
+ }
+ }
+
+ if (flag)
+ enable_interrupts();
+
+ return ret;
+}
+
+#endif
+#endif
--- /dev/null
+/*
+ * (C) Copyright 2002
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+
+/*
+ * CPU test
+ * Ternary instructions instr rA,rS,UIMM
+ *
+ * Logic instructions: ori, oris, xori, xoris
+ *
+ * The test contains a pre-built table of instructions, operands and
+ * expected results. For each table entry, the test will cyclically use
+ * different sets of operand registers and result registers.
+ */
+
+#ifdef CONFIG_POST
+
+#include <post.h>
+#include "cpu_asm.h"
+
+#if CONFIG_POST & CFG_POST_CPU
+
+extern void cpu_post_exec_21 (ulong *code, ulong *cr, ulong *res, ulong op);
+extern ulong cpu_post_makecr (long v);
+
+static struct cpu_post_threei_s
+{
+ ulong cmd;
+ ulong op1;
+ ushort op2;
+ ulong res;
+} cpu_post_threei_table[] =
+{
+ {
+ OP_ORI,
+ 0x80000000,
+ 0xffff,
+ 0x8000ffff
+ },
+ {
+ OP_ORIS,
+ 0x00008000,
+ 0xffff,
+ 0xffff8000
+ },
+ {
+ OP_XORI,
+ 0x8000ffff,
+ 0xffff,
+ 0x80000000
+ },
+ {
+ OP_XORIS,
+ 0x00008000,
+ 0xffff,
+ 0xffff8000
+ },
+};
+static unsigned int cpu_post_threei_size =
+ sizeof (cpu_post_threei_table) / sizeof (struct cpu_post_threei_s);
+
+int cpu_post_test_threei (void)
+{
+ int ret = 0;
+ unsigned int i, reg;
+ int flag = disable_interrupts();
+
+ for (i = 0; i < cpu_post_threei_size && ret == 0; i++)
+ {
+ struct cpu_post_threei_s *test = cpu_post_threei_table + i;
+
+ for (reg = 0; reg < 32 && ret == 0; reg++)
+ {
+ unsigned int reg0 = (reg + 0) % 32;
+ unsigned int reg1 = (reg + 1) % 32;
+ unsigned int stk = reg < 16 ? 31 : 15;
+ unsigned long code[] =
+ {
+ ASM_STW(stk, 1, -4),
+ ASM_ADDI(stk, 1, -16),
+ ASM_STW(3, stk, 8),
+ ASM_STW(reg0, stk, 4),
+ ASM_STW(reg1, stk, 0),
+ ASM_LWZ(reg0, stk, 8),
+ ASM_11IX(test->cmd, reg1, reg0, test->op2),
+ ASM_STW(reg1, stk, 8),
+ ASM_LWZ(reg1, stk, 0),
+ ASM_LWZ(reg0, stk, 4),
+ ASM_LWZ(3, stk, 8),
+ ASM_ADDI(1, stk, 16),
+ ASM_LWZ(stk, 1, -4),
+ ASM_BLR,
+ };
+ ulong res;
+ ulong cr;
+
+ cr = 0;
+ cpu_post_exec_21 (code, & cr, & res, test->op1);
+
+ ret = res == test->res && cr == 0 ? 0 : -1;
+
+ if (ret != 0)
+ {
+ post_log ("Error at threei test %d !\n", i);
+ }
+ }
+ }
+
+ if (flag)
+ enable_interrupts();
+
+ return ret;
+}
+
+#endif
+#endif
--- /dev/null
+/*
+ * (C) Copyright 2002
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+
+/*
+ * CPU test
+ * Ternary instructions instr rA,rS,rB
+ *
+ * Logic instructions: or, orc, xor, nand, nor, eqv
+ * Shift instructions: slw, srw, sraw
+ *
+ * The test contains a pre-built table of instructions, operands and
+ * expected results. For each table entry, the test will cyclically use
+ * different sets of operand registers and result registers.
+ */
+
+#ifdef CONFIG_POST
+
+#include <post.h>
+#include "cpu_asm.h"
+
+#if CONFIG_POST & CFG_POST_CPU
+
+extern void cpu_post_exec_22 (ulong *code, ulong *cr, ulong *res, ulong op1,
+ ulong op2);
+extern ulong cpu_post_makecr (long v);
+
+static struct cpu_post_threex_s
+{
+ ulong cmd;
+ ulong op1;
+ ulong op2;
+ ulong res;
+} cpu_post_threex_table[] =
+{
+ {
+ OP_OR,
+ 0x1234,
+ 0x5678,
+ 0x1234 | 0x5678
+ },
+ {
+ OP_ORC,
+ 0x1234,
+ 0x5678,
+ 0x1234 | ~0x5678
+ },
+ {
+ OP_XOR,
+ 0x1234,
+ 0x5678,
+ 0x1234 ^ 0x5678
+ },
+ {
+ OP_NAND,
+ 0x1234,
+ 0x5678,
+ ~(0x1234 & 0x5678)
+ },
+ {
+ OP_NOR,
+ 0x1234,
+ 0x5678,
+ ~(0x1234 | 0x5678)
+ },
+ {
+ OP_EQV,
+ 0x1234,
+ 0x5678,
+ ~(0x1234 ^ 0x5678)
+ },
+ {
+ OP_SLW,
+ 0x80,
+ 16,
+ 0x800000
+ },
+ {
+ OP_SLW,
+ 0x80,
+ 32,
+ 0
+ },
+ {
+ OP_SRW,
+ 0x800000,
+ 16,
+ 0x80
+ },
+ {
+ OP_SRW,
+ 0x800000,
+ 32,
+ 0
+ },
+ {
+ OP_SRAW,
+ 0x80000000,
+ 3,
+ 0xf0000000
+ },
+ {
+ OP_SRAW,
+ 0x8000,
+ 3,
+ 0x1000
+ },
+};
+static unsigned int cpu_post_threex_size =
+ sizeof (cpu_post_threex_table) / sizeof (struct cpu_post_threex_s);
+
+int cpu_post_test_threex (void)
+{
+ int ret = 0;
+ unsigned int i, reg;
+ int flag = disable_interrupts();
+
+ for (i = 0; i < cpu_post_threex_size && ret == 0; i++)
+ {
+ struct cpu_post_threex_s *test = cpu_post_threex_table + i;
+
+ for (reg = 0; reg < 32 && ret == 0; reg++)
+ {
+ unsigned int reg0 = (reg + 0) % 32;
+ unsigned int reg1 = (reg + 1) % 32;
+ unsigned int reg2 = (reg + 2) % 32;
+ unsigned int stk = reg < 16 ? 31 : 15;
+ unsigned long code[] =
+ {
+ ASM_STW(stk, 1, -4),
+ ASM_ADDI(stk, 1, -24),
+ ASM_STW(3, stk, 12),
+ ASM_STW(4, stk, 16),
+ ASM_STW(reg0, stk, 8),
+ ASM_STW(reg1, stk, 4),
+ ASM_STW(reg2, stk, 0),
+ ASM_LWZ(reg1, stk, 12),
+ ASM_LWZ(reg0, stk, 16),
+ ASM_12X(test->cmd, reg2, reg1, reg0),
+ ASM_STW(reg2, stk, 12),
+ ASM_LWZ(reg2, stk, 0),
+ ASM_LWZ(reg1, stk, 4),
+ ASM_LWZ(reg0, stk, 8),
+ ASM_LWZ(3, stk, 12),
+ ASM_ADDI(1, stk, 24),
+ ASM_LWZ(stk, 1, -4),
+ ASM_BLR,
+ };
+ unsigned long codecr[] =
+ {
+ ASM_STW(stk, 1, -4),
+ ASM_ADDI(stk, 1, -24),
+ ASM_STW(3, stk, 12),
+ ASM_STW(4, stk, 16),
+ ASM_STW(reg0, stk, 8),
+ ASM_STW(reg1, stk, 4),
+ ASM_STW(reg2, stk, 0),
+ ASM_LWZ(reg1, stk, 12),
+ ASM_LWZ(reg0, stk, 16),
+ ASM_12X(test->cmd, reg2, reg1, reg0) | BIT_C,
+ ASM_STW(reg2, stk, 12),
+ ASM_LWZ(reg2, stk, 0),
+ ASM_LWZ(reg1, stk, 4),
+ ASM_LWZ(reg0, stk, 8),
+ ASM_LWZ(3, stk, 12),
+ ASM_ADDI(1, stk, 24),
+ ASM_LWZ(stk, 1, -4),
+ ASM_BLR,
+ };
+ ulong res;
+ ulong cr;
+
+ if (ret == 0)
+ {
+ cr = 0;
+ cpu_post_exec_22 (code, & cr, & res, test->op1, test->op2);
+
+ ret = res == test->res && cr == 0 ? 0 : -1;
+
+ if (ret != 0)
+ {
+ post_log ("Error at threex test %d !\n", i);
+ }
+ }
+
+ if (ret == 0)
+ {
+ cpu_post_exec_22 (codecr, & cr, & res, test->op1, test->op2);
+
+ ret = res == test->res &&
+ (cr & 0xe0000000) == cpu_post_makecr (res) ? 0 : -1;
+
+ if (ret != 0)
+ {
+ post_log ("Error at threex test %d !\n", i);
+ }
+ }
+ }
+ }
+
+ if (flag)
+ enable_interrupts();
+
+ return ret;
+}
+
+#endif
+#endif
--- /dev/null
+/*
+ * (C) Copyright 2002
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+
+/*
+ * CPU test
+ * Binary instructions instr rD,rA
+ *
+ * Logic instructions: neg
+ * Arithmetic instructions: addme, addze, subfme, subfze
+
+ * The test contains a pre-built table of instructions, operands and
+ * expected results. For each table entry, the test will cyclically use
+ * different sets of operand registers and result registers.
+ */
+
+#ifdef CONFIG_POST
+
+#include <post.h>
+#include "cpu_asm.h"
+
+#if CONFIG_POST & CFG_POST_CPU
+
+extern void cpu_post_exec_21 (ulong *code, ulong *cr, ulong *res, ulong op1);
+extern ulong cpu_post_makecr (long v);
+
+static struct cpu_post_two_s
+{
+ ulong cmd;
+ ulong op;
+ ulong res;
+} cpu_post_two_table[] =
+{
+ {
+ OP_NEG,
+ 3,
+ -3
+ },
+ {
+ OP_NEG,
+ 5,
+ -5
+ },
+ {
+ OP_ADDME,
+ 6,
+ 5
+ },
+ {
+ OP_ADDZE,
+ 5,
+ 5
+ },
+ {
+ OP_SUBFME,
+ 6,
+ ~6 - 1
+ },
+ {
+ OP_SUBFZE,
+ 5,
+ ~5
+ },
+};
+static unsigned int cpu_post_two_size =
+ sizeof (cpu_post_two_table) / sizeof (struct cpu_post_two_s);
+
+int cpu_post_test_two (void)
+{
+ int ret = 0;
+ unsigned int i, reg;
+ int flag = disable_interrupts();
+
+ for (i = 0; i < cpu_post_two_size && ret == 0; i++)
+ {
+ struct cpu_post_two_s *test = cpu_post_two_table + i;
+
+ for (reg = 0; reg < 32 && ret == 0; reg++)
+ {
+ unsigned int reg0 = (reg + 0) % 32;
+ unsigned int reg1 = (reg + 1) % 32;
+ unsigned int stk = reg < 16 ? 31 : 15;
+ unsigned long code[] =
+ {
+ ASM_STW(stk, 1, -4),
+ ASM_ADDI(stk, 1, -16),
+ ASM_STW(3, stk, 8),
+ ASM_STW(reg0, stk, 4),
+ ASM_STW(reg1, stk, 0),
+ ASM_LWZ(reg0, stk, 8),
+ ASM_11(test->cmd, reg1, reg0),
+ ASM_STW(reg1, stk, 8),
+ ASM_LWZ(reg1, stk, 0),
+ ASM_LWZ(reg0, stk, 4),
+ ASM_LWZ(3, stk, 8),
+ ASM_ADDI(1, stk, 16),
+ ASM_LWZ(stk, 1, -4),
+ ASM_BLR,
+ };
+ unsigned long codecr[] =
+ {
+ ASM_STW(stk, 1, -4),
+ ASM_ADDI(stk, 1, -16),
+ ASM_STW(3, stk, 8),
+ ASM_STW(reg0, stk, 4),
+ ASM_STW(reg1, stk, 0),
+ ASM_LWZ(reg0, stk, 8),
+ ASM_11(test->cmd, reg1, reg0) | BIT_C,
+ ASM_STW(reg1, stk, 8),
+ ASM_LWZ(reg1, stk, 0),
+ ASM_LWZ(reg0, stk, 4),
+ ASM_LWZ(3, stk, 8),
+ ASM_ADDI(1, stk, 16),
+ ASM_LWZ(stk, 1, -4),
+ ASM_BLR,
+ };
+ ulong res;
+ ulong cr;
+
+ if (ret == 0)
+ {
+ cr = 0;
+ cpu_post_exec_21 (code, & cr, & res, test->op);
+
+ ret = res == test->res && cr == 0 ? 0 : -1;
+
+ if (ret != 0)
+ {
+ post_log ("Error at two test %d !\n", i);
+ }
+ }
+
+ if (ret == 0)
+ {
+ cpu_post_exec_21 (codecr, & cr, & res, test->op);
+
+ ret = res == test->res &&
+ (cr & 0xe0000000) == cpu_post_makecr (res) ? 0 : -1;
+
+ if (ret != 0)
+ {
+ post_log ("Error at two test %d !\n", i);
+ }
+ }
+ }
+ }
+
+ if (flag)
+ enable_interrupts();
+
+ return ret;
+}
+
+#endif
+#endif
--- /dev/null
+/*
+ * (C) Copyright 2002
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+
+/*
+ * CPU test
+ * Binary instructions instr rA,rS
+ *
+ * Logic instructions: cntlzw
+ * Arithmetic instructions: extsb, extsh
+
+ * The test contains a pre-built table of instructions, operands and
+ * expected results. For each table entry, the test will cyclically use
+ * different sets of operand registers and result registers.
+ */
+
+#ifdef CONFIG_POST
+
+#include <post.h>
+#include "cpu_asm.h"
+
+#if CONFIG_POST & CFG_POST_CPU
+
+extern void cpu_post_exec_21 (ulong *code, ulong *cr, ulong *res, ulong op1);
+extern ulong cpu_post_makecr (long v);
+
+static struct cpu_post_twox_s
+{
+ ulong cmd;
+ ulong op;
+ ulong res;
+} cpu_post_twox_table[] =
+{
+ {
+ OP_EXTSB,
+ 3,
+ 3
+ },
+ {
+ OP_EXTSB,
+ 0xff,
+ -1
+ },
+ {
+ OP_EXTSH,
+ 3,
+ 3
+ },
+ {
+ OP_EXTSH,
+ 0xff,
+ 0xff
+ },
+ {
+ OP_EXTSH,
+ 0xffff,
+ -1
+ },
+ {
+ OP_CNTLZW,
+ 0x000fffff,
+ 12
+ },
+};
+static unsigned int cpu_post_twox_size =
+ sizeof (cpu_post_twox_table) / sizeof (struct cpu_post_twox_s);
+
+int cpu_post_test_twox (void)
+{
+ int ret = 0;
+ unsigned int i, reg;
+ int flag = disable_interrupts();
+
+ for (i = 0; i < cpu_post_twox_size && ret == 0; i++)
+ {
+ struct cpu_post_twox_s *test = cpu_post_twox_table + i;
+
+ for (reg = 0; reg < 32 && ret == 0; reg++)
+ {
+ unsigned int reg0 = (reg + 0) % 32;
+ unsigned int reg1 = (reg + 1) % 32;
+ unsigned int stk = reg < 16 ? 31 : 15;
+ unsigned long code[] =
+ {
+ ASM_STW(stk, 1, -4),
+ ASM_ADDI(stk, 1, -16),
+ ASM_STW(3, stk, 8),
+ ASM_STW(reg0, stk, 4),
+ ASM_STW(reg1, stk, 0),
+ ASM_LWZ(reg0, stk, 8),
+ ASM_11X(test->cmd, reg1, reg0),
+ ASM_STW(reg1, stk, 8),
+ ASM_LWZ(reg1, stk, 0),
+ ASM_LWZ(reg0, stk, 4),
+ ASM_LWZ(3, stk, 8),
+ ASM_ADDI(1, stk, 16),
+ ASM_LWZ(stk, 1, -4),
+ ASM_BLR,
+ };
+ unsigned long codecr[] =
+ {
+ ASM_STW(stk, 1, -4),
+ ASM_ADDI(stk, 1, -16),
+ ASM_STW(3, stk, 8),
+ ASM_STW(reg0, stk, 4),
+ ASM_STW(reg1, stk, 0),
+ ASM_LWZ(reg0, stk, 8),
+ ASM_11X(test->cmd, reg1, reg0) | BIT_C,
+ ASM_STW(reg1, stk, 8),
+ ASM_LWZ(reg1, stk, 0),
+ ASM_LWZ(reg0, stk, 4),
+ ASM_LWZ(3, stk, 8),
+ ASM_ADDI(1, stk, 16),
+ ASM_LWZ(stk, 1, -4),
+ ASM_BLR,
+ };
+ ulong res;
+ ulong cr;
+
+ if (ret == 0)
+ {
+ cr = 0;
+ cpu_post_exec_21 (code, & cr, & res, test->op);
+
+ ret = res == test->res && cr == 0 ? 0 : -1;
+
+ if (ret != 0)
+ {
+ post_log ("Error at twox test %d !\n", i);
+ }
+ }
+
+ if (ret == 0)
+ {
+ cpu_post_exec_21 (codecr, & cr, & res, test->op);
+
+ ret = res == test->res &&
+ (cr & 0xe0000000) == cpu_post_makecr (res) ? 0 : -1;
+
+ if (ret != 0)
+ {
+ post_log ("Error at twox test %d !\n", i);
+ }
+ }
+ }
+ }
+
+ if (flag)
+ enable_interrupts();
+
+ return ret;
+}
+
+#endif
+#endif
--- /dev/null
+/*
+ * (C) Copyright 2002
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+
+/*
+ * Ethernet test
+ *
+ * The Serial Communication Controllers (SCC) listed in ctlr_list array below
+ * are tested in the loopback ethernet mode.
+ * The controllers are configured accordingly and several packets
+ * are transmitted. The configurable test parameters are:
+ * MIN_PACKET_LENGTH - minimum size of packet to transmit
+ * MAX_PACKET_LENGTH - maximum size of packet to transmit
+ * TEST_NUM - number of tests
+ */
+
+#ifdef CONFIG_POST
+
+#include <post.h>
+
+#if defined(CONFIG_8xx)
+#include <commproc.h>
+#elif defined(CONFIG_MPC8260)
+#include <asm/cpm_8260.h>
+#else
+#error "Apparently a bad configuration, please fix."
+#endif
+
+#include <command.h>
+#include <net.h>
+
+#if CONFIG_POST & CFG_POST_ETHER
+
+#define MIN_PACKET_LENGTH 64
+#define MAX_PACKET_LENGTH 256
+#define TEST_NUM 1
+
+#define CTLR_SCC 0
+
+extern void spi_init_f (void);
+extern void spi_init_r (void);
+
+/* The list of controllers to test */
+#if defined(CONFIG_MPC823)
+static int ctlr_list[][2] = { {CTLR_SCC, 1} };
+#else
+static int ctlr_list[][2] = { };
+#endif
+
+#define CTRL_LIST_SIZE (sizeof(ctlr_list) / sizeof(ctlr_list[0]))
+
+static struct {
+ void (*init) (int index);
+ int (*send) (int index, volatile void *packet, int length);
+ int (*recv) (int index, void *packet, int length);
+} ctlr_proc[1];
+
+static char *ctlr_name[1] = { "SCC" };
+
+static int used_by_uart[1] = { -1 };
+static int used_by_ether[1] = { -1 };
+
+/* Ethernet Transmit and Receive Buffers */
+#define DBUF_LENGTH 1520
+
+#define TX_BUF_CNT 2
+
+#define TOUT_LOOP 100
+
+static char txbuf[DBUF_LENGTH];
+
+static uint rxIdx; /* index of the current RX buffer */
+static uint txIdx; /* index of the current TX buffer */
+
+/*
+ * SCC Ethernet Tx and Rx buffer descriptors allocated at the
+ * immr->udata_bd address on Dual-Port RAM
+ * Provide for Double Buffering
+ */
+
+typedef volatile struct CommonBufferDescriptor {
+ cbd_t rxbd[PKTBUFSRX]; /* Rx BD */
+ cbd_t txbd[TX_BUF_CNT]; /* Tx BD */
+} RTXBD;
+
+static RTXBD *rtx;
+
+ /*
+ * SCC callbacks
+ */
+
+static void scc_init (int scc_index)
+{
+ DECLARE_GLOBAL_DATA_PTR;
+ bd_t *bd = gd->bd;
+
+ static int proff[] =
+ { PROFF_SCC1, PROFF_SCC2, PROFF_SCC3, PROFF_SCC4 };
+ static unsigned int cpm_cr[] =
+ { CPM_CR_CH_SCC1, CPM_CR_CH_SCC2, CPM_CR_CH_SCC3,
+CPM_CR_CH_SCC4 };
+
+ int i;
+ scc_enet_t *pram_ptr;
+
+ volatile immap_t *immr = (immap_t *) CFG_IMMR;
+
+ immr->im_cpm.cp_scc[scc_index].scc_gsmrl &=
+ ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT);
+
+#if defined(CONFIG_FADS)
+#if defined(CONFIG_MPC860T)
+ /* The FADS860T doesn't use the MODEM_EN or DATA_VOICE signals. */
+ *((uint *) BCSR4) &= ~BCSR4_ETHLOOP;
+ *((uint *) BCSR4) |= BCSR4_TFPLDL | BCSR4_TPSQEL;
+ *((uint *) BCSR1) &= ~BCSR1_ETHEN;
+#else
+ *((uint *) BCSR4) &= ~(BCSR4_ETHLOOP | BCSR4_MODEM_EN);
+ *((uint *) BCSR4) |= BCSR4_TFPLDL | BCSR4_TPSQEL | BCSR4_DATA_VOICE;
+ *((uint *) BCSR1) &= ~BCSR1_ETHEN;
+#endif
+#endif
+
+ pram_ptr = (scc_enet_t *) & (immr->im_cpm.cp_dparam[proff[scc_index]]);
+
+ rxIdx = 0;
+ txIdx = 0;
+
+#ifdef CFG_ALLOC_DPRAM
+ rtx = (RTXBD *) (immr->im_cpm.cp_dpmem +
+ dpram_alloc_align (sizeof (RTXBD), 8));
+#else
+ rtx = (RTXBD *) (immr->im_cpm.cp_dpmem + CPM_SCC_BASE);
+#endif
+
+#if 0
+
+#if (defined(PA_ENET_RXD) && defined(PA_ENET_TXD))
+ /* Configure port A pins for Txd and Rxd.
+ */
+ immr->im_ioport.iop_papar |= (PA_ENET_RXD | PA_ENET_TXD);
+ immr->im_ioport.iop_padir &= ~(PA_ENET_RXD | PA_ENET_TXD);
+ immr->im_ioport.iop_paodr &= ~PA_ENET_TXD;
+#elif (defined(PB_ENET_RXD) && defined(PB_ENET_TXD))
+ /* Configure port B pins for Txd and Rxd.
+ */
+ immr->im_cpm.cp_pbpar |= (PB_ENET_RXD | PB_ENET_TXD);
+ immr->im_cpm.cp_pbdir &= ~(PB_ENET_RXD | PB_ENET_TXD);
+ immr->im_cpm.cp_pbodr &= ~PB_ENET_TXD;
+#else
+#error Configuration Error: exactly ONE of PA_ENET_[RT]XD, PB_ENET_[RT]XD must be defined
+#endif
+
+#if defined(PC_ENET_LBK)
+ /* Configure port C pins to disable External Loopback
+ */
+ immr->im_ioport.iop_pcpar &= ~PC_ENET_LBK;
+ immr->im_ioport.iop_pcdir |= PC_ENET_LBK;
+ immr->im_ioport.iop_pcso &= ~PC_ENET_LBK;
+ immr->im_ioport.iop_pcdat &= ~PC_ENET_LBK; /* Disable Loopback */
+#endif /* PC_ENET_LBK */
+
+ /* Configure port C pins to enable CLSN and RENA.
+ */
+ immr->im_ioport.iop_pcpar &= ~(PC_ENET_CLSN | PC_ENET_RENA);
+ immr->im_ioport.iop_pcdir &= ~(PC_ENET_CLSN | PC_ENET_RENA);
+ immr->im_ioport.iop_pcso |= (PC_ENET_CLSN | PC_ENET_RENA);
+
+ /* Configure port A for TCLK and RCLK.
+ */
+ immr->im_ioport.iop_papar |= (PA_ENET_TCLK | PA_ENET_RCLK);
+ immr->im_ioport.iop_padir &= ~(PA_ENET_TCLK | PA_ENET_RCLK);
+
+ /*
+ * Configure Serial Interface clock routing -- see section 16.7.5.3
+ * First, clear all SCC bits to zero, then set the ones we want.
+ */
+
+ immr->im_cpm.cp_sicr &= ~SICR_ENET_MASK;
+ immr->im_cpm.cp_sicr |= SICR_ENET_CLKRT;
+#else
+ /*
+ * SCC2 receive clock is BRG2
+ * SCC2 transmit clock is BRG3
+ */
+ immr->im_cpm.cp_brgc2 = 0x0001000C;
+ immr->im_cpm.cp_brgc3 = 0x0001000C;
+
+ immr->im_cpm.cp_sicr &= ~0x00003F00;
+ immr->im_cpm.cp_sicr |= 0x00000a00;
+#endif /* 0 */
+
+
+ /*
+ * Initialize SDCR -- see section 16.9.23.7
+ * SDMA configuration register
+ */
+ immr->im_siu_conf.sc_sdcr = 0x01;
+
+
+ /*
+ * Setup SCC Ethernet Parameter RAM
+ */
+
+ pram_ptr->sen_genscc.scc_rfcr = 0x18; /* Normal Operation and Mot byte ordering */
+ pram_ptr->sen_genscc.scc_tfcr = 0x18; /* Mot byte ordering, Normal access */
+
+ pram_ptr->sen_genscc.scc_mrblr = DBUF_LENGTH; /* max. ET package len 1520 */
+
+ pram_ptr->sen_genscc.scc_rbase = (unsigned int) (&rtx->rxbd[0]); /* Set RXBD tbl start at Dual Port */
+ pram_ptr->sen_genscc.scc_tbase = (unsigned int) (&rtx->txbd[0]); /* Set TXBD tbl start at Dual Port */
+
+ /*
+ * Setup Receiver Buffer Descriptors (13.14.24.18)
+ * Settings:
+ * 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_bufaddr = (uint) NetRxPackets[i];
+ }
+
+ rtx->rxbd[PKTBUFSRX - 1].cbd_sc |= BD_ENET_RX_WRAP;
+
+ /*
+ * Setup Ethernet Transmitter Buffer Descriptors (13.14.24.19)
+ * Settings:
+ * Add PADs to Short FRAMES, Wrap, Last, Tx CRC
+ */
+
+ for (i = 0; i < TX_BUF_CNT; i++) {
+ rtx->txbd[i].cbd_sc =
+ (BD_ENET_TX_PAD | 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;
+
+ /*
+ * Enter Command: Initialize Rx Params for SCC
+ */
+
+ do { /* Spin until ready to issue command */
+ __asm__ ("eieio");
+ } while (immr->im_cpm.cp_cpcr & CPM_CR_FLG);
+ /* Issue command */
+ immr->im_cpm.cp_cpcr =
+ ((CPM_CR_INIT_RX << 8) | (cpm_cr[scc_index] << 4) |
+ CPM_CR_FLG);
+ do { /* Spin until command processed */
+ __asm__ ("eieio");
+ } while (immr->im_cpm.cp_cpcr & CPM_CR_FLG);
+
+ /*
+ * Ethernet Specific Parameter RAM
+ * see table 13-16, pg. 660,
+ * pg. 681 (example with suggested settings)
+ */
+
+ pram_ptr->sen_cpres = ~(0x0); /* Preset CRC */
+ pram_ptr->sen_cmask = 0xdebb20e3; /* Constant Mask for CRC */
+ pram_ptr->sen_crcec = 0x0; /* Error Counter CRC (unused) */
+ pram_ptr->sen_alec = 0x0; /* Alignment Error Counter (unused) */
+ pram_ptr->sen_disfc = 0x0; /* Discard Frame Counter (unused) */
+ pram_ptr->sen_pads = 0x8888; /* Short Frame PAD Characters */
+
+ pram_ptr->sen_retlim = 15; /* Retry Limit Threshold */
+ pram_ptr->sen_maxflr = 1518; /* MAX Frame Length Register */
+ pram_ptr->sen_minflr = 64; /* MIN Frame Length Register */
+
+ pram_ptr->sen_maxd1 = DBUF_LENGTH; /* MAX DMA1 Length Register */
+ pram_ptr->sen_maxd2 = DBUF_LENGTH; /* MAX DMA2 Length Register */
+
+ pram_ptr->sen_gaddr1 = 0x0; /* Group Address Filter 1 (unused) */
+ pram_ptr->sen_gaddr2 = 0x0; /* Group Address Filter 2 (unused) */
+ pram_ptr->sen_gaddr3 = 0x0; /* Group Address Filter 3 (unused) */
+ pram_ptr->sen_gaddr4 = 0x0; /* Group Address Filter 4 (unused) */
+
+#define ea bd->bi_enetaddr
+ pram_ptr->sen_paddrh = (ea[5] << 8) + ea[4];
+ pram_ptr->sen_paddrm = (ea[3] << 8) + ea[2];
+ pram_ptr->sen_paddrl = (ea[1] << 8) + ea[0];
+#undef ea
+
+ pram_ptr->sen_pper = 0x0; /* Persistence (unused) */
+ pram_ptr->sen_iaddr1 = 0x0; /* Individual Address Filter 1 (unused) */
+ pram_ptr->sen_iaddr2 = 0x0; /* Individual Address Filter 2 (unused) */
+ pram_ptr->sen_iaddr3 = 0x0; /* Individual Address Filter 3 (unused) */
+ pram_ptr->sen_iaddr4 = 0x0; /* Individual Address Filter 4 (unused) */
+ pram_ptr->sen_taddrh = 0x0; /* Tmp Address (MSB) (unused) */
+ pram_ptr->sen_taddrm = 0x0; /* Tmp Address (unused) */
+ pram_ptr->sen_taddrl = 0x0; /* Tmp Address (LSB) (unused) */
+
+ /*
+ * Enter Command: Initialize Tx Params for SCC
+ */
+
+ do { /* Spin until ready to issue command */
+ __asm__ ("eieio");
+ } while (immr->im_cpm.cp_cpcr & CPM_CR_FLG);
+ /* Issue command */
+ immr->im_cpm.cp_cpcr =
+ ((CPM_CR_INIT_TX << 8) | (cpm_cr[scc_index] << 4) |
+ CPM_CR_FLG);
+ do { /* Spin until command processed */
+ __asm__ ("eieio");
+ } while (immr->im_cpm.cp_cpcr & CPM_CR_FLG);
+
+ /*
+ * Mask all Events in SCCM - we use polling mode
+ */
+ immr->im_cpm.cp_scc[scc_index].scc_sccm = 0;
+
+ /*
+ * Clear Events in SCCE -- Clear bits by writing 1's
+ */
+
+ immr->im_cpm.cp_scc[scc_index].scc_scce = ~(0x0);
+
+
+ /*
+ * Initialize GSMR High 32-Bits
+ * Settings: Normal Mode
+ */
+
+ immr->im_cpm.cp_scc[scc_index].scc_gsmrh = 0;
+
+ /*
+ * Initialize GSMR Low 32-Bits, but do not Enable Transmit/Receive
+ * Settings:
+ * TCI = Invert
+ * TPL = 48 bits
+ * TPP = Repeating 10's
+ * LOOP = Loopback
+ * MODE = Ethernet
+ */
+
+ immr->im_cpm.cp_scc[scc_index].scc_gsmrl = (SCC_GSMRL_TCI |
+ SCC_GSMRL_TPL_48 |
+ SCC_GSMRL_TPP_10 |
+ SCC_GSMRL_DIAG_LOOP |
+ SCC_GSMRL_MODE_ENET);
+
+ /*
+ * Initialize the DSR -- see section 13.14.4 (pg. 513) v0.4
+ */
+
+ immr->im_cpm.cp_scc[scc_index].scc_dsr = 0xd555;
+
+ /*
+ * Initialize the PSMR
+ * Settings:
+ * CRC = 32-Bit CCITT
+ * NIB = Begin searching for SFD 22 bits after RENA
+ * LPB = Loopback Enable (Needed when FDE is set)
+ */
+ immr->im_cpm.cp_scc[scc_index].scc_psmr = SCC_PSMR_ENCRC |
+ SCC_PSMR_NIB22 | SCC_PSMR_LPB;
+
+#if 0
+ /*
+ * Configure Ethernet TENA Signal
+ */
+
+#if (defined(PC_ENET_TENA) && !defined(PB_ENET_TENA))
+ immr->im_ioport.iop_pcpar |= PC_ENET_TENA;
+ immr->im_ioport.iop_pcdir &= ~PC_ENET_TENA;
+#elif (defined(PB_ENET_TENA) && !defined(PC_ENET_TENA))
+ immr->im_cpm.cp_pbpar |= PB_ENET_TENA;
+ immr->im_cpm.cp_pbdir |= PB_ENET_TENA;
+#else
+#error Configuration Error: exactly ONE of PB_ENET_TENA, PC_ENET_TENA must be defined
+#endif
+
+#if defined(CONFIG_ADS) && defined(CONFIG_MPC860)
+ /*
+ * Port C is used to control the PHY,MC68160.
+ */
+ immr->im_ioport.iop_pcdir |=
+ (PC_ENET_ETHLOOP | PC_ENET_TPFLDL | PC_ENET_TPSQEL);
+
+ immr->im_ioport.iop_pcdat |= PC_ENET_TPFLDL;
+ immr->im_ioport.iop_pcdat &= ~(PC_ENET_ETHLOOP | PC_ENET_TPSQEL);
+ *((uint *) BCSR1) &= ~BCSR1_ETHEN;
+#endif /* MPC860ADS */
+
+#if defined(CONFIG_AMX860)
+ /*
+ * Port B is used to control the PHY,MC68160.
+ */
+ immr->im_cpm.cp_pbdir |=
+ (PB_ENET_ETHLOOP | PB_ENET_TPFLDL | PB_ENET_TPSQEL);
+
+ immr->im_cpm.cp_pbdat |= PB_ENET_TPFLDL;
+ immr->im_cpm.cp_pbdat &= ~(PB_ENET_ETHLOOP | PB_ENET_TPSQEL);
+
+ immr->im_ioport.iop_pddir |= PD_ENET_ETH_EN;
+ immr->im_ioport.iop_pddat &= ~PD_ENET_ETH_EN;
+#endif /* AMX860 */
+
+#endif /* 0 */
+
+#ifdef CONFIG_RPXCLASSIC
+ *((uchar *) BCSR0) &= ~BCSR0_ETHLPBK;
+ *((uchar *) BCSR0) |= (BCSR0_ETHEN | BCSR0_COLTEST | BCSR0_FULLDPLX);
+#endif
+
+#ifdef CONFIG_RPXLITE
+ *((uchar *) BCSR0) |= BCSR0_ETHEN;
+#endif
+
+#ifdef CONFIG_MBX
+ board_ether_init ();
+#endif
+
+ /*
+ * Set the ENT/ENR bits in the GSMR Low -- Enable Transmit/Receive
+ */
+
+ immr->im_cpm.cp_scc[scc_index].scc_gsmrl |=
+ (SCC_GSMRL_ENR | SCC_GSMRL_ENT);
+
+ /*
+ * Work around transmit problem with first eth packet
+ */
+#if defined (CONFIG_FADS)
+ udelay (10000); /* wait 10 ms */
+#elif defined (CONFIG_AMX860) || defined(CONFIG_RPXCLASSIC)
+ udelay (100000); /* wait 100 ms */
+#endif
+}
+
+static int scc_send (int index, volatile void *packet, int length)
+{
+ int i, j = 0;
+
+ while ((rtx->txbd[txIdx].cbd_sc & BD_ENET_TX_READY) && (j < TOUT_LOOP)) {
+ udelay (1); /* will also trigger Wd if needed */
+ j++;
+ }
+ if (j >= TOUT_LOOP)
+ printf ("TX not ready\n");
+ rtx->txbd[txIdx].cbd_bufaddr = (uint) packet;
+ rtx->txbd[txIdx].cbd_datlen = length;
+ rtx->txbd[txIdx].cbd_sc |=
+ (BD_ENET_TX_READY | BD_ENET_TX_LAST | BD_ENET_TX_WRAP);
+ while ((rtx->txbd[txIdx].cbd_sc & BD_ENET_TX_READY) && (j < TOUT_LOOP)) {
+ udelay (1); /* will also trigger Wd if needed */
+ j++;
+ }
+ if (j >= TOUT_LOOP)
+ printf ("TX timeout\n");
+ i = (rtx->txbd[txIdx].
+ cbd_sc & BD_ENET_TX_STATS) /* return only status bits */ ;
+ return i;
+}
+
+static int scc_recv (int index, void *packet, int max_length)
+{
+ int length = -1;
+
+ if (rtx->rxbd[rxIdx].cbd_sc & BD_ENET_RX_EMPTY) {
+ goto Done; /* nothing received */
+ }
+
+ if (!(rtx->rxbd[rxIdx].cbd_sc & 0x003f)) {
+ length = rtx->rxbd[rxIdx].cbd_datlen - 4;
+ memcpy (packet,
+ (void *) (NetRxPackets[rxIdx]),
+ length < max_length ? length : max_length);
+ }
+
+ /* Give the buffer back to the SCC. */
+ 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++;
+ }
+
+ Done:
+ return length;
+}
+
+ /*
+ * Test routines
+ */
+
+static void packet_fill (char *packet, int length)
+{
+ char c = (char) length;
+ int i;
+
+ packet[0] = 0xFF;
+ packet[1] = 0xFF;
+ packet[2] = 0xFF;
+ packet[3] = 0xFF;
+ packet[4] = 0xFF;
+ packet[5] = 0xFF;
+
+ for (i = 6; i < length; i++) {
+ packet[i] = c++;
+ }
+}
+
+static int packet_check (char *packet, int length)
+{
+ char c = (char) length;
+ int i;
+
+ for (i = 6; i < length; i++) {
+ if (packet[i] != c++)
+ return -1;
+ }
+
+ return 0;
+}
+
+static int test_ctlr (int ctlr, int index)
+{
+ int res = -1;
+ char packet_send[MAX_PACKET_LENGTH];
+ char packet_recv[MAX_PACKET_LENGTH];
+ int length;
+ int i;
+ int l;
+
+ ctlr_proc[ctlr].init (index);
+
+ for (i = 0; i < TEST_NUM; i++) {
+ for (l = MIN_PACKET_LENGTH; l <= MAX_PACKET_LENGTH; l++) {
+ packet_fill (packet_send, l);
+
+ ctlr_proc[ctlr].send (index, packet_send, l);
+
+ length = ctlr_proc[ctlr].recv (index, packet_recv,
+ MAX_PACKET_LENGTH);
+
+ if (length != l || packet_check (packet_recv, length) < 0) {
+ goto Done;
+ }
+ }
+ }
+
+ res = 0;
+
+ Done:
+
+#if !defined(CONFIG_8xx_CONS_NONE)
+ if (used_by_uart[ctlr] == index) {
+ serial_init ();
+ }
+#endif
+
+#if defined(SCC_ENET)
+ if (used_by_ether[ctlr] == index) {
+ DECLARE_GLOBAL_DATA_PTR;
+
+ eth_init (gd->bd);
+ }
+#endif
+
+ /*
+ * SCC2 Ethernet parameter RAM space overlaps
+ * the SPI parameter RAM space. So we need to restore
+ * the SPI configuration after SCC2 ethernet test.
+ */
+#if defined(CONFIG_SPI)
+ if (ctlr == CTLR_SCC && index == 1) {
+ spi_init_f ();
+ spi_init_r ();
+ }
+#endif
+
+ if (res != 0) {
+ post_log ("ethernet %s%d test failed\n", ctlr_name[ctlr],
+ index + 1);
+ }
+
+ return res;
+}
+
+int ether_post_test (int flags)
+{
+ int res = 0;
+ int i;
+
+#if defined(CONFIG_8xx_CONS_SCC1)
+ used_by_uart[CTLR_SCC] = 0;
+#elif defined(CONFIG_8xx_CONS_SCC2)
+ used_by_uart[CTLR_SCC] = 1;
+#elif defined(CONFIG_8xx_CONS_SCC3)
+ used_by_uart[CTLR_SCC] = 2;
+#elif defined(CONFIG_8xx_CONS_SCC4)
+ used_by_uart[CTLR_SCC] = 3;
+#endif
+
+#if defined(SCC_ENET)
+ used_by_ether[CTLR_SCC] = SCC_ENET;
+#endif
+
+ ctlr_proc[CTLR_SCC].init = scc_init;
+ ctlr_proc[CTLR_SCC].send = scc_send;
+ ctlr_proc[CTLR_SCC].recv = scc_recv;
+
+ for (i = 0; i < CTRL_LIST_SIZE; i++) {
+ if (test_ctlr (ctlr_list[i][0], ctlr_list[i][1]) != 0) {
+ res = -1;
+ }
+ }
+
+ return res;
+}
+
+#endif /* CONFIG_POST & CFG_POST_ETHER */
+
+#endif /* CONFIG_POST */
--- /dev/null
+/*
+ * (C) Copyright 2002
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+
+/* Memory test
+ *
+ * General observations:
+ * o The recommended test sequence is to test the data lines: if they are
+ * broken, nothing else will work properly. Then test the address
+ * lines. Finally, test the cells in the memory now that the test
+ * program knows that the address and data lines work properly.
+ * This sequence also helps isolate and identify what is faulty.
+ *
+ * o For the address line test, it is a good idea to use the base
+ * address of the lowest memory location, which causes a '1' bit to
+ * walk through a field of zeros on the address lines and the highest
+ * memory location, which causes a '0' bit to walk through a field of
+ * '1's on the address line.
+ *
+ * o Floating buses can fool memory tests if the test routine writes
+ * a value and then reads it back immediately. The problem is, the
+ * write will charge the residual capacitance on the data bus so the
+ * bus retains its state briefely. When the test program reads the
+ * value back immediately, the capacitance of the bus can allow it
+ * to read back what was written, even though the memory circuitry
+ * is broken. To avoid this, the test program should write a test
+ * pattern to the target location, write a different pattern elsewhere
+ * to charge the residual capacitance in a differnt manner, then read
+ * the target location back.
+ *
+ * o Always read the target location EXACTLY ONCE and save it in a local
+ * variable. The problem with reading the target location more than
+ * once is that the second and subsequent reads may work properly,
+ * resulting in a failed test that tells the poor technician that
+ * "Memory error at 00000000, wrote aaaaaaaa, read aaaaaaaa" which
+ * doesn't help him one bit and causes puzzled phone calls. Been there,
+ * done that.
+ *
+ * Data line test:
+ * ---------------
+ * This tests data lines for shorts and opens by forcing adjacent data
+ * to opposite states. Because the data lines could be routed in an
+ * arbitrary manner the must ensure test patterns ensure that every case
+ * is tested. By using the following series of binary patterns every
+ * combination of adjacent bits is test regardless of routing.
+ *
+ * ...101010101010101010101010
+ * ...110011001100110011001100
+ * ...111100001111000011110000
+ * ...111111110000000011111111
+ *
+ * Carrying this out, gives us six hex patterns as follows:
+ *
+ * 0xaaaaaaaaaaaaaaaa
+ * 0xcccccccccccccccc
+ * 0xf0f0f0f0f0f0f0f0
+ * 0xff00ff00ff00ff00
+ * 0xffff0000ffff0000
+ * 0xffffffff00000000
+ *
+ * To test for short and opens to other signals on our boards, we
+ * simply test with the 1's complemnt of the paterns as well, resulting
+ * in twelve patterns total.
+ *
+ * After writing a test pattern. a special pattern 0x0123456789ABCDEF is
+ * written to a different address in case the data lines are floating.
+ * Thus, if a byte lane fails, you will see part of the special
+ * pattern in that byte lane when the test runs. For example, if the
+ * xx__xxxxxxxxxxxx byte line fails, you will see aa23aaaaaaaaaaaa
+ * (for the 'a' test pattern).
+ *
+ * Address line test:
+ * ------------------
+ * This function performs a test to verify that all the address lines
+ * hooked up to the RAM work properly. If there is an address line
+ * fault, it usually shows up as two different locations in the address
+ * map (related by the faulty address line) mapping to one physical
+ * memory storage location. The artifact that shows up is writing to
+ * the first location "changes" the second location.
+ *
+ * To test all address lines, we start with the given base address and
+ * xor the address with a '1' bit to flip one address line. For each
+ * test, we shift the '1' bit left to test the next address line.
+ *
+ * In the actual code, we start with address sizeof(ulong) since our
+ * test pattern we use is a ulong and thus, if we tried to test lower
+ * order address bits, it wouldn't work because our pattern would
+ * overwrite itself.
+ *
+ * Example for a 4 bit address space with the base at 0000:
+ * 0000 <- base
+ * 0001 <- test 1
+ * 0010 <- test 2
+ * 0100 <- test 3
+ * 1000 <- test 4
+ * Example for a 4 bit address space with the base at 0010:
+ * 0010 <- base
+ * 0011 <- test 1
+ * 0000 <- (below the base address, skipped)
+ * 0110 <- test 2
+ * 1010 <- test 3
+ *
+ * The test locations are successively tested to make sure that they are
+ * not "mirrored" onto the base address due to a faulty address line.
+ * Note that the base and each test location are related by one address
+ * line flipped. Note that the base address need not be all zeros.
+ *
+ * Memory tests 1-4:
+ * -----------------
+ * These tests verify RAM using sequential writes and reads
+ * to/from RAM. There are several test cases that use different patterns to
+ * verify RAM. Each test case fills a region of RAM with one pattern and
+ * then reads the region back and compares its contents with the pattern.
+ * The following patterns are used:
+ *
+ * 1a) zero pattern (0x00000000)
+ * 1b) negative pattern (0xffffffff)
+ * 1c) checkerboard pattern (0x55555555)
+ * 1d) checkerboard pattern (0xaaaaaaaa)
+ * 2) bit-flip pattern ((1 << (offset % 32))
+ * 3) address pattern (offset)
+ * 4) address pattern (~offset)
+ *
+ * Being run in normal mode, the test verifies only small 4Kb
+ * regions of RAM around each 1Mb boundary. For example, for 64Mb
+ * RAM the following areas are verified: 0x00000000-0x00000800,
+ * 0x000ff800-0x00100800, 0x001ff800-0x00200800, ..., 0x03fff800-
+ * 0x04000000. If the test is run in power-fail mode, it verifies
+ * the whole RAM.
+ */
+
+#ifdef CONFIG_POST
+
+#include <post.h>
+#include <watchdog.h>
+
+#if CONFIG_POST & CFG_POST_MEMORY
+
+/*
+ * Define INJECT_*_ERRORS for testing error detection in the presence of
+ * _good_ hardware.
+ */
+#undef INJECT_DATA_ERRORS
+#undef INJECT_ADDRESS_ERRORS
+
+#ifdef INJECT_DATA_ERRORS
+#warning "Injecting data line errors for testing purposes"
+#endif
+
+#ifdef INJECT_ADDRESS_ERRORS
+#warning "Injecting address line errors for testing purposes"
+#endif
+
+
+/*
+ * This function performs a double word move from the data at
+ * the source pointer to the location at the destination pointer.
+ * This is helpful for testing memory on processors which have a 64 bit
+ * wide data bus.
+ *
+ * On those PowerPC with FPU, use assembly and a floating point move:
+ * this does a 64 bit move.
+ *
+ * For other processors, let the compiler generate the best code it can.
+ */
+static void move64(unsigned long long *src, unsigned long long *dest)
+{
+#if defined(CONFIG_MPC8260) || defined(CONFIG_MPC824X)
+ asm ("lfd 0, 0(3)\n\t" /* fpr0 = *scr */
+ "stfd 0, 0(4)" /* *dest = fpr0 */
+ : : : "fr0" ); /* Clobbers fr0 */
+ return;
+#else
+ *dest = *src;
+#endif
+}
+
+/*
+ * This is 64 bit wide test patterns. Note that they reside in ROM
+ * (which presumably works) and the tests write them to RAM which may
+ * not work.
+ *
+ * The "otherpattern" is written to drive the data bus to values other
+ * than the test pattern. This is for detecting floating bus lines.
+ *
+ */
+const static unsigned long long pattern[] = {
+ 0xaaaaaaaaaaaaaaaa,
+ 0xcccccccccccccccc,
+ 0xf0f0f0f0f0f0f0f0,
+ 0xff00ff00ff00ff00,
+ 0xffff0000ffff0000,
+ 0xffffffff00000000,
+ 0x00000000ffffffff,
+ 0x0000ffff0000ffff,
+ 0x00ff00ff00ff00ff,
+ 0x0f0f0f0f0f0f0f0f,
+ 0x3333333333333333,
+ 0x5555555555555555};
+const unsigned long long otherpattern = 0x0123456789abcdef;
+
+
+static int memory_post_dataline(unsigned long long * pmem)
+{
+ unsigned long long temp64;
+ int num_patterns = sizeof(pattern)/ sizeof(pattern[0]);
+ int i;
+ unsigned int hi, lo, pathi, patlo;
+ int ret = 0;
+
+ for ( i = 0; i < num_patterns; i++) {
+ move64((unsigned long long *)&(pattern[i]), pmem++);
+ /*
+ * Put a different pattern on the data lines: otherwise they
+ * may float long enough to read back what we wrote.
+ */
+ move64((unsigned long long *)&otherpattern, pmem--);
+ move64(pmem, &temp64);
+
+#ifdef INJECT_DATA_ERRORS
+ temp64 ^= 0x00008000;
+#endif
+
+ if (temp64 != pattern[i]){
+ pathi = (pattern[i]>>32) & 0xffffffff;
+ patlo = pattern[i] & 0xffffffff;
+
+ hi = (temp64>>32) & 0xffffffff;
+ lo = temp64 & 0xffffffff;
+
+ post_log ("Memory (date line) error at %08x, "
+ "wrote %08x%08x, read %08x%08x !\n",
+ pmem, pathi, patlo, hi, lo);
+ ret = -1;
+ }
+ }
+ return ret;
+}
+
+static int memory_post_addrline(ulong *testaddr, ulong *base, ulong size)
+{
+ ulong *target;
+ ulong *end;
+ ulong readback;
+ ulong xor;
+ int ret = 0;
+
+ end = base + size;
+ xor = 0;
+ for(xor = sizeof(ulong); xor > 0; xor <<= 1) {
+ target = (ulong *)((ulong)testaddr ^ xor);
+ if((target >= base) && (target < end)) {
+ *testaddr = ~*target;
+ readback = *target;
+
+#ifdef INJECT_ADDRESS_ERRORS
+ if(xor == 0x00008000) {
+ readback = *testaddr;
+ }
+#endif
+ if(readback == *testaddr) {
+ post_log ("Memory (address line) error at %08x<->%08x, "
+ "XOR value %08x !\n",
+ testaddr, target, xor);
+ ret = -1;
+ }
+ }
+ }
+ return ret;
+}
+
+static int memory_post_test1 (unsigned long start,
+ unsigned long size,
+ unsigned long val)
+{
+ unsigned long i;
+ ulong *mem = (ulong *) start;
+ ulong readback;
+ int ret = 0;
+
+ for (i = 0; i < size / sizeof (ulong); i++) {
+ mem[i] = val;
+ if (i % 1024 == 0)
+ WATCHDOG_RESET ();
+ }
+
+ for (i = 0; i < size / sizeof (ulong) && ret == 0; i++) {
+ readback = mem[i];
+ if (readback != val) {
+ post_log ("Memory error at %08x, "
+ "wrote %08x, read %08x !\n",
+ mem + i, val, readback);
+
+ ret = -1;
+ break;
+ }
+ if (i % 1024 == 0)
+ WATCHDOG_RESET ();
+ }
+
+ return ret;
+}
+
+static int memory_post_test2 (unsigned long start, unsigned long size)
+{
+ unsigned long i;
+ ulong *mem = (ulong *) start;
+ ulong readback;
+ int ret = 0;
+
+ for (i = 0; i < size / sizeof (ulong); i++) {
+ mem[i] = 1 << (i % 32);
+ if (i % 1024 == 0)
+ WATCHDOG_RESET ();
+ }
+
+ for (i = 0; i < size / sizeof (ulong) && ret == 0; i++) {
+ readback = mem[i];
+ if (readback != (1 << (i % 32))) {
+ post_log ("Memory error at %08x, "
+ "wrote %08x, read %08x !\n",
+ mem + i, 1 << (i % 32), readback);
+
+ ret = -1;
+ break;
+ }
+ if (i % 1024 == 0)
+ WATCHDOG_RESET ();
+ }
+
+ return ret;
+}
+
+static int memory_post_test3 (unsigned long start, unsigned long size)
+{
+ unsigned long i;
+ ulong *mem = (ulong *) start;
+ ulong readback;
+ int ret = 0;
+
+ for (i = 0; i < size / sizeof (ulong); i++) {
+ mem[i] = i;
+ if (i % 1024 == 0)
+ WATCHDOG_RESET ();
+ }
+
+ for (i = 0; i < size / sizeof (ulong) && ret == 0; i++) {
+ readback = mem[i];
+ if (readback != i) {
+ post_log ("Memory error at %08x, "
+ "wrote %08x, read %08x !\n",
+ mem + i, i, readback);
+
+ ret = -1;
+ break;
+ }
+ if (i % 1024 == 0)
+ WATCHDOG_RESET ();
+ }
+
+ return ret;
+}
+
+static int memory_post_test4 (unsigned long start, unsigned long size)
+{
+ unsigned long i;
+ ulong *mem = (ulong *) start;
+ ulong readback;
+ int ret = 0;
+
+ for (i = 0; i < size / sizeof (ulong); i++) {
+ mem[i] = ~i;
+ if (i % 1024 == 0)
+ WATCHDOG_RESET ();
+ }
+
+ for (i = 0; i < size / sizeof (ulong) && ret == 0; i++) {
+ readback = mem[i];
+ if (readback != ~i) {
+ post_log ("Memory error at %08x, "
+ "wrote %08x, read %08x !\n",
+ mem + i, ~i, readback);
+
+ ret = -1;
+ break;
+ }
+ if (i % 1024 == 0)
+ WATCHDOG_RESET ();
+ }
+
+ return ret;
+}
+
+static int memory_post_tests (unsigned long start, unsigned long size)
+{
+ int ret = 0;
+
+ if (ret == 0)
+ ret = memory_post_dataline ((long long *)start);
+ WATCHDOG_RESET ();
+ if (ret == 0)
+ ret = memory_post_addrline ((long *)start, (long *)start, size);
+ WATCHDOG_RESET ();
+ if (ret == 0)
+ ret = memory_post_addrline ((long *)(start + size - 8),
+ (long *)start, size);
+ WATCHDOG_RESET ();
+ if (ret == 0)
+ ret = memory_post_test1 (start, size, 0x00000000);
+ WATCHDOG_RESET ();
+ if (ret == 0)
+ ret = memory_post_test1 (start, size, 0xffffffff);
+ WATCHDOG_RESET ();
+ if (ret == 0)
+ ret = memory_post_test1 (start, size, 0x55555555);
+ WATCHDOG_RESET ();
+ if (ret == 0)
+ ret = memory_post_test1 (start, size, 0xaaaaaaaa);
+ WATCHDOG_RESET ();
+ if (ret == 0)
+ ret = memory_post_test2 (start, size);
+ WATCHDOG_RESET ();
+ if (ret == 0)
+ ret = memory_post_test3 (start, size);
+ WATCHDOG_RESET ();
+ if (ret == 0)
+ ret = memory_post_test4 (start, size);
+ WATCHDOG_RESET ();
+
+ return ret;
+}
+
+int memory_post_test (int flags)
+{
+ int ret = 0;
+ DECLARE_GLOBAL_DATA_PTR;
+ bd_t *bd = gd->bd;
+ unsigned long memsize = (bd->bi_memsize >= 256 << 20 ?
+ 256 << 20 : bd->bi_memsize) - (1 << 20);
+
+
+ if (flags & POST_POWERFAIL) {
+ ret = memory_post_tests (CFG_SDRAM_BASE, memsize);
+ } else { /* POST_POWERNORMAL */
+
+ unsigned long i;
+
+ for (i = 0; i < (memsize >> 20) && ret == 0; i++) {
+ if (ret == 0)
+ ret = memory_post_tests (i << 20, 0x800);
+ if (ret == 0)
+ ret = memory_post_tests ((i << 20) + 0xff800, 0x800);
+ }
+ }
+
+ return ret;
+}
+
+#endif /* CONFIG_POST & CFG_POST_MEMORY */
+#endif /* CONFIG_POST */
--- /dev/null
+/*
+ * (C) Copyright 2002
+ * ARIO Data Networks, Inc. dchiu@ariodata.com
+ *
+ * modified for DS1556:
+ * Frank Panno <fpanno@delphintech.com>, Delphin Technology AG
+ *
+ * Based on MontaVista DS1743 code and U-Boot mc146818 code
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/*
+ * Date & Time support for the DS1556 RTC
+ */
+
+/*#define RTC_DEBUG */
+
+#include <common.h>
+#include <command.h>
+#include <rtc.h>
+
+
+#if defined(CONFIG_RTC_DS1556) && (CONFIG_COMMANDS & CFG_CMD_DATE)
+
+static uchar rtc_read( unsigned int addr );
+static void rtc_write( unsigned int addr, uchar val);
+static uchar bin2bcd (unsigned int n);
+static unsigned bcd2bin(uchar c);
+
+#define RTC_BASE ( CFG_NVRAM_SIZE + CFG_NVRAM_BASE_ADDR )
+
+#define RTC_YEAR ( RTC_BASE + 0xf )
+#define RTC_MONTH ( RTC_BASE + 0xe )
+#define RTC_DAY_OF_MONTH ( RTC_BASE + 0xd )
+#define RTC_DAY_OF_WEEK ( RTC_BASE + 0xc )
+#define RTC_HOURS ( RTC_BASE + 0xb )
+#define RTC_MINUTES ( RTC_BASE + 0xa )
+#define RTC_SECONDS ( RTC_BASE + 0x9 )
+#define RTC_CENTURY ( RTC_BASE + 0x8 )
+
+#define RTC_CONTROLA RTC_CENTURY
+#define RTC_CONTROLB RTC_SECONDS
+#define RTC_CONTROLC RTC_BASE
+
+#define RTC_CA_WRITE 0x80
+#define RTC_CA_READ 0x40
+
+#define RTC_CB_OSC_DISABLE 0x80
+
+#define RTC_CC_BATTERY_FLAG 0x10
+#define RTC_CC_FREQ_TEST 0x40
+
+/* ------------------------------------------------------------------------- */
+
+void rtc_get( struct rtc_time *tmp )
+{
+ uchar sec, min, hour;
+ uchar mday, wday, mon, year;
+
+ int century;
+
+ uchar reg_a;
+
+ reg_a = rtc_read( RTC_CONTROLA );
+ /* lock clock registers for read */
+ rtc_write( RTC_CONTROLA, ( reg_a | RTC_CA_READ ));
+
+ sec = rtc_read( RTC_SECONDS );
+ min = rtc_read( RTC_MINUTES );
+ hour = rtc_read( RTC_HOURS );
+ mday = rtc_read( RTC_DAY_OF_MONTH );
+ wday = rtc_read( RTC_DAY_OF_WEEK );
+ mon = rtc_read( RTC_MONTH );
+ year = rtc_read( RTC_YEAR );
+ century = rtc_read( RTC_CENTURY );
+
+ /* unlock clock registers after read */
+ rtc_write( RTC_CONTROLA, ( reg_a & ~RTC_CA_READ ));
+
+#ifdef RTC_DEBUG
+ printf( "Get RTC year: %02x mon/cent: %02x mon: %02x mday: %02x wday: %02x "
+ "hr: %02x min: %02x sec: %02x\n",
+ year, century, mon, mday, wday,
+ hour, min, sec );
+#endif
+ tmp->tm_sec = bcd2bin( sec & 0x7F );
+ tmp->tm_min = bcd2bin( min & 0x7F );
+ tmp->tm_hour = bcd2bin( hour & 0x3F );
+ tmp->tm_mday = bcd2bin( mday & 0x3F );
+ tmp->tm_mon = bcd2bin( mon & 0x1F );
+ tmp->tm_wday = bcd2bin( wday & 0x07 );
+
+ /* glue year from century and year in century */
+ tmp->tm_year = bcd2bin( year ) +
+ ( bcd2bin( century & 0x3F ) * 100 );
+
+ tmp->tm_yday = 0;
+ tmp->tm_isdst= 0;
+#ifdef RTC_DEBUG
+ printf( "Get DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n",
+ tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+ tmp->tm_hour, tmp->tm_min, tmp->tm_sec );
+#endif
+}
+
+void rtc_set( struct rtc_time *tmp )
+{
+ uchar reg_a;
+#ifdef RTC_DEBUG
+ printf( "Set DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n",
+ tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+ tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+#endif
+ /* lock clock registers for write */
+ reg_a = rtc_read( RTC_CONTROLA );
+ rtc_write( RTC_CONTROLA, ( reg_a | RTC_CA_WRITE ));
+
+ rtc_write( RTC_MONTH, bin2bcd( tmp->tm_mon ));
+
+ rtc_write( RTC_DAY_OF_WEEK, bin2bcd( tmp->tm_wday ));
+ rtc_write( RTC_DAY_OF_MONTH, bin2bcd( tmp->tm_mday ));
+ rtc_write( RTC_HOURS, bin2bcd( tmp->tm_hour ));
+ rtc_write( RTC_MINUTES, bin2bcd( tmp->tm_min ));
+ rtc_write( RTC_SECONDS, bin2bcd( tmp->tm_sec ));
+
+ /* break year up into century and year in century */
+ rtc_write( RTC_YEAR, bin2bcd( tmp->tm_year % 100 ));
+ rtc_write( RTC_CENTURY, bin2bcd( tmp->tm_year / 100 ));
+
+ /* unlock clock registers after read */
+ rtc_write( RTC_CONTROLA, ( reg_a & ~RTC_CA_WRITE ));
+}
+
+void rtc_reset (void)
+{
+ uchar reg_a, reg_b, reg_c;
+
+ reg_a = rtc_read( RTC_CONTROLA );
+ reg_b = rtc_read( RTC_CONTROLB );
+
+ if ( reg_b & RTC_CB_OSC_DISABLE )
+ {
+ printf( "real-time-clock was stopped. Now starting...\n" );
+ reg_a |= RTC_CA_WRITE;
+ reg_b &= ~RTC_CB_OSC_DISABLE;
+
+ rtc_write( RTC_CONTROLA, reg_a );
+ rtc_write( RTC_CONTROLB, reg_b );
+ }
+
+ /* make sure read/write clock register bits are cleared */
+ reg_a &= ~( RTC_CA_WRITE | RTC_CA_READ );
+ rtc_write( RTC_CONTROLA, reg_a );
+
+ reg_c = rtc_read( RTC_CONTROLC );
+ if (( reg_c & RTC_CC_BATTERY_FLAG ) == 0 )
+ printf( "RTC battery low. Clock setting may not be reliable.\n" );
+}
+
+/* ------------------------------------------------------------------------- */
+
+static uchar rtc_read( unsigned int addr )
+{
+ uchar val = *(volatile unsigned char*)(addr);
+#ifdef RTC_DEBUG
+ printf( "rtc_read: %x:%x\n", addr, val );
+#endif
+ return( val );
+}
+
+static void rtc_write( unsigned int addr, uchar val )
+{
+#ifdef RTC_DEBUG
+ printf( "rtc_write: %x:%x\n", addr, val );
+#endif
+ *(volatile unsigned char*)(addr) = val;
+}
+
+static unsigned bcd2bin (uchar n)
+{
+ return ((((n >> 4) & 0x0F) * 10) + (n & 0x0F));
+}
+
+static unsigned char bin2bcd (unsigned int n)
+{
+ return (((n / 10) << 4) | (n % 10));
+}
+
+#endif /* CONFIG_RTC_DS1556 && CFG_CMD_DATE */