mirror of
https://source.denx.de/u-boot/u-boot.git
synced 2026-06-13 15:03:58 +03:00
Compare commits
16 Commits
U-Boot-0_4
...
LABEL_2003
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4f7cb08ee7 | ||
|
|
a43278a43d | ||
|
|
7205e4075d | ||
|
|
149dded2b1 | ||
|
|
7152b1d0b3 | ||
|
|
4d816774f1 | ||
|
|
093ae273da | ||
|
|
12f34241cb | ||
|
|
326428cc8b | ||
|
|
0cb61d7ddd | ||
|
|
6f21347d49 | ||
|
|
c29fdfc1d8 | ||
|
|
ca75added1 | ||
|
|
437ce07b8a | ||
|
|
fe389a82c9 | ||
|
|
d94f92cbd7 |
121
CHANGELOG
121
CHANGELOG
@@ -1,5 +1,116 @@
|
||||
======================================================================
|
||||
Changes for U-Boot 0.4.5:
|
||||
Changes for U-Boot 1.0.0:
|
||||
======================================================================
|
||||
|
||||
* Patch by Martin Krause, 11 Sep 2003:
|
||||
add burn-in tests for TRAB board
|
||||
|
||||
* Enable instruction cache on MPC5200 board
|
||||
|
||||
* Patch by Denis Peter, 11 Sep 2003:
|
||||
- fix USB data pointer assignment for bulk only transfer.
|
||||
- prevent to display erased directories in FAT filesystem.
|
||||
|
||||
* Change output format for NAND flash - make it look like for other
|
||||
memory, too
|
||||
|
||||
======================================================================
|
||||
Changes for U-Boot 0.4.8:
|
||||
======================================================================
|
||||
|
||||
* Patches by Denis Peter, 9 Sep 2003:
|
||||
add FAT support for IDE, SCSI and USB
|
||||
|
||||
* Patches by Gleb Natapov, 2 Sep 2003:
|
||||
- cleanup of POST code for unsupported architectures
|
||||
- MPC824x locks way0 of data cache for use as initial RAM;
|
||||
this patch unlocks it after relocation to RAM and invalidates
|
||||
the locked entries.
|
||||
|
||||
* Patch by Gleb Natapov, 30 Aug 2003:
|
||||
new I2C driver for mpc107 bridge. Now works from flash.
|
||||
|
||||
* Patch by Dave Ellis, 11 Aug 2003:
|
||||
- JFFS2: fix typo in common/cmd_jffs2.c
|
||||
- JFFS2: fix CFG_JFFS2_SORT_FRAGMENTS option
|
||||
- JFFS2: remove node version 0 warning
|
||||
- JFFS2: accept JFFS2 PADDING nodes
|
||||
- SXNI855T: add AM29LV800 support
|
||||
- SXNI855T: move environment from EEPROM to flash
|
||||
- SXNI855T: boot from JFFS2 in NOR or NAND flash
|
||||
|
||||
* Patch by Bill Hargen, 11 Aug 2003:
|
||||
fixes for I2C on MPC8240
|
||||
- fix i2c_write routine
|
||||
- fix iprobe command
|
||||
- eliminates use of global variables, plus dead code, cleanup.
|
||||
|
||||
* Add support for USB Mass Storage Devices (BBB)
|
||||
(tested with USB memory sticks only)
|
||||
|
||||
* Avoid flicker on TRAB's VFD
|
||||
|
||||
* Add support for SK98xx driver
|
||||
|
||||
* Add PCI support for SL8245 board
|
||||
|
||||
* Support IceCube board configurations with 1 x AMD AM29LV065 (8 MB)
|
||||
or 1 x AM29LV652 (two LV065 in one chip = 16 MB);
|
||||
Run IPB at 133 Mhz; adjust the MII clock frequency accordingly
|
||||
|
||||
* Set BRG_CLK on PM825/826 to 64MHz (VCO_OUT / 4, instead of 16 MHz)
|
||||
to allow for more accurate baudrate settings
|
||||
(error now 0.7% at 115 kbps, instead of 3.5% before)
|
||||
|
||||
* Patch by Andreas Mohr, 4 Sep 2003:
|
||||
Fix a lot of spelling errors
|
||||
|
||||
* Add support for PPChameleon Eval Board
|
||||
|
||||
* Add support for P3G4 board
|
||||
|
||||
* Fix problem with MGT5100 FEC driver: add "early" MAC address
|
||||
initialization
|
||||
|
||||
* Patch by Yuli Barcohen, 7 Aug 2003:
|
||||
check BCSR to detect if the board is configured in PCI mode
|
||||
|
||||
======================================================================
|
||||
Changes for U-Boot 0.4.7:
|
||||
======================================================================
|
||||
|
||||
* Patch by Raghu Krishnaprasad, 7 Aug 2003:
|
||||
add support for Adder II MPC852T module
|
||||
|
||||
* Patch by George G. Davis, 19 Aug 2003:
|
||||
fix TI Innovator/OMAP1510 pin configs
|
||||
|
||||
* Patches by Kshitij, 18 Aug 2003
|
||||
- add support for arm926ejs cpu core
|
||||
- add support for TI OMAP 1610 Innovator Board
|
||||
|
||||
* Patch by Yuli Barcohen, 14 Aug 2003:
|
||||
add support for bzip2 uncompression
|
||||
|
||||
* Add GCC library to examples/Makefile so GCC utility functions will
|
||||
be resolved, too
|
||||
|
||||
* Add I2C and RTC support for RMU board using software I2C driver
|
||||
(because of better response to iprobe command); fix problem with
|
||||
"reset" command
|
||||
|
||||
* Patch by Matthias Fuchs, 28 Aug 2003:
|
||||
Added CONFIG_BOOTP_DNS2 and CONFIG_BOOTP_SEND_HOSTNAME to
|
||||
CONFIG_BOOTP_MAKS (see README).
|
||||
|
||||
* Fix ICU862 environment problem
|
||||
|
||||
* Fix RAM size detection for RMU board
|
||||
|
||||
* Implement "reset" for MGT5100/MPC5200 systems
|
||||
|
||||
======================================================================
|
||||
Changes for U-Boot 0.4.6:
|
||||
======================================================================
|
||||
|
||||
* Make Ethernet autonegotiation on INCA-IP work for all clock rates;
|
||||
@@ -14,6 +125,10 @@ Changes for U-Boot 0.4.5:
|
||||
* Patch by Richard Woodruff, 8 Aug 2003:
|
||||
Allow crc32 to be used at address 0x000 (crc32_no_comp, too).
|
||||
|
||||
======================================================================
|
||||
Changes for U-Boot 0.4.5:
|
||||
======================================================================
|
||||
|
||||
* Update for TQM board defaults:
|
||||
disable clocks_in_mhz, enable boot count limit
|
||||
|
||||
@@ -92,7 +207,7 @@ Changes for U-Boot 0.4.5:
|
||||
add delay to get I2C working with "imm" command and s3c24x0_i2c.c
|
||||
|
||||
* Patch by Richard Woodruff, 17 July 03:
|
||||
- Fixed bug in OMAP1510 baud rate divisor settings.
|
||||
- Fixed bug in OMAP1510 baud rate divisor settings.
|
||||
|
||||
* Patch by Nye Liu, 16 July 2003:
|
||||
MPC860FADS fixes:
|
||||
@@ -200,7 +315,7 @@ Changes for U-Boot 0.4.1:
|
||||
- PIC on LWMON board needs delay after power-on
|
||||
- Add missing RSR definitions for MPC8xx
|
||||
- Improve log buffer handling: guarantee clean reset after power-on
|
||||
- Add support for EXBITGEN board
|
||||
- Add support for EXBITGEN board (aka "genie")
|
||||
- Add support for SL8245 board
|
||||
|
||||
* Code cleanup:
|
||||
|
||||
6
CREDITS
6
CREDITS
@@ -302,3 +302,9 @@ W: www.elinos.com
|
||||
N: Pantelis Antoniou
|
||||
E: panto@intracom.gr
|
||||
D: NETVIA board support, ARTOS support.
|
||||
|
||||
N: Raghu Krishnaprasad
|
||||
E: Raghu.Krishnaprasad@fci.com
|
||||
D: Support for Adder-II MPC852T evaluation board
|
||||
W: http://www.forcecomputers.com
|
||||
|
||||
|
||||
@@ -89,9 +89,12 @@ Wolfgang Denk <wd@denx.de>
|
||||
TQM8255 MPC8255
|
||||
|
||||
CPU86 MPC8260
|
||||
PM825 MPC8250
|
||||
PM826 MPC8260
|
||||
TQM8260 MPC8260
|
||||
|
||||
P3G4 MPC7410
|
||||
|
||||
PCIPPC2 MPC750
|
||||
PCIPPC6 MPC750
|
||||
|
||||
@@ -105,6 +108,10 @@ Dave Ellis <DGE@sixnetio.com>
|
||||
|
||||
SXNI855T MPC8xx
|
||||
|
||||
Raghu Krishnaprasad <raghu.krishnaprasad@fci.com>
|
||||
|
||||
ADDERII MPC852T
|
||||
|
||||
Thomas Frieden <ThomasF@hyperion-entertainment.com>
|
||||
|
||||
AmigaOneG3SE MPC7xx
|
||||
@@ -278,6 +285,7 @@ Gary Jennejohn <gj@denx.de>
|
||||
|
||||
Kshitij Gupta <kshitij@ti.com>
|
||||
omap1510inn ARM925T
|
||||
omap1610inn ARM926EJS
|
||||
|
||||
David Müller <d.mueller@elsoft.ch>
|
||||
|
||||
|
||||
40
MAKEALL
40
MAKEALL
@@ -31,20 +31,21 @@ LIST_5xxx=" \
|
||||
#########################################################################
|
||||
|
||||
LIST_8xx=" \
|
||||
ADS860 AMX860 c2mon CCM \
|
||||
cogent_mpc8xx ESTEEM192E ETX094 ELPT860 \
|
||||
FADS823 FADS850SAR FADS860T FLAGADM \
|
||||
FPS850L GEN860T GEN860T_SC GENIETV \
|
||||
GTH hermes IAD210 ICU862_100MHz \
|
||||
IP860 IVML24 IVML24_128 IVML24_256 \
|
||||
IVMS8 IVMS8_128 IVMS8_256 KUP4K \
|
||||
LANTEC lwmon MBX MBX860T \
|
||||
MHPC MPC86xADS MVS1 NETVIA \
|
||||
NETVIA_V2 NX823 pcu_e R360MPI \
|
||||
RBC823 rmu RPXClassic RPXlite \
|
||||
RRvision SM850 SPD823TS svm_sc8xx \
|
||||
SXNI855T TOP860 TQM823L TQM823L_LCD \
|
||||
TQM850L TQM855L TQM860L v37 \
|
||||
AdderII ADS860 AMX860 c2mon \
|
||||
CCM cogent_mpc8xx ESTEEM192E ETX094 \
|
||||
ELPT860 FADS823 FADS850SAR FADS860T \
|
||||
FLAGADM FPS850L GEN860T GEN860T_SC \
|
||||
GENIETV GTH hermes IAD210 \
|
||||
ICU862_100MHz IP860 IVML24 IVML24_128 \
|
||||
IVML24_256 IVMS8 IVMS8_128 IVMS8_256 \
|
||||
KUP4K LANTEC lwmon MBX \
|
||||
MBX860T MHPC MPC86xADS MVS1 \
|
||||
NETVIA NETVIA_V2 NX823 pcu_e \
|
||||
R360MPI RBC823 rmu RPXClassic \
|
||||
RPXlite RRvision SM850 SPD823TS \
|
||||
svm_sc8xx SXNI855T TOP860 TQM823L \
|
||||
TQM823L_LCD TQM850L TQM855L TQM860L \
|
||||
v37 \
|
||||
"
|
||||
|
||||
#########################################################################
|
||||
@@ -58,7 +59,7 @@ LIST_4xx=" \
|
||||
DU405 EBONY ERIC EXBITGEN \
|
||||
MIP405 MIP405T ML2 OCRTC \
|
||||
ORSG PCI405 PIP405 PMC405 \
|
||||
W7OLMC W7OLMG WALNUT405 \
|
||||
PPChameleonEVB W7OLMC W7OLMG WALNUT405 \
|
||||
"
|
||||
|
||||
#########################################################################
|
||||
@@ -88,7 +89,8 @@ LIST_8260=" \
|
||||
#########################################################################
|
||||
|
||||
LIST_74xx=" \
|
||||
EVB64260 PCIPPC2 PCIPPC6 ZUMA \
|
||||
EVB64260 P3G4 PCIPPC2 PCIPPC6 \
|
||||
ZUMA \
|
||||
"
|
||||
|
||||
LIST_7xx=" \
|
||||
@@ -117,7 +119,11 @@ LIST_ARM7="ep7312 impa7"
|
||||
## ARM9 Systems
|
||||
#########################################################################
|
||||
|
||||
LIST_ARM9="at91rm9200dk omap1510inn smdk2400 smdk2410 trab VCMA9"
|
||||
LIST_ARM9=" \
|
||||
at91rm9200dk omap1510inn omap1610inn \
|
||||
smdk2400 smdk2410 trab \
|
||||
VCMA9 \
|
||||
"
|
||||
|
||||
#########################################################################
|
||||
## Xscale Systems
|
||||
|
||||
18
Makefile
18
Makefile
@@ -87,6 +87,7 @@ SUBDIRS = tools \
|
||||
rtc \
|
||||
dtt \
|
||||
drivers \
|
||||
drivers/sk98lin \
|
||||
post \
|
||||
post/cpu \
|
||||
examples
|
||||
@@ -112,9 +113,12 @@ LIBS += disk/libdisk.a
|
||||
LIBS += rtc/librtc.a
|
||||
LIBS += dtt/libdtt.a
|
||||
LIBS += drivers/libdrivers.a
|
||||
LIBS += drivers/sk98lin/libsk98lin.a
|
||||
LIBS += post/libpost.a post/cpu/libcpu.a
|
||||
LIBS += common/libcommon.a
|
||||
LIBS += lib_generic/libgeneric.a
|
||||
# Add GCC lib
|
||||
PLATFORM_LIBS += -L $(shell dirname `$(CC) -print-libgcc-file-name`) -lgcc
|
||||
|
||||
#########################################################################
|
||||
#########################################################################
|
||||
@@ -142,7 +146,7 @@ u-boot.dis: u-boot
|
||||
u-boot: depend subdirs $(OBJS) $(LIBS) $(LDSCRIPT)
|
||||
UNDEF_SYM=`$(OBJDUMP) -x $(LIBS) |sed -n -e 's/.*\(__u_boot_cmd_.*\)/-u\1/p'|sort|uniq`;\
|
||||
$(LD) $(LDFLAGS) $$UNDEF_SYM $(OBJS) \
|
||||
--start-group $(LIBS) --end-group \
|
||||
--start-group $(LIBS) $(PLATFORM_LIBS) --end-group \
|
||||
-Map u-boot.map -o u-boot
|
||||
|
||||
subdirs:
|
||||
@@ -210,6 +214,9 @@ IceCube_5100_config: unconfig
|
||||
## MPC8xx Systems
|
||||
#########################################################################
|
||||
|
||||
AdderII_config: unconfig
|
||||
@./mkconfig $(@:_config=) ppc mpc8xx adderII
|
||||
|
||||
ADS860_config: unconfig
|
||||
@./mkconfig $(@:_config=) ppc mpc8xx fads
|
||||
|
||||
@@ -536,6 +543,9 @@ PIP405_config:unconfig
|
||||
PMC405_config: unconfig
|
||||
@./mkconfig $(@:_config=) ppc ppc4xx pmc405 esd
|
||||
|
||||
PPChameleonEVB_config: unconfig
|
||||
@./mkconfig $(@:_config=) ppc ppc4xx PPChameleonEVB dave
|
||||
|
||||
W7OLMC_config \
|
||||
W7OLMG_config: unconfig
|
||||
@./mkconfig $(@:_config=) ppc ppc4xx w7o
|
||||
@@ -748,6 +758,9 @@ BAB7xx_config: unconfig
|
||||
ELPPC_config: unconfig
|
||||
@./mkconfig $(@:_config=) ppc 74xx_7xx elppc eltec
|
||||
|
||||
P3G4_config: unconfig
|
||||
@./mkconfig $(@:_config=) ppc 74xx_7xx evb64260
|
||||
|
||||
#========================================================================
|
||||
# ARM
|
||||
#========================================================================
|
||||
@@ -776,6 +789,9 @@ xtract_trab = $(subst _big_flash,,$(subst _config,,$1))
|
||||
omap1510inn_config : unconfig
|
||||
@./mkconfig $(@:_config=) arm arm925t omap1510inn
|
||||
|
||||
omap1610inn_config : unconfig
|
||||
@./mkconfig $(@:_config=) arm arm926ejs omap1610inn
|
||||
|
||||
smdk2400_config : unconfig
|
||||
@./mkconfig $(@:_config=) arm arm920t smdk2400
|
||||
|
||||
|
||||
103
README
103
README
@@ -119,12 +119,12 @@ U-Boot will always have a patchlevel of "0".
|
||||
Directory Hierarchy:
|
||||
====================
|
||||
|
||||
- board Board dependend files
|
||||
- common Misc architecture independend functions
|
||||
- board Board dependent files
|
||||
- common Misc architecture independent functions
|
||||
- cpu CPU specific files
|
||||
- disk Code for disk drive partition handling
|
||||
- doc Documentation (don't expect too much)
|
||||
- drivers Common used device drivers
|
||||
- drivers Commonly used device drivers
|
||||
- dtt Digital Thermometer and Thermostat drivers
|
||||
- examples Example code for standalone applications, etc.
|
||||
- include Header Files
|
||||
@@ -141,6 +141,7 @@ Directory Hierarchy:
|
||||
|
||||
- cpu/74xx_7xx Files specific to Motorola MPC74xx and 7xx CPUs
|
||||
- cpu/arm925t Files specific to ARM 925 CPUs
|
||||
- cpu/arm926ejs Files specific to ARM 926 CPUs
|
||||
- cpu/mpc5xx Files specific to Motorola MPC5xx CPUs
|
||||
- cpu/mpc8xx Files specific to Motorola MPC8xx CPUs
|
||||
- cpu/mpc824x Files specific to Motorola MPC824x CPUs
|
||||
@@ -208,6 +209,8 @@ Directory Hierarchy:
|
||||
- board/oxc Files specific to OXC boards
|
||||
- board/omap1510inn
|
||||
Files specific to OMAP 1510 Innovator boards
|
||||
- board/omap1610inn
|
||||
Files specific to OMAP 1610 Innovator boards
|
||||
- board/pcippc2 Files specific to PCIPPC2/PCIPPC6 boards
|
||||
- board/pm826 Files specific to PM826 boards
|
||||
- board/ppmc8260
|
||||
@@ -303,6 +306,7 @@ The following options need to be configured:
|
||||
or CONFIG_MPC824X, CONFIG_MPC8260
|
||||
or CONFIG_IOP480
|
||||
or CONFIG_405GP
|
||||
or CONFIG_405EP
|
||||
or CONFIG_440
|
||||
or CONFIG_MPC74xx
|
||||
or CONFIG_750FX
|
||||
@@ -357,7 +361,7 @@ The following options need to be configured:
|
||||
|
||||
CONFIG_HHP_CRADLE, CONFIG_DNP1110, CONFIG_EP7312,
|
||||
CONFIG_IMPA7, CONFIG_LART, CONFIG_LUBBOCK,
|
||||
CONFIG_INNOVATOROMAP1510,
|
||||
CONFIG_INNOVATOROMAP1510, CONFIG_INNOVATOROMAP1610
|
||||
CONFIG_SHANNON, CONFIG_SMDK2400, CONFIG_SMDK2410,
|
||||
CONFIG_TRAB, CONFIG_AT91RM9200DK
|
||||
|
||||
@@ -640,7 +644,7 @@ The following options need to be configured:
|
||||
- Watchdog:
|
||||
CONFIG_WATCHDOG
|
||||
If this variable is defined, it enables watchdog
|
||||
support. There must support in the platform specific
|
||||
support. There must be 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.
|
||||
@@ -848,7 +852,7 @@ The following options need to be configured:
|
||||
Normally display is black on white background; define
|
||||
CFG_WHITE_ON_BLACK to get it inverted.
|
||||
|
||||
- Spash Screen Support: CONFIG_SPLASH_SCREEN
|
||||
- Splash Screen Support: CONFIG_SPLASH_SCREEN
|
||||
|
||||
If this option is set, the environment is checked for
|
||||
a variable "splashimage". If found, the usual display
|
||||
@@ -859,6 +863,16 @@ The following options need to be configured:
|
||||
allows for a "silent" boot where a splash screen is
|
||||
loaded very quickly after power-on.
|
||||
|
||||
- Compression support:
|
||||
CONFIG_BZIP2
|
||||
|
||||
If this option is set, support for bzip2 compressed
|
||||
images is included. If not, only uncompressed and gzip
|
||||
compressed images are supported.
|
||||
|
||||
NOTE: the bzip2 algorithm requires a lot of RAM, so
|
||||
the malloc area (as defined by CFG_MALLOC_LEN) should
|
||||
be at least 4MB.
|
||||
|
||||
- Ethernet address:
|
||||
CONFIG_ETHADDR
|
||||
@@ -901,6 +915,29 @@ The following options need to be configured:
|
||||
4th and following
|
||||
BOOTP requests: delay 0 ... 8 sec
|
||||
|
||||
- DHCP Advanced Options:
|
||||
CONFIG_BOOTP_MASK
|
||||
|
||||
You can fine tune the DHCP functionality by adding
|
||||
these flags to the CONFIG_BOOTP_MASK define:
|
||||
|
||||
CONFIG_BOOTP_DNS2 - If a DHCP client requests the DNS
|
||||
serverip from a DHCP server, it is possible that more
|
||||
than one DNS serverip is offered to the client.
|
||||
If CONFIG_BOOTP_DNS2 is enabled, the secondary DNS
|
||||
serverip will be stored in the additional environment
|
||||
variable "dnsip2". The first DNS serverip is always
|
||||
stored in the variable "dnsip", when CONFIG_BOOTP_DNS
|
||||
is added to the CONFIG_BOOTP_MASK.
|
||||
|
||||
CONFIG_BOOTP_SEND_HOSTNAME - Some DHCP servers are capable
|
||||
to do a dynamic update of a DNS server. To do this, they
|
||||
need the hostname of the DHCP requester.
|
||||
If CONFIG_BOOP_SEND_HOSTNAME is added to the
|
||||
CONFIG_BOOTP_MASK, the content of the "hostname"
|
||||
environment variable is passed as option 12 to
|
||||
the DHCP server.
|
||||
|
||||
- Status LED: CONFIG_STATUS_LED
|
||||
|
||||
Several configurations allow to display the current
|
||||
@@ -1166,7 +1203,7 @@ The following options need to be configured:
|
||||
|
||||
U-Boot considers the values of the environment
|
||||
variables "serial#" (Board Serial Number) and
|
||||
"ethaddr" (Ethernet Address) to bb parameters that
|
||||
"ethaddr" (Ethernet Address) to be 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,
|
||||
@@ -1281,7 +1318,7 @@ The following options need to be configured:
|
||||
|
||||
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.
|
||||
the default environment compiled into the boot image.
|
||||
|
||||
For example, place something like this in your
|
||||
board's config file:
|
||||
@@ -1294,7 +1331,7 @@ The following options need to be configured:
|
||||
internal format how the environment is stored by the
|
||||
U-Boot code. This is NOT an official, exported
|
||||
interface! Although it is unlikely that this format
|
||||
will change soon, but there is no guarantee either.
|
||||
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
|
||||
@@ -1732,7 +1769,7 @@ Low Level (hardware related) configuration options:
|
||||
|
||||
- CFG_INIT_RAM_ADDR:
|
||||
|
||||
Start address of memory area tha can be used for
|
||||
Start address of memory area that 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
|
||||
@@ -1872,7 +1909,7 @@ configurations; the following names are supported:
|
||||
GEN860T_config EBONY_config FPS860L_config
|
||||
ELPT860_config cmi_mpc5xx_config NETVIA_config
|
||||
at91rm9200dk_config omap1510inn_config MPC8260ADS_config
|
||||
|
||||
omap1610inn_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
|
||||
@@ -1904,7 +1941,7 @@ Note: for some board special configuration names may exist; check if
|
||||
|
||||
|
||||
Finally, type "make all", and you should get some working U-Boot
|
||||
images ready for downlod to / installation on your system:
|
||||
images ready for download to / installation on your system:
|
||||
|
||||
- "u-boot.bin" is a raw binary image
|
||||
- "u-boot" is an image in ELF binary format
|
||||
@@ -1923,7 +1960,7 @@ steps:
|
||||
1. Add a new configuration option for your board to the toplevel
|
||||
"Makefile" and to the "MAKEALL" script, using the existing
|
||||
entries as examples. Note that here and at many other places
|
||||
boards and other names are listed alphabetically sorted. Please
|
||||
boards and other names are listed in alphabetical sort order. Please
|
||||
keep this order.
|
||||
2. Create a new directory to hold your board specific code. Add any
|
||||
files you need. In your board directory, you will need at least
|
||||
@@ -1953,7 +1990,7 @@ 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'
|
||||
select which (cross) compiler to use by 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
|
||||
|
||||
@@ -2080,10 +2117,10 @@ Some configuration options can be set using Environment Variables:
|
||||
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,
|
||||
RAM, and want to reserve 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
|
||||
sure that the initrd image is placed in the first
|
||||
12 MB as well - this can be done with
|
||||
|
||||
setenv initrd_high 00c00000
|
||||
@@ -2118,6 +2155,7 @@ depending the information provided by your boot server:
|
||||
|
||||
bootfile - see above
|
||||
dnsip - IP address of your Domain Name Server
|
||||
dnsip2 - IP address of your secondary Domain Name Server
|
||||
gatewayip - IP address of the Gateway (Router) to use
|
||||
hostname - Target hostname
|
||||
ipaddr - see above
|
||||
@@ -2151,8 +2189,8 @@ only effect after the next boot (yes, that's just like Windoze :-).
|
||||
Command Line Parsing:
|
||||
=====================
|
||||
|
||||
There are two different command line parsers available with U-Boot:
|
||||
the old "simple" one, and the much more pwerful "hush" shell:
|
||||
There are two different command line parsers available with U-Boot:
|
||||
the old "simple" one, and the much more powerful "hush" shell:
|
||||
|
||||
Old, simple command line parser:
|
||||
--------------------------------
|
||||
@@ -2193,9 +2231,9 @@ General rules:
|
||||
Note for Redundant Ethernet Interfaces:
|
||||
=======================================
|
||||
|
||||
Some boards come with redundand ethernet interfaces; U-Boot supports
|
||||
Some boards come with redundant ethernet interfaces; U-Boot supports
|
||||
such configurations and is capable of automatic selection of a
|
||||
"working" interface when needed. MAC assignemnt works as follows:
|
||||
"working" interface when needed. MAC assignment works as follows:
|
||||
|
||||
Network interfaces are numbered eth0, eth1, eth2, ... Corresponding
|
||||
MAC addresses can be stored in the environment as "ethaddr" (=>eth0),
|
||||
@@ -2239,8 +2277,7 @@ defines the following image properties:
|
||||
* 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).
|
||||
* Compression Type (uncompressed, gzip, bzip2)
|
||||
* Load Address
|
||||
* Entry Point
|
||||
* Image Name
|
||||
@@ -2255,21 +2292,21 @@ Linux Support:
|
||||
==============
|
||||
|
||||
Although U-Boot should support any OS or standalone application
|
||||
easily, Linux has always been in the focus during the design of
|
||||
easily, the main focus has always been on Linux 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:
|
||||
serves several 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
|
||||
lots of low-level, hardware dependent 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
|
||||
@@ -2521,7 +2558,7 @@ parameters. You can check and modify this variable using the
|
||||
...
|
||||
|
||||
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
|
||||
the memory addresses of both the kernel and the initrd image (PPBCOOT
|
||||
format!) to the "bootm" command:
|
||||
|
||||
=> imi 40100000 40200000
|
||||
@@ -2701,7 +2738,7 @@ Hit 'q':
|
||||
Minicom warning:
|
||||
================
|
||||
|
||||
Over time, many people have reported problems when trying to used the
|
||||
Over time, many people have reported problems when trying to use the
|
||||
"minicom" terminal emulation program for serial download. I (wd)
|
||||
consider minicom to be broken, and recommend not to use it. Under
|
||||
Unix, I recommend to use C-Kermit for general purpose use (and
|
||||
@@ -2769,7 +2806,7 @@ 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.
|
||||
|
||||
Chris Hallinan posted a good summy of these issues to the
|
||||
Chris Hallinan posted a good summary of these issues to the
|
||||
u-boot-users mailing list:
|
||||
|
||||
Subject: RE: [U-Boot-Users] RE: More On Memory Bank x (nothingness)?
|
||||
@@ -2815,9 +2852,9 @@ code for the initialization procedures:
|
||||
|
||||
* 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).
|
||||
zation is performed later (when relocating to RAM).
|
||||
|
||||
* Stack space is very limited. Avoid big data buffers or things like
|
||||
* 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
|
||||
@@ -2830,7 +2867,7 @@ 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
|
||||
When choosing a register for such a purpose we are restricted by the
|
||||
relevant (E)ABI specifications for the current architecture, and by
|
||||
GCC's implementation.
|
||||
|
||||
@@ -2920,7 +2957,7 @@ 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 re-map memory U-Boot then jumps to its 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
|
||||
@@ -2936,7 +2973,7 @@ 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
|
||||
different size, the largest 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.
|
||||
|
||||
40
board/adderII/Makefile
Normal file
40
board/adderII/Makefile
Normal file
@@ -0,0 +1,40 @@
|
||||
#
|
||||
# (C) Copyright 2000-2003
|
||||
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
#
|
||||
# See file CREDITS for list of people who contributed to this
|
||||
# project.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License as
|
||||
# published by the Free Software Foundation; either version 2 of
|
||||
# the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
# MA 02111-1307 USA
|
||||
#
|
||||
|
||||
include $(TOPDIR)/config.mk
|
||||
|
||||
LIB = lib$(BOARD).a
|
||||
|
||||
OBJS = $(BOARD).o flash.o
|
||||
|
||||
$(LIB): .depend $(OBJS)
|
||||
$(AR) crv $@ $(OBJS)
|
||||
|
||||
#########################################################################
|
||||
|
||||
.depend: Makefile $(SOBJS:.o=.S) $(OBJS:.o=.c)
|
||||
$(CC) -M $(CFLAGS) $(SOBJS:.o=.S) $(OBJS:.o=.c) > $@
|
||||
|
||||
sinclude .depend
|
||||
|
||||
#########################################################################
|
||||
189
board/adderII/adderII.c
Normal file
189
board/adderII/adderII.c
Normal file
@@ -0,0 +1,189 @@
|
||||
/*
|
||||
* (C) Copyright 2000-2003
|
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <config.h>
|
||||
#include <mpc8xx.h>
|
||||
|
||||
/*
|
||||
* Check Board Identity:
|
||||
*/
|
||||
|
||||
int checkboard( void )
|
||||
{
|
||||
puts("Board: ");
|
||||
puts("AdderII(MPC852T)\n" );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if defined( CONFIG_SDRAM_50MHZ )
|
||||
|
||||
/******************************************************************************
|
||||
** for chip Samsung K4S643232F - T70
|
||||
** this table is for 32-50MHz operation
|
||||
*******************************************************************************/
|
||||
|
||||
#define SDRAM_MPTPRVALUE 0x0200
|
||||
|
||||
#define SDRAM_MAMRVALUE0 0x00802114 /* refresh at 32MHz */
|
||||
#define SDRAM_MAMRVALUE1 0x00802118
|
||||
|
||||
#define SDRAM_OR1VALUE 0xff800e00
|
||||
#define SDRAM_BR1VALUE 0x00000081
|
||||
|
||||
#define SDRAM_MARVALUE 94
|
||||
|
||||
#define SDRAM_MCRVALUE0 0x80808105
|
||||
#define SDRAM_MCRVALUE1 0x80808130
|
||||
|
||||
const uint sdram_table[] = {
|
||||
|
||||
/* single read (offset 0x00 in upm ram) */
|
||||
0x1f07fc24, 0xe0aefc04, 0x10adfc04, 0xe0bbbc00,
|
||||
0x10f77c44, 0xf3fffc07, 0xfffffc04, 0xfffffc04,
|
||||
|
||||
/* burst read (offset 0x08 in upm ram) */
|
||||
0x1f07fc24, 0xe0aefc04, 0x10adfc04, 0xf0affc00,
|
||||
0xf0affc00, 0xf0affc00, 0xf0affc00, 0x10a77c44,
|
||||
0xf7bffc47, 0xfffffc35, 0xfffffc34, 0xfffffc35,
|
||||
0xfffffc35, 0x1ff77c35, 0xfffffc34, 0x1fb57c35,
|
||||
|
||||
/* single write (offset 0x18 in upm ram) */
|
||||
0x1f27fc24, 0xe0aebc04, 0x00b93c00, 0x13f77c47,
|
||||
0xfffdfc04, 0xfffffc04, 0xfffffc04, 0xfffffc04,
|
||||
|
||||
/* burst write (offset 0x20 in upm ram) */
|
||||
0x1f07fc24, 0xeeaebc00, 0x10ad7c00, 0xf0affc00,
|
||||
0xf0affc00, 0xe0abbc00, 0x1fb77c47, 0xfffffc04,
|
||||
0xfffffc04, 0xfffffc04, 0xfffffc04, 0xfffffc04,
|
||||
0xfffffc04, 0xfffffc04, 0xfffffc04, 0xfffffc04,
|
||||
|
||||
/* refresh (offset 0x30 in upm ram) */
|
||||
0x1ff5fca4, 0xfffffc04, 0xfffffc04, 0xfffffc04,
|
||||
0xfffffc84, 0xfffffc07, 0xfffffc04, 0xfffffc04,
|
||||
0xfffffc04, 0xfffffc04, 0xfffffc04, 0xfffffc04,
|
||||
|
||||
/* exception (offset 0x3C in upm ram) */
|
||||
0xfffffc27, 0xfffffc04, 0xfffffc04, 0xfffffc04,
|
||||
};
|
||||
|
||||
#else
|
||||
#error SDRAM not correctly configured
|
||||
#endif
|
||||
|
||||
int _initsdram (uint base, uint noMbytes)
|
||||
{
|
||||
volatile immap_t *immap = (immap_t *) CFG_IMMR;
|
||||
volatile memctl8xx_t *memctl = &immap->im_memctl;
|
||||
|
||||
if (noMbytes != 8) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
upmconfig (UPMA, (uint *) sdram_table,
|
||||
sizeof (sdram_table) / sizeof (uint));
|
||||
|
||||
memctl->memc_mptpr = SDRAM_MPTPRVALUE;
|
||||
|
||||
/* Configure the refresh (mostly). This needs to be
|
||||
* based upon processor clock speed and optimized to provide
|
||||
* the highest level of performance. For multiple banks,
|
||||
* this time has to be divided by the number of banks.
|
||||
* Although it is not clear anywhere, it appears the
|
||||
* refresh steps through the chip selects for this UPM
|
||||
* on each refresh cycle.
|
||||
* We have to be careful changing
|
||||
* UPM registers after we ask it to run these commands.
|
||||
*/
|
||||
|
||||
memctl->memc_mamr = (SDRAM_MAMRVALUE0 | (SDRAM_MARVALUE << 24));
|
||||
memctl->memc_mar = 0x0;
|
||||
udelay (200);
|
||||
|
||||
/* Now run the precharge/nop/mrs commands.
|
||||
*/
|
||||
memctl->memc_mcr = 0x80002115;
|
||||
udelay (200);
|
||||
|
||||
/* Run 8 refresh cycles */
|
||||
memctl->memc_mcr = 0x80002380;
|
||||
udelay (200);
|
||||
|
||||
memctl->memc_mar = 0x88;
|
||||
udelay (200);
|
||||
|
||||
memctl->memc_mcr = 0x80002116;
|
||||
udelay (200);
|
||||
|
||||
memctl->memc_or1 = SDRAM_OR1VALUE;
|
||||
memctl->memc_br1 = SDRAM_BR1VALUE | base;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void _sdramdisable( void )
|
||||
{
|
||||
volatile immap_t *immap = (immap_t *)CFG_IMMR;
|
||||
volatile memctl8xx_t *memctl = &immap->im_memctl;
|
||||
|
||||
memctl->memc_br1 = 0x00000000;
|
||||
|
||||
/* maybe we should turn off upma here or something */
|
||||
}
|
||||
|
||||
int initsdram (uint base, uint * noMbytes)
|
||||
{
|
||||
uint m = 8;
|
||||
|
||||
*noMbytes = m;
|
||||
|
||||
if (!_initsdram (base, m)) {
|
||||
return 0;
|
||||
} else {
|
||||
_sdramdisable ();
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
long int initdram (int board_type)
|
||||
{
|
||||
/* AdderII: has 8MB SDRAM */
|
||||
uint sdramsz;
|
||||
uint m = 0;
|
||||
|
||||
if (!initsdram (0x00000000, &sdramsz)) {
|
||||
m += sdramsz;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
return (m << 20);
|
||||
}
|
||||
|
||||
int testdram (void)
|
||||
{
|
||||
/* TODO: XXX XXX XXX not an actual SDRAM test */
|
||||
printf ("Test: 8MB SDRAM\n");
|
||||
|
||||
return (0);
|
||||
}
|
||||
45
board/adderII/adderII.h
Normal file
45
board/adderII/adderII.h
Normal file
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* (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
|
||||
*/
|
||||
|
||||
/****************************************************************************
|
||||
* FLASH Memory Map as used by FADS Monitor:
|
||||
*
|
||||
* Start Address Length
|
||||
* +-----------------------+ 0xFE00_0000 Start of Flash -----------------
|
||||
* | MON8xx code | 0xFE00_0100 Reset Vector
|
||||
* +-----------------------+ 0xFE0?_????
|
||||
* | (unused) |
|
||||
* +-----------------------+
|
||||
* | |
|
||||
* +-----------------------+
|
||||
* | |
|
||||
* +-----------------------+
|
||||
* | |
|
||||
* +-----------------------+
|
||||
* | |
|
||||
* +=======================+
|
||||
* | |
|
||||
* | ... |
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
29
board/adderII/config.mk
Normal file
29
board/adderII/config.mk
Normal file
@@ -0,0 +1,29 @@
|
||||
#
|
||||
# (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
|
||||
#
|
||||
|
||||
#
|
||||
# AdderII board ( Analogue-Micro )
|
||||
#
|
||||
|
||||
TEXT_BASE = 0xFE000000
|
||||
|
||||
501
board/adderII/flash.c
Normal file
501
board/adderII/flash.c
Normal file
@@ -0,0 +1,501 @@
|
||||
/*
|
||||
* (C) Copyright 2000-2003
|
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
/******************************************************************************
|
||||
** Notes: AM29LV320DB - 90EI ( 32 Mbit device )
|
||||
** Sectors - Eight 8 Kb sector
|
||||
** - Sixty three 64 Kb sector
|
||||
** Bottom boot sector
|
||||
******************************************************************************/
|
||||
#include <common.h>
|
||||
#include <mpc8xx.h>
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
** Defines
|
||||
******************************************************************************/
|
||||
#ifdef CONFIG_ADDERII
|
||||
|
||||
#define ADDR0 0x0555
|
||||
#define ADDR1 0x02AA
|
||||
#define FLASH_WORD_SIZE unsigned short
|
||||
|
||||
#endif
|
||||
|
||||
#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
|
||||
|
||||
/******************************************************************************
|
||||
** Global Parameters
|
||||
******************************************************************************/
|
||||
flash_info_t flash_info[CFG_MAX_FLASH_BANKS];
|
||||
|
||||
/******************************************************************************
|
||||
** Function Prototypes
|
||||
******************************************************************************/
|
||||
static ulong flash_get_size( vu_long *addr, flash_info_t *info );
|
||||
|
||||
static int write_word( flash_info_t *info, ulong dest, ulong data );
|
||||
|
||||
static void flash_get_offsets( ulong base, flash_info_t *info );
|
||||
|
||||
int wait_for_DQ7( flash_info_t *info, int sect );
|
||||
|
||||
/******************************************************************************
|
||||
** Function : flash_init
|
||||
** Param : void
|
||||
** Notes : Initializes the Flash Chip
|
||||
******************************************************************************/
|
||||
ulong flash_init (void)
|
||||
{
|
||||
ulong size_b0 = -1;
|
||||
int i;
|
||||
volatile immap_t *immap = (immap_t *) CFG_IMMR;
|
||||
volatile memctl8xx_t *memctl = &immap->im_memctl;
|
||||
|
||||
/* Set Flash to unknown */
|
||||
for (i = 0; i < CFG_MAX_FLASH_BANKS; i++) {
|
||||
flash_info[i].flash_id = FLASH_UNKNOWN;
|
||||
}
|
||||
|
||||
/* Get the Flash Bank Size */
|
||||
|
||||
size_b0 = flash_get_size ((vu_long *) (CFG_FLASH_BASE),
|
||||
&flash_info[0]);
|
||||
|
||||
if (flash_info[0].flash_id == FLASH_UNKNOWN) {
|
||||
printf ("## UNKNOWN Flash on Bank 0 - Size = 0x%08lx = %ldMB\n",
|
||||
size_b0, size_b0 >> 20);
|
||||
}
|
||||
|
||||
/* Remap Flash according to size detected */
|
||||
memctl->memc_or0 = 0xFF800774;
|
||||
memctl->memc_br0 = CFG_BR0_PRELIM;
|
||||
|
||||
/* Setup Flash Sector Offsets */
|
||||
|
||||
flash_get_offsets (CFG_FLASH_BASE, &flash_info[0]);
|
||||
|
||||
/* Monitor Protection ON - default */
|
||||
|
||||
#if ( CFG_MONITOR_BASE >= CFG_FLASH_BASE )
|
||||
flash_protect (FLAG_PROTECT_SET, CFG_MONITOR_BASE,
|
||||
(CFG_MONITOR_BASE + monitor_flash_len - 1),
|
||||
&flash_info[0]);
|
||||
#endif
|
||||
|
||||
/* Protect Environment Variables */
|
||||
#ifdef CFG_ENV_IS_IN_FLASH
|
||||
flash_protect (FLAG_PROTECT_SET, CFG_ENV_ADDR,
|
||||
(CFG_ENV_ADDR + CFG_ENV_SIZE - 1), &flash_info[0]);
|
||||
#endif
|
||||
|
||||
return size_b0;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
** Function : flash_get_offsets
|
||||
** Param : ulong base, flash_into_t *info
|
||||
** Notes :
|
||||
******************************************************************************/
|
||||
static void flash_get_offsets (ulong base, flash_info_t * info)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
** Function : flash_print_info
|
||||
** Param : flash_info_t
|
||||
** Notes :
|
||||
******************************************************************************/
|
||||
void flash_print_info (flash_info_t * info)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (info->flash_id == FLASH_UNKNOWN) {
|
||||
printf ("Missing or unknown flash type\n");
|
||||
return;
|
||||
}
|
||||
|
||||
switch (info->flash_id & FLASH_VENDMASK) {
|
||||
case FLASH_MAN_AMD:
|
||||
printf ("AMD ");
|
||||
break;
|
||||
case FLASH_MAN_FUJ:
|
||||
printf ("FUJITSU ");
|
||||
break;
|
||||
case FLASH_MAN_BM:
|
||||
printf ("BRIGHT MICRO ");
|
||||
break;
|
||||
default:
|
||||
printf ("Unknown Vendor ");
|
||||
break;
|
||||
}
|
||||
|
||||
switch (info->flash_id & FLASH_TYPEMASK) {
|
||||
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;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
** Function : flash_get_size
|
||||
** Param : vu_long *addr, flash_info_t *info
|
||||
** Notes :
|
||||
******************************************************************************/
|
||||
static ulong flash_get_size (vu_long * addr, flash_info_t * info)
|
||||
{
|
||||
short i;
|
||||
FLASH_WORD_SIZE manu_id, dev_id;
|
||||
ulong base = (ulong) addr;
|
||||
volatile FLASH_WORD_SIZE *addr2 = (FLASH_WORD_SIZE *) addr;
|
||||
|
||||
/* Write Auto Select Command and read Manufacturer's ID and Dev ID */
|
||||
|
||||
addr2[ADDR0] = (FLASH_WORD_SIZE) 0xAAAAAAAA;
|
||||
addr2[ADDR1] = (FLASH_WORD_SIZE) 0x55555555;
|
||||
addr2[ADDR0] = (FLASH_WORD_SIZE) 0x90909090;
|
||||
|
||||
manu_id = addr2[0];
|
||||
|
||||
switch (manu_id) {
|
||||
case (FLASH_WORD_SIZE) AMD_MANUFACT:
|
||||
info->flash_id = FLASH_MAN_AMD;
|
||||
break;
|
||||
|
||||
default:
|
||||
info->flash_id = FLASH_UNKNOWN;
|
||||
info->sector_count = 0;
|
||||
info->size = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Read Device Id */
|
||||
dev_id = addr2[1];
|
||||
|
||||
switch (dev_id) {
|
||||
case (FLASH_WORD_SIZE) AMD_ID_LV320B:
|
||||
info->flash_id += FLASH_AM320B;
|
||||
info->sector_count = 71; /* 8 - boot sec + 63 normal */
|
||||
info->size = 0x400000; /* 4MByte */
|
||||
break;
|
||||
|
||||
default:
|
||||
info->flash_id = FLASH_UNKNOWN;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Set up sector start Addresses */
|
||||
|
||||
if (info->flash_id & FLASH_BTYPE) {
|
||||
/* set sector offsets for bottom boot block
|
||||
** Eight 8 Kb Boot sectors
|
||||
** Sixty Three 64Kb sectors
|
||||
*/
|
||||
for (i = 0; i < 8; i++) {
|
||||
info->start[i] = base + (i * 0x00002000);
|
||||
}
|
||||
for (i = 8; i < info->sector_count; i++) {
|
||||
info->start[i] = base + (i * 0x00010000) - 0x00070000;
|
||||
}
|
||||
}
|
||||
|
||||
/* Reset To read mode */
|
||||
|
||||
if (info->flash_id != FLASH_UNKNOWN) {
|
||||
addr = (ulong *) info->start[0];
|
||||
*addr = 0xF0F0F0F0;
|
||||
}
|
||||
return (info->size);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
** Function : flash_erase
|
||||
** Param : flash_info_t *info, int s_first, int s_last
|
||||
** Notes :
|
||||
******************************************************************************/
|
||||
int flash_erase (flash_info_t * info, int s_first, int s_last)
|
||||
{
|
||||
volatile FLASH_WORD_SIZE *addr = (FLASH_WORD_SIZE *) (info->start[0]);
|
||||
volatile FLASH_WORD_SIZE *addr2;
|
||||
int flag, prot, sect, l_sect;
|
||||
int i;
|
||||
|
||||
if ((s_first < 0) || (s_first > s_last)) {
|
||||
if (info->flash_id == FLASH_UNKNOWN) {
|
||||
printf ("- missing\n");
|
||||
} else {
|
||||
printf ("- no sectors to erase\n");
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (info->flash_id == FLASH_UNKNOWN) {
|
||||
printf ("Can't erase unknown flash type - aborted\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
prot = 0;
|
||||
for (sect = s_first; sect <= s_last; ++sect) {
|
||||
if (info->protect[sect]) {
|
||||
prot++;
|
||||
}
|
||||
}
|
||||
|
||||
if (prot) {
|
||||
printf ("Warning: %d protected sectors will not be erased!\n",
|
||||
prot);
|
||||
} else {
|
||||
printf ("\n");
|
||||
}
|
||||
|
||||
l_sect = -1;
|
||||
|
||||
/* Disable interrupts which might cause a timeout here */
|
||||
flag = disable_interrupts ();
|
||||
|
||||
/* Start erase on unprotected sectors */
|
||||
for (sect = s_first; sect <= s_last; sect++) {
|
||||
|
||||
if (info->protect[sect] == 0) { /* not protected */
|
||||
addr2 = (FLASH_WORD_SIZE *) (info->start[sect]);
|
||||
|
||||
if ((info->flash_id & FLASH_VENDMASK) ==
|
||||
FLASH_MAN_SST) {
|
||||
addr[ADDR0] = (FLASH_WORD_SIZE) 0x00AA00AA;
|
||||
addr[ADDR1] = (FLASH_WORD_SIZE) 0x00550055;
|
||||
addr[ADDR0] = (FLASH_WORD_SIZE) 0x00800080;
|
||||
addr[ADDR0] = (FLASH_WORD_SIZE) 0x00AA00AA;
|
||||
addr[ADDR1] = (FLASH_WORD_SIZE) 0x00550055;
|
||||
addr2[0] = (FLASH_WORD_SIZE) 0x00500050; /* block erase */
|
||||
for (i = 0; i < 50; i++)
|
||||
udelay (1000); /* wait 1 ms */
|
||||
} else {
|
||||
addr[ADDR0] = (FLASH_WORD_SIZE) 0x00AA00AA;
|
||||
addr[ADDR1] = (FLASH_WORD_SIZE) 0x00550055;
|
||||
addr[ADDR0] = (FLASH_WORD_SIZE) 0x00800080;
|
||||
addr[ADDR0] = (FLASH_WORD_SIZE) 0x00AA00AA;
|
||||
addr[ADDR1] = (FLASH_WORD_SIZE) 0x00550055;
|
||||
addr2[0] = (FLASH_WORD_SIZE) 0x00300030; /* sector erase */
|
||||
}
|
||||
l_sect = sect;
|
||||
/*
|
||||
* Wait for each sector to complete, it's more
|
||||
* reliable. According to AMD Spec, you must
|
||||
* issue all erase commands within a specified
|
||||
* timeout. This has been seen to fail, especially
|
||||
* if printf()s are included (for debug)!!
|
||||
*/
|
||||
wait_for_DQ7 (info, sect);
|
||||
}
|
||||
}
|
||||
/* re-enable interrupts if necessary */
|
||||
if (flag)
|
||||
enable_interrupts ();
|
||||
|
||||
/* wait at least 80us - let's wait 1 ms */
|
||||
udelay (1000);
|
||||
|
||||
/* reset to read mode */
|
||||
addr = (FLASH_WORD_SIZE *) info->start[0];
|
||||
addr[0] = (FLASH_WORD_SIZE) 0x00F000F0; /* reset bank */
|
||||
|
||||
printf (" done\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int wait_for_DQ7 (flash_info_t * info, int sect)
|
||||
{
|
||||
ulong start, now, last;
|
||||
volatile FLASH_WORD_SIZE *addr =
|
||||
(FLASH_WORD_SIZE *) (info->start[sect]);
|
||||
|
||||
start = get_timer (0);
|
||||
last = start;
|
||||
while ((addr[0] & (FLASH_WORD_SIZE) 0x00800080) !=
|
||||
(FLASH_WORD_SIZE) 0x00800080) {
|
||||
if ((now = get_timer (start)) > CFG_FLASH_ERASE_TOUT) {
|
||||
printf ("Timeout\n");
|
||||
return -1;
|
||||
}
|
||||
/* show that we're waiting */
|
||||
if ((now - last) > 1000) {
|
||||
putc ('.');
|
||||
last = now;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
** Function : write_buff
|
||||
** Param : flash_info_t *info, uchar *src, ulong addr, ulong cnt
|
||||
** Notes :
|
||||
******************************************************************************/
|
||||
int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt)
|
||||
{
|
||||
ulong cp, wp, data;
|
||||
int i, l, rc;
|
||||
|
||||
/* get lower word aligned address */
|
||||
wp = (addr & ~3);
|
||||
|
||||
/*
|
||||
* 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));
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
** Function : write_word
|
||||
** Param : flash_info_t *info, ulong dest, ulong data
|
||||
** Notes :
|
||||
******************************************************************************/
|
||||
static int write_word (flash_info_t * info, ulong dest, ulong data)
|
||||
{
|
||||
volatile FLASH_WORD_SIZE *addr2 =
|
||||
(FLASH_WORD_SIZE *) (info->start[0]);
|
||||
volatile FLASH_WORD_SIZE *dest2 = (FLASH_WORD_SIZE *) dest;
|
||||
volatile FLASH_WORD_SIZE *data2 = (FLASH_WORD_SIZE *) & data;
|
||||
ulong start;
|
||||
int i;
|
||||
|
||||
/* Check if Flash is (sufficiently) erased */
|
||||
if ((*((volatile FLASH_WORD_SIZE *) dest) &
|
||||
(FLASH_WORD_SIZE) data) != (FLASH_WORD_SIZE) data) {
|
||||
return (2);
|
||||
}
|
||||
|
||||
for (i = 0; i < 4 / sizeof (FLASH_WORD_SIZE); i++) {
|
||||
int flag;
|
||||
|
||||
/* Disable interrupts which might cause a timeout here */
|
||||
flag = disable_interrupts ();
|
||||
|
||||
addr2[ADDR0] = (FLASH_WORD_SIZE) 0x00AA00AA;
|
||||
addr2[ADDR1] = (FLASH_WORD_SIZE) 0x00550055;
|
||||
addr2[ADDR0] = (FLASH_WORD_SIZE) 0x00A000A0;
|
||||
|
||||
dest2[i] = data2[i];
|
||||
|
||||
/* re-enable interrupts if necessary */
|
||||
if (flag)
|
||||
enable_interrupts ();
|
||||
|
||||
/* data polling for D7 */
|
||||
start = get_timer (0);
|
||||
while ((dest2[i] & (FLASH_WORD_SIZE) 0x00800080) !=
|
||||
(data2[i] & (FLASH_WORD_SIZE) 0x00800080)) {
|
||||
if (get_timer (start) > CFG_FLASH_WRITE_TOUT) {
|
||||
return (1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
147
board/adderII/u-boot.lds
Normal file
147
board/adderII/u-boot.lds
Normal file
@@ -0,0 +1,147 @@
|
||||
/*
|
||||
* (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)
|
||||
/*
|
||||
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)
|
||||
*(.rodata.str1.4)
|
||||
}
|
||||
.fini : { *(.fini) } =0
|
||||
.ctors : { *(.ctors) }
|
||||
.dtors : { *(.dtors) }
|
||||
|
||||
/* Read-write section, merged into data segment: */
|
||||
. = (. + 0x0FFF) & 0xFFFFF000;
|
||||
_erotext = .;
|
||||
PROVIDE (erotext = .);
|
||||
.reloc :
|
||||
{
|
||||
*(.got)
|
||||
_GOT2_TABLE_ = .;
|
||||
*(.got2)
|
||||
_FIXUP_TABLE_ = .;
|
||||
*(.fixup)
|
||||
}
|
||||
__got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2;
|
||||
__fixup_entries = (. - _FIXUP_TABLE_)>>2;
|
||||
|
||||
.data :
|
||||
{
|
||||
*(.data)
|
||||
*(.data1)
|
||||
*(.sdata)
|
||||
*(.sdata2)
|
||||
*(.dynamic)
|
||||
CONSTRUCTORS
|
||||
}
|
||||
_edata = .;
|
||||
PROVIDE (edata = .);
|
||||
|
||||
__u_boot_cmd_start = .;
|
||||
.u_boot_cmd : { *(.u_boot_cmd) }
|
||||
__u_boot_cmd_end = .;
|
||||
|
||||
|
||||
__start___ex_table = .;
|
||||
__ex_table : { *(__ex_table) }
|
||||
__stop___ex_table = .;
|
||||
|
||||
. = ALIGN(256);
|
||||
__init_begin = .;
|
||||
.text.init : { *(.text.init) }
|
||||
.data.init : { *(.data.init) }
|
||||
. = ALIGN(256);
|
||||
__init_end = .;
|
||||
|
||||
__bss_start = .;
|
||||
.bss :
|
||||
{
|
||||
*(.sbss) *(.scommon)
|
||||
*(.dynbss)
|
||||
*(.bss)
|
||||
*(COMMON)
|
||||
}
|
||||
. = ALIGN(256 * 1024);
|
||||
.ppcenv :
|
||||
{
|
||||
common/environment.o (.ppcenv)
|
||||
}
|
||||
_end = . ;
|
||||
PROVIDE (end = .);
|
||||
}
|
||||
|
||||
@@ -66,7 +66,7 @@ int dram_init (void)
|
||||
* The NAND lives in the CS2* space
|
||||
*/
|
||||
#if (CONFIG_COMMANDS & CFG_CMD_NAND)
|
||||
extern void nand_probe (ulong physadr);
|
||||
extern ulong nand_probe (ulong physadr);
|
||||
|
||||
#define AT91_SMARTMEDIA_BASE 0x40000000 /* physical address to access memory on NCS3 */
|
||||
void nand_init (void)
|
||||
@@ -103,10 +103,12 @@ void nand_init (void)
|
||||
*AT91C_PIOB_ODR = AT91C_PIO_PB1; /* disable output */
|
||||
|
||||
if (*AT91C_PIOB_PDSR & AT91C_PIO_PB1)
|
||||
printf ("No ");
|
||||
printf ("SmartMedia card inserted\n");
|
||||
printf (" No SmartMedia card inserted\n");
|
||||
#ifdef DEBUG
|
||||
printf (" SmartMedia card inserted\n");
|
||||
|
||||
printf ("Probing at 0x%.8x\n", AT91_SMARTMEDIA_BASE);
|
||||
nand_probe (AT91_SMARTMEDIA_BASE);
|
||||
#endif
|
||||
printf ("%4lu MB\n", nand_probe(AT91_SMARTMEDIA_BASE) >> 20);
|
||||
}
|
||||
#endif
|
||||
|
||||
46
board/dave/PPChameleonEVB/Makefile
Normal file
46
board/dave/PPChameleonEVB/Makefile
Normal file
@@ -0,0 +1,46 @@
|
||||
#
|
||||
# (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): $(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
|
||||
|
||||
#########################################################################
|
||||
274
board/dave/PPChameleonEVB/PPChameleonEVB.c
Normal file
274
board/dave/PPChameleonEVB/PPChameleonEVB.c
Normal file
@@ -0,0 +1,274 @@
|
||||
/*
|
||||
* (C) Copyright 2001-2003
|
||||
* Stefan Roese, esd gmbh germany, stefan.roese@esd-electronics.com
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <asm/processor.h>
|
||||
#include <command.h>
|
||||
#include <malloc.h>
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
#if 0
|
||||
#define FPGA_DEBUG
|
||||
#endif
|
||||
|
||||
/* fpga configuration data - gzip compressed and generated by bin2c */
|
||||
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)
|
||||
{
|
||||
out32(GPIO0_OR, CFG_NAND0_CE); /* set initial outputs */
|
||||
out32(GPIO0_OR, CFG_NAND1_CE); /* set initial outputs */
|
||||
|
||||
/*
|
||||
* IRQ 0-15 405GP internally generated; active high; level sensitive
|
||||
* IRQ 16 405GP internally generated; active low; level sensitive
|
||||
* IRQ 17-24 RESERVED
|
||||
* IRQ 25 (EXT IRQ 0) CAN0; active low; level sensitive
|
||||
* IRQ 26 (EXT IRQ 1) SER0 ; active low; level sensitive
|
||||
* IRQ 27 (EXT IRQ 2) SER1; active low; level sensitive
|
||||
* IRQ 28 (EXT IRQ 3) FPGA 0; active low; level sensitive
|
||||
* IRQ 29 (EXT IRQ 4) FPGA 1; active low; level sensitive
|
||||
* IRQ 30 (EXT IRQ 5) PCI INTA; active low; level sensitive
|
||||
* IRQ 31 (EXT IRQ 6) COMPACT FLASH; active high; level sensitive
|
||||
*/
|
||||
mtdcr(uicsr, 0xFFFFFFFF); /* clear all ints */
|
||||
mtdcr(uicer, 0x00000000); /* disable all ints */
|
||||
mtdcr(uiccr, 0x00000000); /* set all to be non-critical*/
|
||||
mtdcr(uicpr, 0xFFFFFF81); /* set int polarities */
|
||||
mtdcr(uictr, 0x10000000); /* set int trigger levels */
|
||||
mtdcr(uicvcr, 0x00000001); /* set vect base=0,INT0 highest priority*/
|
||||
mtdcr(uicsr, 0xFFFFFFFF); /* clear all ints */
|
||||
|
||||
/*
|
||||
* EBC Configuration Register: set ready timeout to 512 ebc-clks -> ca. 15 us
|
||||
*/
|
||||
#if 1 /* test-only */
|
||||
mtebc (epcr, 0xa8400000); /* ebc always driven */
|
||||
#else
|
||||
mtebc (epcr, 0x28400000); /* ebc in high-z */
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
int misc_init_f (void)
|
||||
{
|
||||
return 0; /* dummy implementation */
|
||||
}
|
||||
|
||||
|
||||
int misc_init_r (void)
|
||||
{
|
||||
#if 0 /* test-only */
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
#if 0
|
||||
volatile unsigned short *fpga_mode =
|
||||
(unsigned short *)((ulong)CFG_FPGA_BASE_ADDR + CFG_FPGA_CTRL);
|
||||
volatile unsigned char *duart0_mcr =
|
||||
(unsigned char *)((ulong)DUART0_BA + 4);
|
||||
volatile unsigned char *duart1_mcr =
|
||||
(unsigned char *)((ulong)DUART1_BA + 4);
|
||||
|
||||
bd_t *bd = gd->bd;
|
||||
char * tmp; /* Temporary char pointer */
|
||||
unsigned char *dst;
|
||||
ulong len = sizeof(fpgadata);
|
||||
int status;
|
||||
int index;
|
||||
int i;
|
||||
unsigned long cntrl0Reg;
|
||||
|
||||
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');
|
||||
|
||||
free(dst);
|
||||
|
||||
/*
|
||||
* Reset FPGA via FPGA_DATA pin
|
||||
*/
|
||||
SET_FPGA(FPGA_PRG | FPGA_CLK);
|
||||
udelay(1000); /* wait 1ms */
|
||||
SET_FPGA(FPGA_PRG | FPGA_CLK | FPGA_DATA);
|
||||
udelay(1000); /* wait 1ms */
|
||||
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
/*
|
||||
* Enable power on PS/2 interface
|
||||
*/
|
||||
*fpga_mode |= CFG_FPGA_CTRL_PS2_RESET;
|
||||
|
||||
/*
|
||||
* Enable interrupts in exar duart mcr[3]
|
||||
*/
|
||||
*duart0_mcr = 0x08;
|
||||
*duart1_mcr = 0x08;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
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 PPChameleonEVB");
|
||||
} 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 /* test-only */
|
||||
for (;;) {
|
||||
NAND_DISABLE_CE(1);
|
||||
udelay(100);
|
||||
NAND_ENABLE_CE(1);
|
||||
udelay(100);
|
||||
}
|
||||
#endif
|
||||
#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);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
#if (CONFIG_COMMANDS & CFG_CMD_NAND)
|
||||
extern ulong
|
||||
nand_probe(ulong physadr);
|
||||
|
||||
void
|
||||
nand_init(void)
|
||||
{
|
||||
ulong totlen;
|
||||
|
||||
debug ("Probing at 0x%.8x\n", CFG_NAND0_BASE);
|
||||
totlen = nand_probe (CFG_NAND0_BASE);
|
||||
|
||||
debug ("Probing at 0x%.8x\n", CFG_NAND1_BASE);
|
||||
totlen += nand_probe (CFG_NAND1_BASE);
|
||||
|
||||
printf ("%4lu MB\n", totlen >>20);
|
||||
}
|
||||
#endif
|
||||
24
board/dave/PPChameleonEVB/config.mk
Normal file
24
board/dave/PPChameleonEVB/config.mk
Normal file
@@ -0,0 +1,24 @@
|
||||
#
|
||||
# (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
|
||||
#
|
||||
|
||||
TEXT_BASE = 0xFFFC0000
|
||||
105
board/dave/PPChameleonEVB/flash.c
Normal file
105
board/dave/PPChameleonEVB/flash.c
Normal file
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
* (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 common flash code (for esd boards)
|
||||
*/
|
||||
#include "../common/flash.c"
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
* Functions
|
||||
*/
|
||||
static ulong flash_get_size (vu_long * addr, flash_info_t * info);
|
||||
static void flash_get_offsets (ulong base, flash_info_t * info);
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
unsigned long flash_init (void)
|
||||
{
|
||||
#ifdef __DEBUG_START_FROM_SRAM__
|
||||
return CFG_DUMMY_FLASH_SIZE;
|
||||
#else
|
||||
unsigned long size_b0;
|
||||
int i;
|
||||
uint pbcr;
|
||||
unsigned long base_b0;
|
||||
int size_val = 0;
|
||||
|
||||
/* 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);
|
||||
}
|
||||
|
||||
/* Setup offsets */
|
||||
flash_get_offsets (-size_b0, &flash_info[0]);
|
||||
|
||||
/* Re-do sizing to get full correct info */
|
||||
mtdcr(ebccfga, pb0cr);
|
||||
pbcr = mfdcr(ebccfgd);
|
||||
mtdcr(ebccfga, pb0cr);
|
||||
base_b0 = -size_b0;
|
||||
switch (size_b0) {
|
||||
case 1 << 20:
|
||||
size_val = 0;
|
||||
break;
|
||||
case 2 << 20:
|
||||
size_val = 1;
|
||||
break;
|
||||
case 4 << 20:
|
||||
size_val = 2;
|
||||
break;
|
||||
case 8 << 20:
|
||||
size_val = 3;
|
||||
break;
|
||||
case 16 << 20:
|
||||
size_val = 4;
|
||||
break;
|
||||
}
|
||||
pbcr = (pbcr & 0x0001ffff) | base_b0 | (size_val << 17);
|
||||
mtdcr(ebccfgd, pbcr);
|
||||
|
||||
/* Monitor protection ON by default */
|
||||
(void)flash_protect(FLAG_PROTECT_SET,
|
||||
-CFG_MONITOR_LEN,
|
||||
0xffffffff,
|
||||
&flash_info[0]);
|
||||
|
||||
flash_info[0].size = size_b0;
|
||||
|
||||
return (size_b0);
|
||||
#endif
|
||||
}
|
||||
1139
board/dave/PPChameleonEVB/fpgadata.c
Normal file
1139
board/dave/PPChameleonEVB/fpgadata.c
Normal file
File diff suppressed because it is too large
Load Diff
147
board/dave/PPChameleonEVB/u-boot.lds
Normal file
147
board/dave/PPChameleonEVB/u-boot.lds
Normal file
@@ -0,0 +1,147 @@
|
||||
/*
|
||||
* (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
|
||||
{
|
||||
.resetvec 0xFFFFFFFC :
|
||||
{
|
||||
*(.resetvec)
|
||||
} = 0xffff
|
||||
|
||||
/* Read-only sections, merged into text segment: */
|
||||
. = + SIZEOF_HEADERS;
|
||||
.interp : { *(.interp) }
|
||||
.hash : { *(.hash) }
|
||||
.dynsym : { *(.dynsym) }
|
||||
.dynstr : { *(.dynstr) }
|
||||
.rel.text : { *(.rel.text) }
|
||||
.rela.text : { *(.rela.text) }
|
||||
.rel.data : { *(.rel.data) }
|
||||
.rela.data : { *(.rela.data) }
|
||||
.rel.rodata : { *(.rel.rodata) }
|
||||
.rela.rodata : { *(.rela.rodata) }
|
||||
.rel.got : { *(.rel.got) }
|
||||
.rela.got : { *(.rela.got) }
|
||||
.rel.ctors : { *(.rel.ctors) }
|
||||
.rela.ctors : { *(.rela.ctors) }
|
||||
.rel.dtors : { *(.rel.dtors) }
|
||||
.rela.dtors : { *(.rela.dtors) }
|
||||
.rel.bss : { *(.rel.bss) }
|
||||
.rela.bss : { *(.rela.bss) }
|
||||
.rel.plt : { *(.rel.plt) }
|
||||
.rela.plt : { *(.rela.plt) }
|
||||
.init : { *(.init) }
|
||||
.plt : { *(.plt) }
|
||||
.text :
|
||||
{
|
||||
/* WARNING - the following is hand-optimized to fit within */
|
||||
/* the sector layout of our flash chips! XXX FIXME XXX */
|
||||
|
||||
cpu/ppc4xx/start.o (.text)
|
||||
cpu/ppc4xx/traps.o (.text)
|
||||
cpu/ppc4xx/interrupts.o (.text)
|
||||
cpu/ppc4xx/serial.o (.text)
|
||||
cpu/ppc4xx/cpu_init.o (.text)
|
||||
cpu/ppc4xx/speed.o (.text)
|
||||
cpu/ppc4xx/405gp_enet.o (.text)
|
||||
common/dlmalloc.o (.text)
|
||||
lib_generic/crc32.o (.text)
|
||||
lib_ppc/extable.o (.text)
|
||||
lib_generic/zlib.o (.text)
|
||||
|
||||
/* . = env_offset;*/
|
||||
/* common/environment.o(.text)*/
|
||||
|
||||
*(.text)
|
||||
*(.fixup)
|
||||
*(.got1)
|
||||
}
|
||||
_etext = .;
|
||||
PROVIDE (etext = .);
|
||||
.rodata :
|
||||
{
|
||||
*(.rodata)
|
||||
*(.rodata1)
|
||||
}
|
||||
.fini : { *(.fini) } =0
|
||||
.ctors : { *(.ctors) }
|
||||
.dtors : { *(.dtors) }
|
||||
|
||||
/* Read-write section, merged into data segment: */
|
||||
. = (. + 0x00FF) & 0xFFFFFF00;
|
||||
_erotext = .;
|
||||
PROVIDE (erotext = .);
|
||||
.reloc :
|
||||
{
|
||||
*(.got)
|
||||
_GOT2_TABLE_ = .;
|
||||
*(.got2)
|
||||
_FIXUP_TABLE_ = .;
|
||||
*(.fixup)
|
||||
}
|
||||
__got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2;
|
||||
__fixup_entries = (. - _FIXUP_TABLE_)>>2;
|
||||
|
||||
.data :
|
||||
{
|
||||
*(.data)
|
||||
*(.data1)
|
||||
*(.sdata)
|
||||
*(.sdata2)
|
||||
*(.dynamic)
|
||||
CONSTRUCTORS
|
||||
}
|
||||
_edata = .;
|
||||
PROVIDE (edata = .);
|
||||
|
||||
__u_boot_cmd_start = .;
|
||||
.u_boot_cmd : { *(.u_boot_cmd) }
|
||||
__u_boot_cmd_end = .;
|
||||
|
||||
|
||||
__start___ex_table = .;
|
||||
__ex_table : { *(__ex_table) }
|
||||
__stop___ex_table = .;
|
||||
|
||||
. = ALIGN(256);
|
||||
__init_begin = .;
|
||||
.text.init : { *(.text.init) }
|
||||
.data.init : { *(.data.init) }
|
||||
. = ALIGN(256);
|
||||
__init_end = .;
|
||||
|
||||
__bss_start = .;
|
||||
.bss :
|
||||
{
|
||||
*(.sbss) *(.scommon)
|
||||
*(.dynbss)
|
||||
*(.bss)
|
||||
*(COMMON)
|
||||
}
|
||||
_end = . ;
|
||||
PROVIDE (end = .);
|
||||
}
|
||||
681
board/dave/common/flash.c
Normal file
681
board/dave/common/flash.c
Normal file
@@ -0,0 +1,681 @@
|
||||
/*
|
||||
* (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>
|
||||
|
||||
flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
* Functions
|
||||
*/
|
||||
static int write_word (flash_info_t *info, ulong dest, ulong data);
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
*/
|
||||
static void flash_get_offsets (ulong base, flash_info_t *info)
|
||||
{
|
||||
int i;
|
||||
short n;
|
||||
|
||||
/* set up sector start address table */
|
||||
if (((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_SST) ||
|
||||
((info->flash_id & FLASH_TYPEMASK) == FLASH_AM640U)) {
|
||||
for (i = 0; i < info->sector_count; i++)
|
||||
info->start[i] = base + (i * 0x00010000);
|
||||
} else if (((info->flash_id & FLASH_TYPEMASK) == FLASH_AMDL322B) ||
|
||||
((info->flash_id & FLASH_TYPEMASK) == FLASH_AMDL323B) ||
|
||||
((info->flash_id & FLASH_TYPEMASK) == FLASH_AM320B) ||
|
||||
((info->flash_id & FLASH_TYPEMASK) == FLASH_AMDL324B)) {
|
||||
/* set sector offsets for bottom boot block type */
|
||||
for (i=0; i<8; ++i) { /* 8 x 8k boot sectors */
|
||||
info->start[i] = base;
|
||||
base += 8 << 10;
|
||||
}
|
||||
while (i < info->sector_count) { /* 64k regular sectors */
|
||||
info->start[i] = base;
|
||||
base += 64 << 10;
|
||||
++i;
|
||||
}
|
||||
} else if (((info->flash_id & FLASH_TYPEMASK) == FLASH_AMDL322T) ||
|
||||
((info->flash_id & FLASH_TYPEMASK) == FLASH_AMDL323T) ||
|
||||
((info->flash_id & FLASH_TYPEMASK) == FLASH_AM320T) ||
|
||||
((info->flash_id & FLASH_TYPEMASK) == FLASH_AMDL324T)) {
|
||||
/* set sector offsets for top boot block type */
|
||||
base += info->size;
|
||||
i = info->sector_count;
|
||||
for (n=0; n<8; ++n) { /* 8 x 8k boot sectors */
|
||||
base -= 8 << 10;
|
||||
--i;
|
||||
info->start[i] = base;
|
||||
}
|
||||
while (i > 0) { /* 64k regular sectors */
|
||||
base -= 64 << 10;
|
||||
--i;
|
||||
info->start[i] = base;
|
||||
}
|
||||
} else {
|
||||
if (info->flash_id & FLASH_BTYPE) {
|
||||
/* set sector offsets for bottom boot block type */
|
||||
info->start[0] = base + 0x00000000;
|
||||
info->start[1] = base + 0x00004000;
|
||||
info->start[2] = base + 0x00006000;
|
||||
info->start[3] = base + 0x00008000;
|
||||
for (i = 4; i < info->sector_count; i++) {
|
||||
info->start[i] = base + (i * 0x00010000) - 0x00030000;
|
||||
}
|
||||
} else {
|
||||
/* set sector offsets for top boot block type */
|
||||
i = info->sector_count - 1;
|
||||
info->start[i--] = base + info->size - 0x00004000;
|
||||
info->start[i--] = base + info->size - 0x00006000;
|
||||
info->start[i--] = base + info->size - 0x00008000;
|
||||
for (; i >= 0; i--) {
|
||||
info->start[i] = base + i * 0x00010000;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
*/
|
||||
void flash_print_info (flash_info_t *info)
|
||||
{
|
||||
int i;
|
||||
int k;
|
||||
int size;
|
||||
int erased;
|
||||
volatile unsigned long *flash;
|
||||
|
||||
if (info->flash_id == FLASH_UNKNOWN) {
|
||||
printf ("missing or unknown FLASH type\n");
|
||||
return;
|
||||
}
|
||||
|
||||
switch (info->flash_id & FLASH_VENDMASK) {
|
||||
case FLASH_MAN_AMD: printf ("AMD "); break;
|
||||
case FLASH_MAN_FUJ: printf ("FUJITSU "); break;
|
||||
case FLASH_MAN_SST: printf ("SST "); break;
|
||||
case FLASH_MAN_STM: printf ("ST "); 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_AM320T: printf ("AM29LV320T (32 M, top sector)\n");
|
||||
break;
|
||||
case FLASH_AM320B: printf ("AM29LV320B (32 M, bottom sector)\n");
|
||||
break;
|
||||
case FLASH_AMDL322T: printf ("AM29DL322T (32 M, top sector)\n");
|
||||
break;
|
||||
case FLASH_AMDL322B: printf ("AM29DL322B (32 M, bottom sector)\n");
|
||||
break;
|
||||
case FLASH_AMDL323T: printf ("AM29DL323T (32 M, top sector)\n");
|
||||
break;
|
||||
case FLASH_AMDL323B: printf ("AM29DL323B (32 M, bottom sector)\n");
|
||||
break;
|
||||
case FLASH_AM640U: printf ("AM29LV640D (64 M, uniform sector)\n");
|
||||
break;
|
||||
case FLASH_SST800A: printf ("SST39LF/VF800 (8 Mbit, uniform sector size)\n");
|
||||
break;
|
||||
case FLASH_SST160A: printf ("SST39LF/VF160 (16 Mbit, uniform sector size)\n");
|
||||
break;
|
||||
case FLASH_STMW320DT: printf ("M29W320DT (32 M, top 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) {
|
||||
#ifdef CFG_FLASH_EMPTY_INFO
|
||||
/*
|
||||
* Check if whole sector is erased
|
||||
*/
|
||||
if (i != (info->sector_count-1))
|
||||
size = info->start[i+1] - info->start[i];
|
||||
else
|
||||
size = info->start[0] + info->size - info->start[i];
|
||||
erased = 1;
|
||||
flash = (volatile unsigned long *)info->start[i];
|
||||
size = size >> 2; /* divide by 4 for longword access */
|
||||
for (k=0; k<size; k++)
|
||||
{
|
||||
if (*flash++ != 0xffffffff)
|
||||
{
|
||||
erased = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ((i % 5) == 0)
|
||||
printf ("\n ");
|
||||
/* print empty and read-only info */
|
||||
printf (" %08lX%s%s",
|
||||
info->start[i],
|
||||
erased ? " E" : " ",
|
||||
info->protect[i] ? "RO " : " ");
|
||||
#else
|
||||
if ((i % 5) == 0)
|
||||
printf ("\n ");
|
||||
printf (" %08lX%s",
|
||||
info->start[i],
|
||||
info->protect[i] ? " (RO)" : " ");
|
||||
#endif
|
||||
|
||||
}
|
||||
printf ("\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/*
|
||||
* The following code cannot be run from FLASH!
|
||||
*/
|
||||
static ulong flash_get_size (vu_long *addr, flash_info_t *info)
|
||||
{
|
||||
short i;
|
||||
short n;
|
||||
CFG_FLASH_WORD_SIZE value;
|
||||
ulong base = (ulong)addr;
|
||||
volatile CFG_FLASH_WORD_SIZE *addr2 = (CFG_FLASH_WORD_SIZE *)addr;
|
||||
|
||||
/* Write auto select command: read Manufacturer ID */
|
||||
addr2[CFG_FLASH_ADDR0] = (CFG_FLASH_WORD_SIZE)0x00AA00AA;
|
||||
addr2[CFG_FLASH_ADDR1] = (CFG_FLASH_WORD_SIZE)0x00550055;
|
||||
addr2[CFG_FLASH_ADDR0] = (CFG_FLASH_WORD_SIZE)0x00900090;
|
||||
|
||||
value = addr2[CFG_FLASH_READ0];
|
||||
|
||||
switch (value) {
|
||||
case (CFG_FLASH_WORD_SIZE)AMD_MANUFACT:
|
||||
info->flash_id = FLASH_MAN_AMD;
|
||||
break;
|
||||
case (CFG_FLASH_WORD_SIZE)FUJ_MANUFACT:
|
||||
info->flash_id = FLASH_MAN_FUJ;
|
||||
break;
|
||||
case (CFG_FLASH_WORD_SIZE)SST_MANUFACT:
|
||||
info->flash_id = FLASH_MAN_SST;
|
||||
break;
|
||||
case (CFG_FLASH_WORD_SIZE)STM_MANUFACT:
|
||||
info->flash_id = FLASH_MAN_STM;
|
||||
break;
|
||||
default:
|
||||
info->flash_id = FLASH_UNKNOWN;
|
||||
info->sector_count = 0;
|
||||
info->size = 0;
|
||||
return (0); /* no or unknown flash */
|
||||
}
|
||||
|
||||
value = addr2[CFG_FLASH_READ1]; /* device ID */
|
||||
|
||||
switch (value) {
|
||||
case (CFG_FLASH_WORD_SIZE)AMD_ID_LV400T:
|
||||
info->flash_id += FLASH_AM400T;
|
||||
info->sector_count = 11;
|
||||
info->size = 0x00080000;
|
||||
break; /* => 0.5 MB */
|
||||
|
||||
case (CFG_FLASH_WORD_SIZE)AMD_ID_LV400B:
|
||||
info->flash_id += FLASH_AM400B;
|
||||
info->sector_count = 11;
|
||||
info->size = 0x00080000;
|
||||
break; /* => 0.5 MB */
|
||||
|
||||
case (CFG_FLASH_WORD_SIZE)AMD_ID_LV800T:
|
||||
info->flash_id += FLASH_AM800T;
|
||||
info->sector_count = 19;
|
||||
info->size = 0x00100000;
|
||||
break; /* => 1 MB */
|
||||
|
||||
case (CFG_FLASH_WORD_SIZE)AMD_ID_LV800B:
|
||||
info->flash_id += FLASH_AM800B;
|
||||
info->sector_count = 19;
|
||||
info->size = 0x00100000;
|
||||
break; /* => 1 MB */
|
||||
|
||||
case (CFG_FLASH_WORD_SIZE)AMD_ID_LV160T:
|
||||
info->flash_id += FLASH_AM160T;
|
||||
info->sector_count = 35;
|
||||
info->size = 0x00200000;
|
||||
break; /* => 2 MB */
|
||||
|
||||
case (CFG_FLASH_WORD_SIZE)AMD_ID_LV160B:
|
||||
info->flash_id += FLASH_AM160B;
|
||||
info->sector_count = 35;
|
||||
info->size = 0x00200000;
|
||||
break; /* => 2 MB */
|
||||
|
||||
case (CFG_FLASH_WORD_SIZE)STM_ID_29W320DT:
|
||||
info->flash_id += FLASH_STMW320DT;
|
||||
info->sector_count = 67;
|
||||
info->size = 0x00400000; break; /* => 4 MB */
|
||||
|
||||
case (CFG_FLASH_WORD_SIZE)AMD_ID_LV320T:
|
||||
info->flash_id += FLASH_AM320T;
|
||||
info->sector_count = 71;
|
||||
info->size = 0x00400000; break; /* => 4 MB */
|
||||
|
||||
case (CFG_FLASH_WORD_SIZE)AMD_ID_LV320B:
|
||||
info->flash_id += FLASH_AM320B;
|
||||
info->sector_count = 71;
|
||||
info->size = 0x00400000; break; /* => 4 MB */
|
||||
|
||||
case (CFG_FLASH_WORD_SIZE)AMD_ID_DL322T:
|
||||
info->flash_id += FLASH_AMDL322T;
|
||||
info->sector_count = 71;
|
||||
info->size = 0x00400000; break; /* => 4 MB */
|
||||
|
||||
case (CFG_FLASH_WORD_SIZE)AMD_ID_DL322B:
|
||||
info->flash_id += FLASH_AMDL322B;
|
||||
info->sector_count = 71;
|
||||
info->size = 0x00400000; break; /* => 4 MB */
|
||||
|
||||
case (CFG_FLASH_WORD_SIZE)AMD_ID_DL323T:
|
||||
info->flash_id += FLASH_AMDL323T;
|
||||
info->sector_count = 71;
|
||||
info->size = 0x00400000; break; /* => 4 MB */
|
||||
|
||||
case (CFG_FLASH_WORD_SIZE)AMD_ID_DL323B:
|
||||
info->flash_id += FLASH_AMDL323B;
|
||||
info->sector_count = 71;
|
||||
info->size = 0x00400000; break; /* => 4 MB */
|
||||
|
||||
case (CFG_FLASH_WORD_SIZE)AMD_ID_LV640U:
|
||||
info->flash_id += FLASH_AM640U;
|
||||
info->sector_count = 128;
|
||||
info->size = 0x00800000; break; /* => 8 MB */
|
||||
|
||||
case (CFG_FLASH_WORD_SIZE)SST_ID_xF800A:
|
||||
info->flash_id += FLASH_SST800A;
|
||||
info->sector_count = 16;
|
||||
info->size = 0x00100000;
|
||||
break; /* => 1 MB */
|
||||
|
||||
case (CFG_FLASH_WORD_SIZE)SST_ID_xF160A:
|
||||
info->flash_id += FLASH_SST160A;
|
||||
info->sector_count = 32;
|
||||
info->size = 0x00200000;
|
||||
break; /* => 2 MB */
|
||||
|
||||
default:
|
||||
info->flash_id = FLASH_UNKNOWN;
|
||||
return (0); /* => no or unknown flash */
|
||||
|
||||
}
|
||||
|
||||
/* set up sector start address table */
|
||||
if (((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_SST) ||
|
||||
((info->flash_id & FLASH_TYPEMASK) == FLASH_AM640U)) {
|
||||
for (i = 0; i < info->sector_count; i++)
|
||||
info->start[i] = base + (i * 0x00010000);
|
||||
} else if (((info->flash_id & FLASH_TYPEMASK) == FLASH_AMDL322B) ||
|
||||
((info->flash_id & FLASH_TYPEMASK) == FLASH_AMDL323B) ||
|
||||
((info->flash_id & FLASH_TYPEMASK) == FLASH_AM320B) ||
|
||||
((info->flash_id & FLASH_TYPEMASK) == FLASH_AMDL324B)) {
|
||||
/* set sector offsets for bottom boot block type */
|
||||
for (i=0; i<8; ++i) { /* 8 x 8k boot sectors */
|
||||
info->start[i] = base;
|
||||
base += 8 << 10;
|
||||
}
|
||||
while (i < info->sector_count) { /* 64k regular sectors */
|
||||
info->start[i] = base;
|
||||
base += 64 << 10;
|
||||
++i;
|
||||
}
|
||||
} else if (((info->flash_id & FLASH_TYPEMASK) == FLASH_AMDL322T) ||
|
||||
((info->flash_id & FLASH_TYPEMASK) == FLASH_AMDL323T) ||
|
||||
((info->flash_id & FLASH_TYPEMASK) == FLASH_AM320T) ||
|
||||
((info->flash_id & FLASH_TYPEMASK) == FLASH_AMDL324T)) {
|
||||
/* set sector offsets for top boot block type */
|
||||
base += info->size;
|
||||
i = info->sector_count;
|
||||
for (n=0; n<8; ++n) { /* 8 x 8k boot sectors */
|
||||
base -= 8 << 10;
|
||||
--i;
|
||||
info->start[i] = base;
|
||||
}
|
||||
while (i > 0) { /* 64k regular sectors */
|
||||
base -= 64 << 10;
|
||||
--i;
|
||||
info->start[i] = base;
|
||||
}
|
||||
} else if ((info->flash_id & FLASH_TYPEMASK) == FLASH_STMW320DT) {
|
||||
/* set sector offsets for top boot block type */
|
||||
base += info->size;
|
||||
i = info->sector_count;
|
||||
/* 1 x 16k boot sector */
|
||||
base -= 16 << 10;
|
||||
--i;
|
||||
info->start[i] = base;
|
||||
/* 2 x 8k boot sectors */
|
||||
for (n=0; n<2; ++n) {
|
||||
base -= 8 << 10;
|
||||
--i;
|
||||
info->start[i] = base;
|
||||
}
|
||||
/* 1 x 32k boot sector */
|
||||
base -= 32 << 10;
|
||||
--i;
|
||||
info->start[i] = base;
|
||||
|
||||
while (i > 0) { /* 64k regular sectors */
|
||||
base -= 64 << 10;
|
||||
--i;
|
||||
info->start[i] = base;
|
||||
}
|
||||
} else {
|
||||
if (info->flash_id & FLASH_BTYPE) {
|
||||
/* set sector offsets for bottom boot block type */
|
||||
info->start[0] = base + 0x00000000;
|
||||
info->start[1] = base + 0x00004000;
|
||||
info->start[2] = base + 0x00006000;
|
||||
info->start[3] = base + 0x00008000;
|
||||
for (i = 4; i < info->sector_count; i++) {
|
||||
info->start[i] = base + (i * 0x00010000) - 0x00030000;
|
||||
}
|
||||
} else {
|
||||
/* set sector offsets for top boot block type */
|
||||
i = info->sector_count - 1;
|
||||
info->start[i--] = base + info->size - 0x00004000;
|
||||
info->start[i--] = base + info->size - 0x00006000;
|
||||
info->start[i--] = base + info->size - 0x00008000;
|
||||
for (; i >= 0; i--) {
|
||||
info->start[i] = base + i * 0x00010000;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* check for protected sectors */
|
||||
for (i = 0; i < info->sector_count; i++) {
|
||||
/* read sector protection at sector address, (A7 .. A0) = 0x02 */
|
||||
/* D0 = 1 if protected */
|
||||
addr2 = (volatile CFG_FLASH_WORD_SIZE *)(info->start[i]);
|
||||
if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_SST)
|
||||
info->protect[i] = 0;
|
||||
else
|
||||
info->protect[i] = addr2[CFG_FLASH_READ2] & 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Prevent writes to uninitialized FLASH.
|
||||
*/
|
||||
if (info->flash_id != FLASH_UNKNOWN) {
|
||||
addr2 = (CFG_FLASH_WORD_SIZE *)info->start[0];
|
||||
*addr2 = (CFG_FLASH_WORD_SIZE)0x00F000F0; /* reset bank */
|
||||
}
|
||||
|
||||
return (info->size);
|
||||
}
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
int flash_erase (flash_info_t *info, int s_first, int s_last)
|
||||
{
|
||||
volatile CFG_FLASH_WORD_SIZE *addr = (CFG_FLASH_WORD_SIZE *)(info->start[0]);
|
||||
volatile CFG_FLASH_WORD_SIZE *addr2;
|
||||
int flag, prot, sect, l_sect;
|
||||
ulong start, now, last;
|
||||
int i;
|
||||
|
||||
if ((s_first < 0) || (s_first > s_last)) {
|
||||
if (info->flash_id == FLASH_UNKNOWN) {
|
||||
printf ("- missing\n");
|
||||
} else {
|
||||
printf ("- no sectors to erase\n");
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (info->flash_id == FLASH_UNKNOWN) {
|
||||
printf ("Can't erase unknown flash type - aborted\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
prot = 0;
|
||||
for (sect=s_first; sect<=s_last; ++sect) {
|
||||
if (info->protect[sect]) {
|
||||
prot++;
|
||||
}
|
||||
}
|
||||
|
||||
if (prot) {
|
||||
printf ("- Warning: %d protected sectors will not be erased!\n",
|
||||
prot);
|
||||
} else {
|
||||
printf ("\n");
|
||||
}
|
||||
|
||||
l_sect = -1;
|
||||
|
||||
/* Disable interrupts which might cause a timeout here */
|
||||
flag = disable_interrupts();
|
||||
|
||||
/* Start erase on unprotected sectors */
|
||||
for (sect = s_first; sect<=s_last; sect++) {
|
||||
if (info->protect[sect] == 0) { /* not protected */
|
||||
addr2 = (CFG_FLASH_WORD_SIZE *)(info->start[sect]);
|
||||
if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_SST) {
|
||||
addr[CFG_FLASH_ADDR0] = (CFG_FLASH_WORD_SIZE)0x00AA00AA;
|
||||
addr[CFG_FLASH_ADDR1] = (CFG_FLASH_WORD_SIZE)0x00550055;
|
||||
addr[CFG_FLASH_ADDR0] = (CFG_FLASH_WORD_SIZE)0x00800080;
|
||||
addr[CFG_FLASH_ADDR0] = (CFG_FLASH_WORD_SIZE)0x00AA00AA;
|
||||
addr[CFG_FLASH_ADDR1] = (CFG_FLASH_WORD_SIZE)0x00550055;
|
||||
addr2[0] = (CFG_FLASH_WORD_SIZE)0x00500050; /* block erase */
|
||||
for (i=0; i<50; i++)
|
||||
udelay(1000); /* wait 1 ms */
|
||||
} else {
|
||||
if (sect == s_first) {
|
||||
addr[CFG_FLASH_ADDR0] = (CFG_FLASH_WORD_SIZE)0x00AA00AA;
|
||||
addr[CFG_FLASH_ADDR1] = (CFG_FLASH_WORD_SIZE)0x00550055;
|
||||
addr[CFG_FLASH_ADDR0] = (CFG_FLASH_WORD_SIZE)0x00800080;
|
||||
addr[CFG_FLASH_ADDR0] = (CFG_FLASH_WORD_SIZE)0x00AA00AA;
|
||||
addr[CFG_FLASH_ADDR1] = (CFG_FLASH_WORD_SIZE)0x00550055;
|
||||
}
|
||||
addr2[0] = (CFG_FLASH_WORD_SIZE)0x00300030; /* sector erase */
|
||||
}
|
||||
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 = (CFG_FLASH_WORD_SIZE *)(info->start[l_sect]);
|
||||
while ((addr[0] & (CFG_FLASH_WORD_SIZE)0x00800080) != (CFG_FLASH_WORD_SIZE)0x00800080) {
|
||||
if ((now = get_timer(start)) > CFG_FLASH_ERASE_TOUT) {
|
||||
printf ("Timeout\n");
|
||||
return 1;
|
||||
}
|
||||
/* show that we're waiting */
|
||||
if ((now - last) > 1000) { /* every second */
|
||||
putc ('.');
|
||||
last = now;
|
||||
}
|
||||
}
|
||||
|
||||
DONE:
|
||||
/* reset to read mode */
|
||||
addr = (CFG_FLASH_WORD_SIZE *)info->start[0];
|
||||
addr[0] = (CFG_FLASH_WORD_SIZE)0x00F000F0; /* reset bank */
|
||||
|
||||
printf (" done\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
* Copy memory to flash, returns:
|
||||
* 0 - OK
|
||||
* 1 - write timeout
|
||||
* 2 - Flash not erased
|
||||
*/
|
||||
|
||||
int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
|
||||
{
|
||||
ulong cp, wp, data;
|
||||
int i, l, rc;
|
||||
|
||||
wp = (addr & ~3); /* get lower word aligned address */
|
||||
|
||||
/*
|
||||
* handle unaligned start bytes
|
||||
*/
|
||||
if ((l = addr - wp) != 0) {
|
||||
data = 0;
|
||||
for (i=0, cp=wp; i<l; ++i, ++cp) {
|
||||
data = (data << 8) | (*(uchar *)cp);
|
||||
}
|
||||
for (; i<4 && cnt>0; ++i) {
|
||||
data = (data << 8) | *src++;
|
||||
--cnt;
|
||||
++cp;
|
||||
}
|
||||
for (; cnt==0 && i<4; ++i, ++cp) {
|
||||
data = (data << 8) | (*(uchar *)cp);
|
||||
}
|
||||
|
||||
if ((rc = write_word(info, wp, data)) != 0) {
|
||||
return (rc);
|
||||
}
|
||||
wp += 4;
|
||||
}
|
||||
|
||||
/*
|
||||
* handle word aligned part
|
||||
*/
|
||||
while (cnt >= 4) {
|
||||
data = 0;
|
||||
for (i=0; i<4; ++i) {
|
||||
data = (data << 8) | *src++;
|
||||
}
|
||||
if ((rc = write_word(info, wp, data)) != 0) {
|
||||
return (rc);
|
||||
}
|
||||
wp += 4;
|
||||
cnt -= 4;
|
||||
}
|
||||
|
||||
if (cnt == 0) {
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* handle unaligned tail bytes
|
||||
*/
|
||||
data = 0;
|
||||
for (i=0, cp=wp; i<4 && cnt>0; ++i, ++cp) {
|
||||
data = (data << 8) | *src++;
|
||||
--cnt;
|
||||
}
|
||||
for (; i<4; ++i, ++cp) {
|
||||
data = (data << 8) | (*(uchar *)cp);
|
||||
}
|
||||
|
||||
return (write_word(info, wp, data));
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
* Write a word to Flash, returns:
|
||||
* 0 - OK
|
||||
* 1 - write timeout
|
||||
* 2 - Flash not erased
|
||||
*/
|
||||
static int write_word (flash_info_t *info, ulong dest, ulong data)
|
||||
{
|
||||
volatile CFG_FLASH_WORD_SIZE *addr2 = (CFG_FLASH_WORD_SIZE *)(info->start[0]);
|
||||
volatile CFG_FLASH_WORD_SIZE *dest2 = (CFG_FLASH_WORD_SIZE *)dest;
|
||||
volatile CFG_FLASH_WORD_SIZE *data2 = (CFG_FLASH_WORD_SIZE *)&data;
|
||||
ulong start;
|
||||
int flag;
|
||||
int i;
|
||||
|
||||
/* Check if Flash is (sufficiently) erased */
|
||||
if ((*((volatile CFG_FLASH_WORD_SIZE *)dest) &
|
||||
(CFG_FLASH_WORD_SIZE)data) != (CFG_FLASH_WORD_SIZE)data) {
|
||||
return (2);
|
||||
}
|
||||
/* Disable interrupts which might cause a timeout here */
|
||||
flag = disable_interrupts();
|
||||
|
||||
for (i=0; i<4/sizeof(CFG_FLASH_WORD_SIZE); i++)
|
||||
{
|
||||
addr2[CFG_FLASH_ADDR0] = (CFG_FLASH_WORD_SIZE)0x00AA00AA;
|
||||
addr2[CFG_FLASH_ADDR1] = (CFG_FLASH_WORD_SIZE)0x00550055;
|
||||
addr2[CFG_FLASH_ADDR0] = (CFG_FLASH_WORD_SIZE)0x00A000A0;
|
||||
|
||||
dest2[i] = data2[i];
|
||||
|
||||
/* re-enable interrupts if necessary */
|
||||
if (flag)
|
||||
enable_interrupts();
|
||||
|
||||
/* data polling for D7 */
|
||||
start = get_timer (0);
|
||||
while ((dest2[i] & (CFG_FLASH_WORD_SIZE)0x00800080) !=
|
||||
(data2[i] & (CFG_FLASH_WORD_SIZE)0x00800080)) {
|
||||
if (get_timer(start) > CFG_FLASH_WRITE_TOUT) {
|
||||
return (1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
*/
|
||||
256
board/dave/common/fpga.c
Normal file
256
board/dave/common/fpga.c
Normal file
@@ -0,0 +1,256 @@
|
||||
/*
|
||||
* (C) Copyright 2001-2003
|
||||
* 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
|
||||
|
||||
#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(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 */
|
||||
|
||||
#if 0
|
||||
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 (GPIO0_ODR, 0x00000000); /* no open drain pins */
|
||||
out32 (GPIO0_TCR, in32 (GPIO0_TCR) | FPGA_PRG | FPGA_CLK | FPGA_DATA); /* setup for output */
|
||||
out32 (GPIO0_OR, in32 (GPIO0_OR) | FPGA_PRG | FPGA_CLK | FPGA_DATA); /* set pins to high */
|
||||
|
||||
DBG ("%s, ",
|
||||
((in32 (GPIO0_IR) & FPGA_DONE) == 0) ? "NOT DONE" : "DONE");
|
||||
DBG ("%s\n",
|
||||
((in32 (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 (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 (GPIO0_IR) & FPGA_DONE) == 0) ? "NOT DONE" : "DONE");
|
||||
DBG ("%s\n",
|
||||
((in32 (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 (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 (GPIO0_IR) & FPGA_DONE) == 0) ? "NOT DONE" : "DONE");
|
||||
DBG ("%s\n",
|
||||
((in32 (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 /* ! CFG_FPGA_SPARTAN2 */
|
||||
/* 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 /* CFG_FPGA_SPARTAN2 */
|
||||
|
||||
DBG ("%s, ",
|
||||
((in32 (GPIO0_IR) & FPGA_DONE) == 0) ? "NOT DONE" : "DONE");
|
||||
DBG ("%s\n",
|
||||
((in32 (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 (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;
|
||||
}
|
||||
#endif /* 0 */
|
||||
202
board/dave/common/pci.c
Normal file
202
board/dave/common/pci.c
Normal file
@@ -0,0 +1,202 @@
|
||||
/*
|
||||
* (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);
|
||||
}
|
||||
@@ -239,15 +239,11 @@ int testdram (void)
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
#if (CONFIG_COMMANDS & CFG_CMD_NAND)
|
||||
#include <linux/mtd/nand.h>
|
||||
extern struct nand_chip nand_dev_desc[CFG_MAX_NAND_DEVICE];
|
||||
|
||||
void nand_init(void)
|
||||
{
|
||||
nand_probe(CFG_NAND_BASE);
|
||||
if (nand_dev_desc[0].ChipID != NAND_ChipID_UNKNOWN) {
|
||||
puts("NAND: ");
|
||||
print_size(nand_dev_desc[0].totlen, "\n");
|
||||
}
|
||||
unsigned long totlen = nand_probe(CFG_NAND_BASE);
|
||||
|
||||
printf ("%4lu MB\n", totlen >> 20);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -237,7 +237,7 @@ int board_pre_init (void)
|
||||
* on-board sram on the eval board, and updates the correct
|
||||
* registers to boot from the sram. (device0)
|
||||
*/
|
||||
#ifdef CONFIG_ZUMA_V2
|
||||
#if defined(CONFIG_ZUMA_V2) || defined(CONFIG_P3G4)
|
||||
/* Zuma has no SRAM */
|
||||
sram_boot = 0;
|
||||
#else
|
||||
@@ -265,6 +265,7 @@ int board_pre_init (void)
|
||||
GT_REG_WRITE(DEVICE_BANK2PARAMETERS, CFG_DEV2_PAR);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_EVB64260
|
||||
#ifdef CFG_32BIT_BOOT_PAR
|
||||
/* detect if we are booting from the 32 bit flash */
|
||||
if (GTREGREAD(DEVICE_BOOT_BANK_PARAMETERS) & (0x3 << 20)) {
|
||||
@@ -280,6 +281,11 @@ int board_pre_init (void)
|
||||
/* 8 bit boot flash only */
|
||||
GT_REG_WRITE(DEVICE_BOOT_BANK_PARAMETERS, CFG_8BIT_BOOT_PAR);
|
||||
#endif
|
||||
#else /* CONFIG_EVB64260 not defined */
|
||||
/* We are booting from 16-bit flash.
|
||||
*/
|
||||
GT_REG_WRITE(DEVICE_BOOT_BANK_PARAMETERS, CFG_16BIT_BOOT_PAR);
|
||||
#endif
|
||||
|
||||
gt_cpu_config();
|
||||
|
||||
@@ -351,7 +357,7 @@ checkboard (void)
|
||||
void
|
||||
debug_led(int led, int mode)
|
||||
{
|
||||
#ifndef CONFIG_ZUMA_V2
|
||||
#if !defined(CONFIG_ZUMA_V2) && !defined(CONFIG_P3G4)
|
||||
volatile int *addr = NULL;
|
||||
int dummy;
|
||||
|
||||
|
||||
@@ -54,6 +54,7 @@ flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */
|
||||
static ulong flash_get_size (int portwidth, vu_long *addr, flash_info_t *info);
|
||||
static int write_word (flash_info_t *info, ulong dest, ulong data);
|
||||
static void flash_get_offsets (ulong base, flash_info_t *info);
|
||||
static flash_info_t *flash_get_info(ulong base);
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
*/
|
||||
@@ -72,7 +73,11 @@ flash_init (void)
|
||||
|
||||
/* the boot flash */
|
||||
base = CFG_FLASH_BASE;
|
||||
size_b0 = flash_get_size(1, (vu_long *)base, &flash_info[0]);
|
||||
#ifndef CFG_BOOT_FLASH_WIDTH
|
||||
#define CFG_BOOT_FLASH_WIDTH 1
|
||||
#endif
|
||||
size_b0 = flash_get_size(CFG_BOOT_FLASH_WIDTH, (vu_long *)base,
|
||||
&flash_info[0]);
|
||||
|
||||
printf("[%ldkB@%lx] ", size_b0/1024, base);
|
||||
|
||||
@@ -98,6 +103,22 @@ flash_init (void)
|
||||
base+=size;
|
||||
}
|
||||
|
||||
#if CFG_MONITOR_BASE >= CFG_FLASH_BASE
|
||||
/* monitor protection ON by default */
|
||||
flash_protect(FLAG_PROTECT_SET,
|
||||
CFG_MONITOR_BASE,
|
||||
CFG_MONITOR_BASE + monitor_flash_len - 1,
|
||||
flash_get_info(CFG_MONITOR_BASE));
|
||||
#endif
|
||||
|
||||
#ifdef CFG_ENV_IS_IN_FLASH
|
||||
/* ENV protection ON by default */
|
||||
flash_protect(FLAG_PROTECT_SET,
|
||||
CFG_ENV_ADDR,
|
||||
CFG_ENV_ADDR + CFG_ENV_SIZE - 1,
|
||||
flash_get_info(CFG_ENV_ADDR));
|
||||
#endif
|
||||
|
||||
flash_size = size_b0 + size_b1;
|
||||
return flash_size;
|
||||
}
|
||||
@@ -146,6 +167,23 @@ flash_get_offsets (ulong base, flash_info_t *info)
|
||||
}
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
static flash_info_t *flash_get_info(ulong base)
|
||||
{
|
||||
int i;
|
||||
flash_info_t * info;
|
||||
|
||||
for (i = 0; i < CFG_MAX_FLASH_BANKS; i ++) {
|
||||
info = & flash_info[i];
|
||||
if (info->start[0] <= base && base <= info->start[0] + info->size - 1)
|
||||
break;
|
||||
}
|
||||
|
||||
return i == CFG_MAX_FLASH_BANKS ? 0 : info;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
*/
|
||||
void
|
||||
@@ -247,8 +285,11 @@ static inline void flash_cmd(int width, volatile unsigned char *addr, int offset
|
||||
/* 2x16 */
|
||||
unsigned long cmd32=(cmd<<16)|cmd;
|
||||
*(volatile unsigned long *)(addr+offset*2)=cmd32;
|
||||
} else if (width == 2) {
|
||||
/* 1x16 */
|
||||
*(volatile unsigned short *)((unsigned short*)addr+offset)=cmd;
|
||||
} else {
|
||||
/* 1x16 or 1x8 */
|
||||
/* 1x8 */
|
||||
*(volatile unsigned char *)(addr+offset)=cmd;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -273,7 +273,7 @@ mpsc_init(int baud)
|
||||
|
||||
/* BRG CONFIG */
|
||||
galbrg_set_baudrate(CHANNEL, baud);
|
||||
#ifdef CONFIG_ZUMA_V2
|
||||
#if defined(CONFIG_ZUMA_V2) || defined(CONFIG_P3G4)
|
||||
galbrg_set_clksrc(CHANNEL,0x8); /* connect TCLK -> BRG */
|
||||
#else
|
||||
galbrg_set_clksrc(CHANNEL,0);
|
||||
@@ -387,7 +387,7 @@ galbrg_set_baudrate(int channel, int rate)
|
||||
|
||||
galbrg_disable(channel);
|
||||
|
||||
#ifdef CONFIG_ZUMA_V2
|
||||
#if defined(CONFIG_ZUMA_V2) || defined(CONFIG_P3G4)
|
||||
/* from tclk */
|
||||
clock = (CFG_BUS_HZ/(16*rate)) - 1;
|
||||
#else
|
||||
@@ -803,6 +803,7 @@ static int
|
||||
galmpsc_shutdown(int mpsc)
|
||||
{
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
#if 0
|
||||
unsigned int temp;
|
||||
|
||||
/* cause RX abort (clears RX) */
|
||||
@@ -810,9 +811,11 @@ galmpsc_shutdown(int mpsc)
|
||||
temp |= MPSC_RX_ABORT | MPSC_TX_ABORT;
|
||||
temp &= ~MPSC_ENTER_HUNT;
|
||||
GT_REG_WRITE_MIRROR(GALMPSC_CHANNELREG_2,mpsc,GALMPSC_REG_GAP,temp);
|
||||
#endif
|
||||
|
||||
GT_REG_WRITE(GALSDMA_0_COM_REG, 0);
|
||||
GT_REG_WRITE(GALSDMA_0_COM_REG, SDMA_TX_ABORT | SDMA_RX_ABORT);
|
||||
GT_REG_WRITE(GALSDMA_0_COM_REG + CHANNEL * GALSDMA_REG_DIFF, 0);
|
||||
GT_REG_WRITE(GALSDMA_0_COM_REG + CHANNEL * GALSDMA_REG_DIFF,
|
||||
SDMA_TX_ABORT | SDMA_RX_ABORT);
|
||||
|
||||
/* shut down the MPSC */
|
||||
GT_REG_WRITE(GALMPSC_MCONF_LOW, 0);
|
||||
@@ -823,14 +826,15 @@ galmpsc_shutdown(int mpsc)
|
||||
|
||||
/* shut down the sdma engines. */
|
||||
/* reset config to default */
|
||||
GT_REG_WRITE(GALSDMA_0_CONF_REG, 0x000000fc);
|
||||
GT_REG_WRITE(GALSDMA_0_CONF_REG + CHANNEL * GALSDMA_REG_DIFF,
|
||||
0x000000fc);
|
||||
|
||||
udelay(100);
|
||||
|
||||
/* clear the SDMA current and first TX and RX pointers */
|
||||
GT_REG_WRITE(GALSDMA_0_CUR_RX_PTR, 0);
|
||||
GT_REG_WRITE(GALSDMA_0_CUR_TX_PTR, 0);
|
||||
GT_REG_WRITE(GALSDMA_0_FIR_TX_PTR, 0);
|
||||
GT_REG_WRITE(GALSDMA_0_CUR_RX_PTR + CHANNEL * GALSDMA_REG_DIFF, 0);
|
||||
GT_REG_WRITE(GALSDMA_0_CUR_TX_PTR + CHANNEL * GALSDMA_REG_DIFF, 0);
|
||||
GT_REG_WRITE(GALSDMA_0_FIR_TX_PTR + CHANNEL * GALSDMA_REG_DIFF, 0);
|
||||
|
||||
udelay(100);
|
||||
|
||||
|
||||
@@ -175,7 +175,30 @@ check_dimm(uchar slot, sdram_info_t *info)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else /* ! CONFIG_ZUMA_V2 */
|
||||
#elif defined(CONFIG_P3G4)
|
||||
|
||||
static int
|
||||
check_dimm(uchar slot, sdram_info_t *info)
|
||||
{
|
||||
memset(info, 0, sizeof(*info));
|
||||
|
||||
if (slot)
|
||||
return 0;
|
||||
|
||||
info->slot = slot;
|
||||
info->banks = 1;
|
||||
info->registered = 0;
|
||||
info->drb_size = 4;
|
||||
info->tpar = 3;
|
||||
info->tras_clocks = 6;
|
||||
info->burst_len = 4;
|
||||
#ifdef CONFIG_ECC
|
||||
info->ecc = 2;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else /* ! CONFIG_ZUMA_V2 && ! CONFIG_P3G4*/
|
||||
|
||||
/* This code reads the SPD chip on the sdram and populates
|
||||
* the array which is passed in with the relevant information */
|
||||
|
||||
@@ -64,24 +64,20 @@ unsigned long flash_init (void)
|
||||
unsigned long size = 0;
|
||||
int i;
|
||||
extern void flash_preinit(void);
|
||||
extern void flash_afterinit(ulong);
|
||||
ulong flashbase = CFG_FLASH_BASE;
|
||||
|
||||
flash_preinit();
|
||||
|
||||
/* Init: no FLASHes known */
|
||||
for (i=0; i < CFG_MAX_FLASH_BANKS; ++i) {
|
||||
ulong flashbase = CFG_FLASH_BASE;
|
||||
|
||||
memset(&flash_info[i], 0, sizeof(flash_info_t));
|
||||
|
||||
flash_info[i].size =
|
||||
flash_get_size((FPW *)flashbase, &flash_info[i]);
|
||||
|
||||
if (flash_info[i].flash_id == FLASH_UNKNOWN) {
|
||||
printf ("## Unknown FLASH on Bank %d - Size = 0x%08lx\n",
|
||||
i, flash_info[i].size);
|
||||
}
|
||||
|
||||
size += flash_info[i].size;
|
||||
flashbase += 0x800000;
|
||||
}
|
||||
#if CFG_MONITOR_BASE >= CFG_FLASH_BASE
|
||||
/* monitor protection ON by default */
|
||||
@@ -100,6 +96,7 @@ unsigned long flash_init (void)
|
||||
#endif
|
||||
|
||||
|
||||
flash_afterinit(size);
|
||||
return size ? size : 1;
|
||||
}
|
||||
|
||||
@@ -126,7 +123,8 @@ static flash_info_t *flash_get_info(ulong base)
|
||||
|
||||
for (i = 0; i < CFG_MAX_FLASH_BANKS; i ++) {
|
||||
info = & flash_info[i];
|
||||
if (info->start[0] <= base && base <= info->start[0] + info->size - 1)
|
||||
if (info->size &&
|
||||
info->start[0] <= base && base <= info->start[0] + info->size - 1)
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -211,6 +209,8 @@ void flash_print_info (flash_info_t *info)
|
||||
ulong flash_get_size (FPWV *addr, flash_info_t *info)
|
||||
{
|
||||
int i;
|
||||
FPWV* addr2;
|
||||
|
||||
/* Write auto select command: read Manufacturer ID */
|
||||
/* Write auto select command sequence and test FLASH answer */
|
||||
addr[FLASH_CYCLE1] = (FPW)0x00AA00AA; /* for AMD, Intel ignores this */
|
||||
@@ -256,6 +256,17 @@ ulong flash_get_size (FPWV *addr, flash_info_t *info)
|
||||
return (0); /* => no or unknown flash */
|
||||
}
|
||||
|
||||
/* test for real flash at bank 1 */
|
||||
addr2 = (FPW *)((ulong)addr | 0x800000);
|
||||
if (addr2 != addr &&
|
||||
((addr2[0] & 0xff) == (addr[0] & 0xff)) && ((FPW)addr2[1] == (FPW)addr[1])) {
|
||||
/* Seems 2 banks are the same space (8Mb chip is installed,
|
||||
* J24 in default position (CS0)). Disable this (first) bank.
|
||||
*/
|
||||
info->flash_id = FLASH_UNKNOWN;
|
||||
info->sector_count = 0;
|
||||
info->size = 0;
|
||||
}
|
||||
/* Put FLASH back in read mode */
|
||||
flash_reset(info);
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include <mpc5xxx.h>
|
||||
#include <pci.h>
|
||||
|
||||
#ifndef CFG_RAMBOOT
|
||||
static long int dram_size(long int *base, long int maxsize)
|
||||
{
|
||||
volatile long int *addr;
|
||||
@@ -86,11 +87,14 @@ static void sdram_start (int hi_addr)
|
||||
/* normal operation */
|
||||
*(vu_long *)MPC5XXX_SDRAM_CTRL = 0x504f0000 | hi_addr_bit;
|
||||
}
|
||||
#endif
|
||||
|
||||
long int initdram (int board_type)
|
||||
{
|
||||
ulong test1, test2, dramsize = 0;
|
||||
ulong dramsize = 0;
|
||||
#ifndef CFG_RAMBOOT
|
||||
ulong test1, test2;
|
||||
|
||||
/* configure SDRAM start/end */
|
||||
#if defined(CONFIG_MPC5200)
|
||||
*(vu_long *)MPC5XXX_SDRAM_CS0CFG = 0x0000001e;/* 2G at 0x0 */
|
||||
@@ -133,8 +137,11 @@ long int initdram (int board_type)
|
||||
#else
|
||||
#ifdef CONFIG_MGT5100
|
||||
*(vu_long *)MPC5XXX_ADDECR |= (1 << 22); /* Enable SDRAM */
|
||||
dramsize = ((*(vu_long *)MPC5XXX_SDRAM_STOP + 1) << 15);
|
||||
#else
|
||||
dramsize = ((1 << (*(vu_long *)MPC5XXX_SDRAM_CS0CFG - 0x13)) << 20);
|
||||
#endif
|
||||
#endif
|
||||
#endif /* CFG_RAMBOOT */
|
||||
/* return total ram size */
|
||||
return dramsize;
|
||||
}
|
||||
@@ -164,6 +171,16 @@ void flash_preinit(void)
|
||||
*(vu_long *)MPC5XXX_BOOTCS_CFG &= ~0x1; /* clear RO */
|
||||
}
|
||||
|
||||
void flash_afterinit(ulong size)
|
||||
{
|
||||
if (size == 0x800000) { /* adjust mapping */
|
||||
*(vu_long *)MPC5XXX_BOOTCS_START = *(vu_long *)MPC5XXX_CS0_START =
|
||||
START_REG(CFG_BOOTCS_START | size);
|
||||
*(vu_long *)MPC5XXX_BOOTCS_STOP = *(vu_long *)MPC5XXX_CS0_STOP =
|
||||
STOP_REG(CFG_BOOTCS_START | size, size);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PCI
|
||||
static struct pci_controller hose;
|
||||
|
||||
|
||||
@@ -136,11 +136,6 @@ SECTIONS
|
||||
*(.bss)
|
||||
*(COMMON)
|
||||
}
|
||||
. = ALIGN(256 * 1024);
|
||||
.ppcenv :
|
||||
{
|
||||
common/environment.o (.ppcenv)
|
||||
}
|
||||
_end = . ;
|
||||
PROVIDE (end = .);
|
||||
}
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
#include <common.h>
|
||||
#include <ioports.h>
|
||||
#include <mpc8260.h>
|
||||
#include <asm/m8260_pci.h>
|
||||
#include <i2c.h>
|
||||
#include <spd.h>
|
||||
#include <miiphy.h>
|
||||
@@ -237,6 +238,9 @@ int board_pre_init (void)
|
||||
|
||||
long int initdram (int board_type)
|
||||
{
|
||||
#if CONFIG_ADSTYPE == CFG_PQ2FADS
|
||||
vu_long *bcsr = (vu_long *)CFG_BCSR;
|
||||
#endif
|
||||
volatile immap_t *immap = (immap_t *) CFG_IMMR;
|
||||
volatile memctl8260_t *memctl = &immap->im_memctl;
|
||||
volatile uchar *ramaddr, c = 0xff;
|
||||
@@ -252,27 +256,41 @@ long int initdram (int board_type)
|
||||
immap->im_siu_conf.sc_ppc_alrh = 0x01267893;
|
||||
immap->im_siu_conf.sc_tescr1 = 0x00004000;
|
||||
|
||||
#if CONFIG_ADSTYPE == CFG_PQ2FADS
|
||||
if ((bcsr[3] & BCSR_PCI_MODE) == 0) { /* PCI mode selected by JP9 */
|
||||
immap->im_clkrst.car_sccr |= M826X_SCCR_PCI_MODE_EN;
|
||||
immap->im_siu_conf.sc_siumcr =
|
||||
(immap->im_siu_conf.sc_siumcr & ~SIUMCR_LBPC11)
|
||||
| SIUMCR_LBPC01;
|
||||
}
|
||||
#endif /* CONFIG_ADSTYPE == CFG_PQ2FADS */
|
||||
|
||||
memctl->memc_mptpr = CFG_MPTPR;
|
||||
#ifdef CFG_LSDRAM_BASE
|
||||
/* Init local bus SDRAM */
|
||||
memctl->memc_lsrt = CFG_LSRT;
|
||||
/*
|
||||
Initialise local bus SDRAM only if the pins
|
||||
are configured as local bus pins and not as PCI.
|
||||
The configuration is determined by the HRCW.
|
||||
*/
|
||||
if ((immap->im_siu_conf.sc_siumcr & SIUMCR_LBPC11) == SIUMCR_LBPC00) {
|
||||
memctl->memc_lsrt = CFG_LSRT;
|
||||
#if CONFIG_ADSTYPE == CFG_PQ2FADS /* CS3 */
|
||||
memctl->memc_or3 = 0xFF803280;
|
||||
memctl->memc_br3 = CFG_LSDRAM_BASE | 0x00001861;
|
||||
memctl->memc_or3 = 0xFF803280;
|
||||
memctl->memc_br3 = CFG_LSDRAM_BASE | 0x00001861;
|
||||
#else /* CS4 */
|
||||
memctl->memc_or4 = 0xFFC01480;
|
||||
memctl->memc_br4 = CFG_LSDRAM_BASE | 0x00001861;
|
||||
memctl->memc_or4 = 0xFFC01480;
|
||||
memctl->memc_br4 = CFG_LSDRAM_BASE | 0x00001861;
|
||||
#endif /* CONFIG_ADSTYPE == CFG_PQ2FADS */
|
||||
memctl->memc_lsdmr = CFG_LSDMR | 0x28000000;
|
||||
ramaddr = (uchar *) CFG_LSDRAM_BASE;
|
||||
*ramaddr = c;
|
||||
memctl->memc_lsdmr = CFG_LSDMR | 0x08000000;
|
||||
for (i = 0; i < 8; i++) {
|
||||
memctl->memc_lsdmr = CFG_LSDMR | 0x28000000;
|
||||
ramaddr = (uchar *) CFG_LSDRAM_BASE;
|
||||
*ramaddr = c;
|
||||
memctl->memc_lsdmr = CFG_LSDMR | 0x08000000;
|
||||
for (i = 0; i < 8; i++)
|
||||
*ramaddr = c;
|
||||
memctl->memc_lsdmr = CFG_LSDMR | 0x18000000;
|
||||
*ramaddr = c;
|
||||
memctl->memc_lsdmr = CFG_LSDMR | 0x40000000;
|
||||
}
|
||||
memctl->memc_lsdmr = CFG_LSDMR | 0x18000000;
|
||||
*ramaddr = c;
|
||||
memctl->memc_lsdmr = CFG_LSDMR | 0x40000000;
|
||||
#endif /* CFG_LSDRAM_BASE */
|
||||
|
||||
/* Init 60x bus SDRAM */
|
||||
|
||||
@@ -375,138 +375,6 @@ void show_stdio_dev(void)
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
/* 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
|
||||
|
||||
#if defined(CONFIG_PIP405) || defined(CONFIG_MIP405)
|
||||
int switch_cs(unsigned char boot)
|
||||
{
|
||||
unsigned long pbcr;
|
||||
int mode;
|
||||
|
||||
mode=get_boot_mode();
|
||||
mtdcr(ebccfga, pb0cr);
|
||||
pbcr = mfdcr (ebccfgd);
|
||||
if (mode & BOOT_MPS) {
|
||||
/* Boot width = 8 bit MPS Boot, set up MPS on CS0 */
|
||||
/* 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 get_boot_mode(void)
|
||||
{
|
||||
unsigned long pbcr;
|
||||
int res = 0;
|
||||
pbcr = mfdcr (strap);
|
||||
if ((pbcr & PSR_ROM_WIDTH_MASK) == 0)
|
||||
/* boot via MPS or MPS mapping */
|
||||
res = BOOT_MPS;
|
||||
if(pbcr & PSR_ROM_LOC)
|
||||
/* boot via PCI.. */
|
||||
res |= BOOT_PCI;
|
||||
return res;
|
||||
}
|
||||
|
||||
/* Setup cs0 parameter finally.
|
||||
Map the flash high (in boot area)
|
||||
This code can only be executed from SDRAM (after relocation).
|
||||
*/
|
||||
void setup_cs_reloc(void)
|
||||
{
|
||||
unsigned long pbcr;
|
||||
/* Since we are relocated, we can set-up the CS finaly
|
||||
* but first of all, switch off PCI mapping (in case it was a PCI boot) */
|
||||
out32r(PMM0MA,0L);
|
||||
icache_enable (); /* we are relocated */
|
||||
/* for PCI Boot, we have to set-up the remaining CS correctly */
|
||||
pbcr = mfdcr (strap);
|
||||
if(pbcr & PSR_ROM_LOC) {
|
||||
/* boot via PCI.. */
|
||||
if ((pbcr & PSR_ROM_WIDTH_MASK) == 0) {
|
||||
/* Boot width = 8 bit MPS Boot, set up MPS on CS0 */
|
||||
#ifdef DEBUG
|
||||
printf("Mapping MPS to CS0 @ 0x%lx\n",(MPS_CR_B & 0xfff00000));
|
||||
#endif
|
||||
mtdcr (ebccfga, pb0ap);
|
||||
mtdcr (ebccfgd, MPS_AP);
|
||||
mtdcr (ebccfga, pb0cr);
|
||||
mtdcr (ebccfgd, MPS_CR_B);
|
||||
}
|
||||
else {
|
||||
/* Flash boot, set up the Flash on CS0 */
|
||||
#ifdef DEBUG
|
||||
printf("Mapping Flash to CS0 @ 0x%lx\n",(FLASH_CR_B & 0xfff00000));
|
||||
#endif
|
||||
mtdcr (ebccfga, pb0ap);
|
||||
mtdcr (ebccfgd, FLASH_AP);
|
||||
mtdcr (ebccfga, pb0cr);
|
||||
mtdcr (ebccfgd, FLASH_CR_B);
|
||||
}
|
||||
}
|
||||
switch_cs(0); /* map Flash High */
|
||||
}
|
||||
|
||||
|
||||
#elif defined(CONFIG_VCMA9)
|
||||
int switch_cs(unsigned char boot)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif /* CONFIG_VCMA9 */
|
||||
|
||||
int do_mplcommon(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
|
||||
{
|
||||
@@ -625,6 +493,7 @@ void doc_init (void)
|
||||
|
||||
#ifdef CONFIG_CONSOLE_EXTRA_INFO
|
||||
extern GraphicDevice ctfb;
|
||||
extern int get_boot_mode(void);
|
||||
|
||||
void video_get_info_str (int line_number, char *info)
|
||||
{
|
||||
|
||||
@@ -31,10 +31,8 @@ typedef struct {
|
||||
} backup_t;
|
||||
|
||||
void get_backup_values(backup_t *buf);
|
||||
int switch_cs(unsigned char boot);
|
||||
|
||||
#if defined(CONFIG_PIP405) || defined(CONFIG_MIP405)
|
||||
int get_boot_mode(void);
|
||||
void setup_cs_reloc(void);
|
||||
#define BOOT_MPS 0x01
|
||||
#define BOOT_PCI 0x02
|
||||
#endif
|
||||
|
||||
@@ -39,6 +39,13 @@
|
||||
#include <ppc4xx.h>
|
||||
#include <asm/processor.h>
|
||||
#include "common_util.h"
|
||||
#if defined(CONFIG_MIP405)
|
||||
#include "../mip405/mip405.h"
|
||||
#endif
|
||||
#if defined(CONFIG_PIP405)
|
||||
#include "../pip405/pip405.h"
|
||||
#endif
|
||||
#include <405gp_pci.h>
|
||||
|
||||
flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */
|
||||
/*-----------------------------------------------------------------------
|
||||
@@ -66,23 +73,102 @@ void unlock_intel_sectors(flash_info_t *info,ulong addr,ulong cnt);
|
||||
#define TRUE 1
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
* Some CS switching routines:
|
||||
*
|
||||
* On PIP/MIP405 we have 3 (4) possible boot mode
|
||||
*
|
||||
* - Boot from Flash (Flash CS = CS0, MPS CS = CS1)
|
||||
* - Boot from MPS (Flash CS = CS1, MPS CS = CS0)
|
||||
* - Boot from PCI with Flash map (Flash CS = CS0, MPS CS = CS1)
|
||||
* - Boot from PCI with MPS map (Flash CS = CS1, MPS CS = CS0)
|
||||
* The flash init is the first board specific routine which is called
|
||||
* after code relocation (running from SDRAM)
|
||||
* The first thing we do is to map the Flash CS to the Flash area and
|
||||
* the MPS CS to the MPS area. Since the flash size is unknown at this
|
||||
* point, we use the max flash size and the lowest flash address as base.
|
||||
*
|
||||
* After flash detection we adjust the size of the CS area accordingly.
|
||||
* The board_init_r will fill in wrong values in the board init structure,
|
||||
* but this will be fixed in the misc_init_r routine:
|
||||
* bd->bi_flashstart=0-flash_info[0].size
|
||||
* bd->bi_flashsize=flash_info[0].size-CFG_MONITOR_LEN
|
||||
* bd->bi_flashoffset=0
|
||||
*
|
||||
*/
|
||||
int get_boot_mode(void)
|
||||
{
|
||||
unsigned long pbcr;
|
||||
int res = 0;
|
||||
pbcr = mfdcr (strap);
|
||||
if ((pbcr & PSR_ROM_WIDTH_MASK) == 0)
|
||||
/* boot via MPS or MPS mapping */
|
||||
res = BOOT_MPS;
|
||||
if(pbcr & PSR_ROM_LOC)
|
||||
/* boot via PCI.. */
|
||||
res |= BOOT_PCI;
|
||||
return res;
|
||||
}
|
||||
|
||||
/* Map the flash high (in boot area)
|
||||
This code can only be executed from SDRAM (after relocation).
|
||||
*/
|
||||
void setup_cs_reloc(void)
|
||||
{
|
||||
int mode;
|
||||
/* Since we are relocated, we can set-up the CS finaly
|
||||
* but first of all, switch off PCI mapping (in case it was a PCI boot) */
|
||||
out32r(PMM0MA,0L);
|
||||
icache_enable (); /* we are relocated */
|
||||
/* get boot mode */
|
||||
mode=get_boot_mode();
|
||||
/* we map the flash high in every case */
|
||||
/* first findout on which cs the flash is */
|
||||
if(mode & BOOT_MPS) {
|
||||
/* map flash high on CS1 and MPS on CS0 */
|
||||
mtdcr (ebccfga, pb0ap);
|
||||
mtdcr (ebccfgd, MPS_AP);
|
||||
mtdcr (ebccfga, pb0cr);
|
||||
mtdcr (ebccfgd, MPS_CR);
|
||||
/* we use the default values (max values) for the flash
|
||||
* because its real size is not yet known */
|
||||
mtdcr (ebccfga, pb1ap);
|
||||
mtdcr (ebccfgd, FLASH_AP);
|
||||
mtdcr (ebccfga, pb1cr);
|
||||
mtdcr (ebccfgd, FLASH_CR_B);
|
||||
}
|
||||
else {
|
||||
/* map flash high on CS0 and MPS on CS1 */
|
||||
mtdcr (ebccfga, pb1ap);
|
||||
mtdcr (ebccfgd, MPS_AP);
|
||||
mtdcr (ebccfga, pb1cr);
|
||||
mtdcr (ebccfgd, MPS_CR);
|
||||
/* we use the default values (max values) for the flash
|
||||
* because its real size is not yet known */
|
||||
mtdcr (ebccfga, pb0ap);
|
||||
mtdcr (ebccfgd, FLASH_AP);
|
||||
mtdcr (ebccfga, pb0cr);
|
||||
mtdcr (ebccfgd, FLASH_CR_B);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
unsigned long flash_init (void)
|
||||
{
|
||||
unsigned long size_b0, size_b1;
|
||||
int i;
|
||||
unsigned long size_b0, size_b1,flashcr;
|
||||
int mode, i;
|
||||
extern char version_string;
|
||||
char *p=&version_string;
|
||||
|
||||
/* Since we are relocated, we can set-up the CS finally */
|
||||
setup_cs_reloc();
|
||||
/* get and display boot mode */
|
||||
i=get_boot_mode();
|
||||
if(i & BOOT_PCI)
|
||||
printf("(PCI Boot %s Map) ",(i & BOOT_MPS) ?
|
||||
mode=get_boot_mode();
|
||||
if(mode & BOOT_PCI)
|
||||
printf("(PCI Boot %s Map) ",(mode & BOOT_MPS) ?
|
||||
"MPS" : "Flash");
|
||||
else
|
||||
printf("(%s Boot) ",(i & BOOT_MPS) ?
|
||||
printf("(%s Boot) ",(mode & BOOT_MPS) ?
|
||||
"MPS" : "Flash");
|
||||
/* Init: no FLASHes known */
|
||||
for (i=0; i<CFG_MAX_FLASH_BANKS; ++i) {
|
||||
@@ -91,7 +177,7 @@ unsigned long flash_init (void)
|
||||
|
||||
/* Static FLASH Bank configuration here - FIXME XXX */
|
||||
|
||||
size_b0 = flash_get_size((vu_long *)FLASH_BASE0_PRELIM, &flash_info[0]);
|
||||
size_b0 = flash_get_size((vu_long *)CFG_MONITOR_BASE, &flash_info[0]);
|
||||
|
||||
if (flash_info[0].flash_id == FLASH_UNKNOWN) {
|
||||
printf ("## Unknown FLASH on Bank 0 - Size = 0x%08lx = %ld MB\n",
|
||||
@@ -109,8 +195,31 @@ unsigned long flash_init (void)
|
||||
flash_info[0].protect[flash_info[0].sector_count-1] = 1;
|
||||
size_b1 = 0 ;
|
||||
flash_info[0].size = size_b0;
|
||||
/* set up flash cs according to the size */
|
||||
if(mode & BOOT_MPS) {
|
||||
/* flash is on CS1 */
|
||||
mtdcr(ebccfga, pb1cr);
|
||||
flashcr = mfdcr (ebccfgd);
|
||||
/* we map the flash high in every case */
|
||||
flashcr&=0x0001FFFF; /* mask out address bits */
|
||||
flashcr|= ((0-flash_info[0].size) & 0xFFF00000); /* start addr */
|
||||
flashcr|= (((flash_info[0].size >>21) & 0x07) << 17); /* size addr */
|
||||
mtdcr(ebccfga, pb1cr);
|
||||
mtdcr(ebccfgd, flashcr);
|
||||
}
|
||||
else {
|
||||
/* flash is on CS0 */
|
||||
mtdcr(ebccfga, pb0cr);
|
||||
flashcr = mfdcr (ebccfgd);
|
||||
/* we map the flash high in every case */
|
||||
flashcr&=0x0001FFFF; /* mask out address bits */
|
||||
flashcr|= ((0-flash_info[0].size) & 0xFFF00000); /* start addr */
|
||||
flashcr|= (((flash_info[0].size >>21) & 0x07) << 17); /* size addr */
|
||||
mtdcr(ebccfga, pb0cr);
|
||||
mtdcr(ebccfgd, flashcr);
|
||||
}
|
||||
#if 0
|
||||
/* include this if you want to test if
|
||||
/* enable this if you want to test if
|
||||
the relocation has be done ok.
|
||||
This will disable both Chipselects */
|
||||
mtdcr (ebccfga, pb0cr);
|
||||
@@ -119,6 +228,14 @@ unsigned long flash_init (void)
|
||||
mtdcr (ebccfgd, 0L);
|
||||
printf("CS0 & CS1 switched off for test\n");
|
||||
#endif
|
||||
/* patch version_string */
|
||||
for(i=0;i<0x100;i++) {
|
||||
if(*p=='\n') {
|
||||
*p=0;
|
||||
break;
|
||||
}
|
||||
p++;
|
||||
}
|
||||
return (size_b0);
|
||||
}
|
||||
|
||||
@@ -171,6 +288,8 @@ void flash_print_info (flash_info_t *info)
|
||||
break;
|
||||
case FLASH_INTEL320T: printf ("TE28F320C3 (32 Mbit, top sector size)\n");
|
||||
break;
|
||||
case FLASH_AM640U: printf ("AM29LV640U (64 Mbit, uniform sector size)\n");
|
||||
break;
|
||||
default: printf ("Unknown Chip Type\n");
|
||||
break;
|
||||
}
|
||||
@@ -211,7 +330,8 @@ void flash_print_info (flash_info_t *info)
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
* The following code cannot be run from FLASH!
|
||||
@@ -220,7 +340,7 @@ static ulong flash_get_size (vu_long *addr, flash_info_t *info)
|
||||
{
|
||||
short i;
|
||||
FLASH_WORD_SIZE value;
|
||||
ulong base = (ulong)addr;
|
||||
ulong base;
|
||||
volatile FLASH_WORD_SIZE *addr2 = (FLASH_WORD_SIZE *)addr;
|
||||
|
||||
/* Write auto select command: read Manufacturer ID */
|
||||
@@ -250,7 +370,7 @@ static ulong flash_get_size (vu_long *addr, flash_info_t *info)
|
||||
return (0); /* no or unknown flash */
|
||||
}
|
||||
value = addr2[1]; /* device ID */
|
||||
/* printf("Device value %x\n",value); */
|
||||
/* printf("Device value %x\n",value); */
|
||||
switch (value) {
|
||||
case (FLASH_WORD_SIZE)AMD_ID_F040B:
|
||||
info->flash_id += FLASH_AM040;
|
||||
@@ -292,12 +412,17 @@ static ulong flash_get_size (vu_long *addr, flash_info_t *info)
|
||||
info->sector_count = 35;
|
||||
info->size = 0x00200000;
|
||||
break; /* => 2 MB */
|
||||
#if 0 /* enable when device IDs are available */
|
||||
case (FLASH_WORD_SIZE)AMD_ID_LV320T:
|
||||
info->flash_id += FLASH_AM320T;
|
||||
info->sector_count = 67;
|
||||
info->size = 0x00400000;
|
||||
break; /* => 4 MB */
|
||||
case (FLASH_WORD_SIZE)AMD_ID_LV640U:
|
||||
info->flash_id += FLASH_AM640U;
|
||||
info->sector_count = 128;
|
||||
info->size = 0x00800000;
|
||||
break; /* => 8 MB */
|
||||
#if 0 /* enable when device IDs are available */
|
||||
|
||||
case (FLASH_WORD_SIZE)AMD_ID_LV320B:
|
||||
info->flash_id += FLASH_AM320B;
|
||||
@@ -328,10 +453,12 @@ static ulong flash_get_size (vu_long *addr, flash_info_t *info)
|
||||
return (0); /* => no or unknown flash */
|
||||
|
||||
}
|
||||
|
||||
/* base address calculation */
|
||||
base=0-info->size;
|
||||
/* set up sector start address table */
|
||||
if (((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_SST) ||
|
||||
(info->flash_id == FLASH_AM040)){
|
||||
(info->flash_id == FLASH_AM040) ||
|
||||
(info->flash_id == FLASH_AM640U)){
|
||||
for (i = 0; i < info->sector_count; i++)
|
||||
info->start[i] = base + (i * 0x00010000);
|
||||
}
|
||||
|
||||
@@ -32,7 +32,6 @@
|
||||
#include "kbd.h"
|
||||
#include "video.h"
|
||||
|
||||
extern int drv_isa_kbd_init (void);
|
||||
|
||||
#undef ISA_DEBUG
|
||||
|
||||
@@ -49,6 +48,9 @@ extern int drv_isa_kbd_init (void);
|
||||
#define FALSE 0
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_PIP405)
|
||||
|
||||
extern int drv_isa_kbd_init (void);
|
||||
|
||||
/* fdc (logical device 0) */
|
||||
const SIO_LOGDEV_TABLE sio_fdc[] = {
|
||||
@@ -183,7 +185,7 @@ void isa_sio_setup(void)
|
||||
close_cfg_super_IO(0x3F0);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/******************************************************************************
|
||||
* IRQ Controller
|
||||
@@ -202,7 +204,7 @@ static struct isa_irq_action isa_irqs[16];
|
||||
/*
|
||||
* This contains the irq mask for both 8259A irq controllers,
|
||||
*/
|
||||
static unsigned int cached_irq_mask = 0xffff;
|
||||
static unsigned int cached_irq_mask = 0xfff9;
|
||||
|
||||
#define cached_imr1 (unsigned char)cached_irq_mask
|
||||
#define cached_imr2 (unsigned char)(cached_irq_mask>>8)
|
||||
@@ -387,19 +389,22 @@ int handle_isa_int(void)
|
||||
isr2=in8(ISR_2);
|
||||
isr1=in8(ISR_1);
|
||||
irq=(unsigned char)irqack;
|
||||
if((irq==7)&&((isr1&0x80)==0)) {
|
||||
irq-=32;
|
||||
/* if((irq==7)&&((isr1&0x80)==0)) {
|
||||
PRINTF("IRQ7 detected but not in ISR\n");
|
||||
}
|
||||
else {
|
||||
/* we should handle cascaded interrupts here also */
|
||||
/* printf("ISA Irq %d\n",irq); */
|
||||
isa_irqs[irq].count++;
|
||||
if (isa_irqs[irq].handler != NULL)
|
||||
(*isa_irqs[irq].handler)(isa_irqs[irq].arg); /* call isr */
|
||||
else
|
||||
*/ /* we should handle cascaded interrupts here also */
|
||||
{
|
||||
PRINTF ("bogus interrupt vector 0x%x\n", irq);
|
||||
}
|
||||
/* printf("ISA Irq %d\n",irq); */
|
||||
isa_irqs[irq].count++;
|
||||
if(irq!=2) { /* just swallow the cascade irq 2 */
|
||||
if (isa_irqs[irq].handler != NULL)
|
||||
(*isa_irqs[irq].handler)(isa_irqs[irq].arg); /* call isr */
|
||||
else {
|
||||
PRINTF ("bogus interrupt vector 0x%x\n", irq);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* issue EOI instruction to clear the IRQ */
|
||||
mask_and_ack_8259A(irq);
|
||||
@@ -413,13 +418,13 @@ int handle_isa_int(void)
|
||||
|
||||
void isa_irq_install_handler(int vec, interrupt_handler_t *handler, void *arg)
|
||||
{
|
||||
if (isa_irqs[vec].handler != NULL) {
|
||||
printf ("ISA Interrupt vector %d: handler 0x%x replacing 0x%x\n",
|
||||
vec, (uint)handler, (uint)isa_irqs[vec].handler);
|
||||
}
|
||||
isa_irqs[vec].handler = handler;
|
||||
isa_irqs[vec].arg = arg;
|
||||
enable_8259A_irq(vec);
|
||||
if (isa_irqs[vec].handler != NULL) {
|
||||
printf ("ISA Interrupt vector %d: handler 0x%x replacing 0x%x\n",
|
||||
vec, (uint)handler, (uint)isa_irqs[vec].handler);
|
||||
}
|
||||
isa_irqs[vec].handler = handler;
|
||||
isa_irqs[vec].arg = arg;
|
||||
enable_8259A_irq(vec);
|
||||
PRINTF ("Install ISA IRQ %d ==> %p, @ %p mask=%04x\n", vec, handler, &isa_irqs[vec].handler,cached_irq_mask);
|
||||
|
||||
}
|
||||
@@ -427,9 +432,9 @@ void isa_irq_install_handler(int vec, interrupt_handler_t *handler, void *arg)
|
||||
void isa_irq_free_handler(int vec)
|
||||
{
|
||||
disable_8259A_irq(vec);
|
||||
isa_irqs[vec].handler = NULL;
|
||||
isa_irqs[vec].arg = NULL;
|
||||
printf ("Free ISA IRQ %d mask=%04x\n", vec, cached_irq_mask);
|
||||
isa_irqs[vec].handler = NULL;
|
||||
isa_irqs[vec].arg = NULL;
|
||||
PRINTF ("Free ISA IRQ %d mask=%04x\n", vec, cached_irq_mask);
|
||||
|
||||
}
|
||||
|
||||
@@ -448,16 +453,42 @@ void isa_init_irq_contr(void)
|
||||
init_8259A();
|
||||
out8(IMR_2,0xFF);
|
||||
}
|
||||
/*************************************************************************/
|
||||
|
||||
void isa_show_irq(void)
|
||||
{
|
||||
int vec;
|
||||
|
||||
printf ("\nISA Interrupt-Information:\n");
|
||||
printf ("Nr Routine Arg Count\n");
|
||||
|
||||
for (vec=0; vec<16; vec++) {
|
||||
if (isa_irqs[vec].handler != NULL) {
|
||||
printf ("%02d %08lx %08lx %d\n",
|
||||
vec,
|
||||
(ulong)isa_irqs[vec].handler,
|
||||
(ulong)isa_irqs[vec].arg,
|
||||
isa_irqs[vec].count);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int isa_irq_get_count(int vec)
|
||||
{
|
||||
return(isa_irqs[vec].count);
|
||||
}
|
||||
|
||||
/******************************************************************
|
||||
* Init the ISA bus and devices.
|
||||
*/
|
||||
|
||||
#if defined(CONFIG_PIP405)
|
||||
|
||||
int isa_init(void)
|
||||
{
|
||||
isa_sio_setup();
|
||||
isa_init_irq_contr();
|
||||
drv_isa_kbd_init();
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -21,12 +21,12 @@
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef _PIP405_ISA_H_
|
||||
#define _PIP405_ISA_H_
|
||||
#ifndef _ISA_H_
|
||||
#define _ISA_H_
|
||||
/* Super IO */
|
||||
#define SIO_CFG_PORT 0x3F0 /* Config Port Address */
|
||||
|
||||
|
||||
#if defined(CONFIG_PIP405)
|
||||
/* table fore SIO initialization */
|
||||
typedef struct {
|
||||
const uchar index;
|
||||
@@ -44,10 +44,14 @@ unsigned char read_cfg_super_IO(int address, unsigned char function, unsigned ch
|
||||
void write_cfg_super_IO(int address, unsigned char function, unsigned char regaddr, unsigned char data);
|
||||
void close_cfg_super_IO(int address);
|
||||
void isa_sio_setup(void);
|
||||
void isa_sio_setup(void);
|
||||
#endif
|
||||
|
||||
void isa_irq_install_handler(int vec, interrupt_handler_t *handler, void *arg);
|
||||
void isa_irq_free_handler(int vec);
|
||||
int handle_isa_int(void);
|
||||
void isa_init_irq_contr(void);
|
||||
void isa_show_irq(void);
|
||||
int isa_irq_get_count(int vec);
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -92,7 +92,7 @@ extern void pci_pip405_write_regs(struct pci_controller *,
|
||||
/* 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_GENCFG, 0x00018041, 4}, /* enable SERIRQs, ISA, PNP, GPI11 */
|
||||
{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 */
|
||||
@@ -106,6 +106,7 @@ static struct pci_pip405_config_entry piix4_isa_bridge_f0[] = {
|
||||
|
||||
/* PIIX4 IDE Controller Function 1 */
|
||||
static struct pci_pip405_config_entry piix4_ide_cntrl_f1[] = {
|
||||
{PCI_CFG_PIIX4_BMIBA, 0x0001000, 4}, /* set BMI to a valid address */
|
||||
{PCI_COMMAND, 0x0001, 2}, /* enable IO access */
|
||||
#if !defined(CONFIG_MIP405T)
|
||||
{PCI_CFG_PIIX4_IDETIM, 0x80008000, 4}, /* enable Both IDE channels */
|
||||
@@ -129,10 +130,10 @@ static struct pci_pip405_config_entry piix4_usb_cntrl_f2[] = {
|
||||
|
||||
/* 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_PMBA, 0x00004000, 4}, /* set PMBA to "valid" value */
|
||||
{PCI_CFG_PIIX4_SMBBA, 0x00005000, 4}, /* set SMBBA to "valid" value */
|
||||
{PCI_CFG_PIIX4_PMMISC, 0x01, 1}, /* enable PMBA IO access */
|
||||
{PCI_COMMAND, 0x0001, 2}, /* enable IO access */
|
||||
{ } /* end of device table */
|
||||
};
|
||||
/* PPC405 Dummy only used to prevent autosetup on this host bridge */
|
||||
|
||||
@@ -143,7 +143,7 @@
|
||||
#define PCI_CFG_PIIX4_LEGSUP 0xC0
|
||||
|
||||
/* Function 3 Power Management */
|
||||
#define PCI_CFG_PIIX4_PMAB 0x40
|
||||
#define PCI_CFG_PIIX4_PMBA 0x40
|
||||
#define PCI_CFG_PIIX4_CNTA 0x44
|
||||
#define PCI_CFG_PIIX4_CNTB 0x48
|
||||
#define PCI_CFG_PIIX4_GPICTL 0x4C
|
||||
|
||||
@@ -54,10 +54,13 @@ int do_mip405(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
|
||||
return (do_mplcommon(cmdtp, flag, argc, argv));
|
||||
}
|
||||
U_BOOT_CMD(
|
||||
mip405, 6, 1, do_mip405,
|
||||
mip405, 8, 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"
|
||||
"mip405 info - displays board information\n"
|
||||
"mip405 led <on> - switches LED on (on=1) or off (on=0)\n"
|
||||
"mip405 mem [cnt] - Memory Test <cnt>-times, <cnt> = -1 loop forever\n"
|
||||
);
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
@@ -87,19 +87,15 @@ ext_bus_cntlr_init:
|
||||
mfdcr r4,ebccfgd
|
||||
|
||||
andi. r0, r4, 0x2000 /* mask out irrelevant bits */
|
||||
beq 0f /* jump if 8 bit bus width */
|
||||
beq 0f /* jump if 8 bit bus width */
|
||||
|
||||
/* setup 16 bit things (Flash Boot)
|
||||
/* setup 16 bit things
|
||||
*-----------------------------------------------------------------------
|
||||
* Memory Bank 0 (16 Bit Flash) initialization
|
||||
*---------------------------------------------------------------------- */
|
||||
|
||||
addi r4,0,pb0ap
|
||||
mtdcr ebccfga,r4
|
||||
/* addis r4,0,0xFF8F */
|
||||
/* ori r4,r4,0xFE80 */
|
||||
/* addis r4,0,0x9B01 */
|
||||
/* ori r4,r4,0x5480 */
|
||||
addis r4,0,(FLASH_AP_B)@h
|
||||
ori r4,r4,(FLASH_AP_B)@l
|
||||
mtdcr ebccfgd,r4
|
||||
@@ -107,8 +103,6 @@ ext_bus_cntlr_init:
|
||||
addi r4,0,pb0cr
|
||||
mtdcr ebccfga,r4
|
||||
/* BS=0x010(4MB),BU=0x3(R/W), */
|
||||
/* addis r4,0,((FLASH_BASE0_PRELIM & 0xFFF00000) | 0x00050000)@h */
|
||||
/* ori r4,r4,0xA000 / * BW=0x01(16 bits) */
|
||||
addis r4,0,(FLASH_CR_B)@h
|
||||
ori r4,r4,(FLASH_CR_B)@l
|
||||
mtdcr ebccfgd,r4
|
||||
@@ -123,21 +117,13 @@ ext_bus_cntlr_init:
|
||||
/* 0x7F8FFE80 slowest boot */
|
||||
addi r4,0,pb0ap
|
||||
mtdcr ebccfga,r4
|
||||
#if 0
|
||||
addis r4,0,0x9B01
|
||||
ori r4,r4,0x5480
|
||||
#else
|
||||
addis r4,0,(MPS_AP_B)@h
|
||||
ori r4,r4,(MPS_AP_B)@l
|
||||
#endif
|
||||
mtdcr ebccfgd,r4
|
||||
|
||||
addi r4,0,pb0cr
|
||||
mtdcr ebccfga,r4
|
||||
/* BS=0x010(4MB),BU=0x3(R/W), */
|
||||
/* addis r4,0,((FLASH_BASE0_PRELIM & 0xFFF00000) | 0x00050000)@h */
|
||||
/* ori r4,r4,0x8000 / * BW=0x0( 8 bits) */
|
||||
|
||||
addis r4,0,(MPS_CR_B)@h
|
||||
ori r4,r4,(MPS_CR_B)@l
|
||||
|
||||
@@ -178,18 +164,18 @@ ext_bus_cntlr_init:
|
||||
ori r4,r4,0x0000
|
||||
mtdcr ebccfgd,r4
|
||||
|
||||
addi r4,0,pb6cr
|
||||
addi r4,0,pb6cr
|
||||
mtdcr ebccfga,r4
|
||||
addis r4,0,0x0000
|
||||
ori r4,r4,0x0000
|
||||
mtdcr ebccfgd,r4
|
||||
|
||||
addi r4,0,pb7cr
|
||||
addi r4,0,pb7cr
|
||||
mtdcr ebccfga,r4
|
||||
addis r4,0,0x0000
|
||||
ori r4,r4,0x0000
|
||||
mtdcr ebccfgd,r4
|
||||
nop /* pass2 DCR errata #8 */
|
||||
nop /* pass2 DCR errata #8 */
|
||||
blr
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
@@ -667,9 +667,16 @@ static int test_dram (unsigned long ramsize)
|
||||
/* used to check if the time in RTC is valid */
|
||||
static unsigned long start;
|
||||
static struct rtc_time tm;
|
||||
extern flash_info_t flash_info[]; /* info for FLASH chips */
|
||||
|
||||
int misc_init_r (void)
|
||||
{
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
/* adjust flash start and size as well as the offset */
|
||||
gd->bd->bi_flashstart=0-flash_info[0].size;
|
||||
gd->bd->bi_flashsize=flash_info[0].size-CFG_MONITOR_LEN;
|
||||
gd->bd->bi_flashoffset=0;
|
||||
|
||||
/* check, if RTC is running */
|
||||
rtc_get (&tm);
|
||||
start=get_timer(0);
|
||||
|
||||
@@ -137,13 +137,13 @@ void user_led0(unsigned char on);
|
||||
(FLASH_WBF << 12) + (FLASH_TH << 9) + (FLASH_RE << 8) + (FLASH_SOR << 7) + (FLASH_BEM << 6) + (FLASH_PEN << 5))
|
||||
|
||||
/* Size: 0=1MB, 1=2MB, 2=4MB, 3=8MB, 4=16MB, 5=32MB, 6=64MB, 7=128MB */
|
||||
#define FLASH_BS 2 /* 4 MByte */
|
||||
#define FLASH_BS FLASH_SIZE_PRELIM /* 4 MByte */
|
||||
/* Usage: 0=disabled, 1=Read only, 2=Write Only, 3=R/W */
|
||||
#define FLASH_BU 3 /* R/W */
|
||||
/* Bus width: 0=8Bit, 1=16Bit, 2=32Bit, 3=Reserved */
|
||||
#define FLASH_BW 1 /* 16Bit */
|
||||
/* CR register for Boot */
|
||||
#define FLASH_CR_B ((FLASH_BASE0_PRELIM & 0xfff00000) + (FLASH_BS << 17) + (FLASH_BU << 15) + (FLASH_BW << 13))
|
||||
#define FLASH_CR_B ((FLASH_BASE_PRELIM & 0xfff00000) + (FLASH_BS << 17) + (FLASH_BU << 15) + (FLASH_BW << 13))
|
||||
/* CR register for non Boot */
|
||||
#define FLASH_CR ((MULTI_PURPOSE_SOCKET_ADDR & 0xfff00000) + (FLASH_BS << 17) + (FLASH_BU << 15) + (FLASH_BW << 13))
|
||||
|
||||
@@ -172,11 +172,12 @@ void user_led0(unsigned char on);
|
||||
|
||||
/* Size: 0=1MB, 1=2MB, 2=4MB, 3=8MB, 4=16MB, 5=32MB, 6=64MB, 7=128MB */
|
||||
#define MPS_BS 2 /* 4 MByte */
|
||||
#define MPS_BS_B FLASH_SIZE_PRELIM /* 1 MByte */
|
||||
/* Usage: 0=disabled, 1=Read only, 2=Write Only, 3=R/W */
|
||||
#define MPS_BU 3 /* R/W */
|
||||
/* Bus width: 0=8Bit, 1=16Bit, 2=32Bit, 3=Reserved */
|
||||
#define MPS_BW 0 /* 8Bit */
|
||||
/* CR register for Boot */
|
||||
#define MPS_CR_B ((FLASH_BASE0_PRELIM & 0xfff00000) + (MPS_BS << 17) + (MPS_BU << 15) + (MPS_BW << 13))
|
||||
#define MPS_CR_B ((FLASH_BASE_PRELIM & 0xfff00000) + (MPS_BS_B << 17) + (MPS_BU << 15) + (MPS_BW << 13))
|
||||
/* CR register for non Boot */
|
||||
#define MPS_CR ((MULTI_PURPOSE_SOCKET_ADDR & 0xfff00000) + (MPS_BS << 17) + (MPS_BU << 15) + (MPS_BW << 13))
|
||||
|
||||
@@ -41,17 +41,21 @@
|
||||
|
||||
#define _LINUX_CONFIG_H 1 /* avoid reading Linux autoconf.h file */
|
||||
|
||||
#include "configs/PIP405.h"
|
||||
#include <configs/PIP405.h>
|
||||
#include <ppc_asm.tmpl>
|
||||
#include <ppc_defs.h>
|
||||
|
||||
#include <asm/cache.h>
|
||||
#include <asm/mmu.h>
|
||||
#include "pip405.h"
|
||||
|
||||
.globl ext_bus_cntlr_init
|
||||
ext_bus_cntlr_init:
|
||||
mflr r4 /* save link register */
|
||||
mfdcr r3,strap /* get strapping reg */
|
||||
andi. r0, r3, PSR_ROM_LOC /* mask out irrelevant bits */
|
||||
bnelr /* jump back if PCI boot */
|
||||
|
||||
.globl ext_bus_cntlr_init
|
||||
ext_bus_cntlr_init:
|
||||
mflr r4 /* save link register */
|
||||
bl ..getAddr
|
||||
..getAddr:
|
||||
mflr r3 /* get address of ..getAddr */
|
||||
@@ -82,7 +86,7 @@ ext_bus_cntlr_init:
|
||||
mfdcr r4,ebccfgd
|
||||
|
||||
andi. r0, r4, 0x2000 /* mask out irrelevant bits */
|
||||
beq 0f /* jump if 8 bit bus width */
|
||||
beq 0f /* jump if 8 bit bus width */
|
||||
|
||||
/* setup 16 bit things
|
||||
*-----------------------------------------------------------------------
|
||||
@@ -90,74 +94,49 @@ ext_bus_cntlr_init:
|
||||
*---------------------------------------------------------------------- */
|
||||
|
||||
addi r4,0,pb0ap
|
||||
mtdcr ebccfga,r4
|
||||
addis r4,0,0x9B01
|
||||
ori r4,r4,0x5480
|
||||
mtdcr ebccfgd,r4
|
||||
mtdcr ebccfga,r4
|
||||
addis r4,0,(FLASH_AP_B)@h
|
||||
ori r4,r4,(FLASH_AP_B)@l
|
||||
mtdcr ebccfgd,r4
|
||||
|
||||
addi r4,0,pb0cr
|
||||
mtdcr ebccfga,r4
|
||||
/* BS=0x011(8MB),BU=0x3(R/W), */
|
||||
addis r4,0,((FLASH_BASE0_PRELIM & 0xFFF00000) | 0x00050000)@h
|
||||
ori r4,r4,0xA000 /* BW=0x01(16 bits) */
|
||||
mtdcr ebccfgd,r4
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
* Memory Bank 1 (Multi Purpose Socket) initialization
|
||||
*----------------------------------------------------------------------*/
|
||||
addi r4,0,pb1ap
|
||||
mtdcr ebccfga,r4
|
||||
addis r4,0,0x0281
|
||||
ori r4,r4,0x5480
|
||||
mtdcr ebccfgd,r4
|
||||
|
||||
addi r4,0,pb1cr
|
||||
mtdcr ebccfga,r4
|
||||
/* BS=0x011(8MB),BU=0x3(R/W), */
|
||||
addis r4,0,((MULTI_PURPOSE_SOCKET_ADDR & 0xFFF00000) | 0x00050000)@h
|
||||
ori r4,r4,0x8000 /* BW=0x0( 8 bits) */
|
||||
mtdcr ebccfgd,r4
|
||||
addi r4,0,pb0cr
|
||||
mtdcr ebccfga,r4
|
||||
/* BS=0x010(4MB),BU=0x3(R/W), */
|
||||
addis r4,0,(FLASH_CR_B)@h
|
||||
ori r4,r4,(FLASH_CR_B)@l
|
||||
mtdcr ebccfgd,r4
|
||||
b 1f
|
||||
|
||||
0:
|
||||
/* 8Bit boot mode: */
|
||||
/* 8Bit boot mode: */
|
||||
/*-----------------------------------------------------------------------
|
||||
* Memory Bank 0 Multi Purpose Socket initialization
|
||||
*----------------------------------------------------------------------- */
|
||||
|
||||
* Memory Bank 0 Multi Purpose Socket initialization
|
||||
*----------------------------------------------------------------------- */
|
||||
/* 0x7F8FFE80 slowest boot */
|
||||
addi r4,0,pb0ap
|
||||
mtdcr ebccfga,r4
|
||||
addis r4,0,0x9B01
|
||||
ori r4,r4,0x5480
|
||||
mtdcr ebccfgd,r4
|
||||
mtdcr ebccfga,r4
|
||||
addis r4,0,(MPS_AP_B)@h
|
||||
ori r4,r4,(MPS_AP_B)@l
|
||||
mtdcr ebccfgd,r4
|
||||
|
||||
addi r4,0,pb0cr
|
||||
mtdcr ebccfga,r4
|
||||
/* BS=0x011(4MB),BU=0x3(R/W), */
|
||||
addis r4,0,((FLASH_BASE0_PRELIM & 0xFFF00000) | 0x00050000)@h
|
||||
ori r4,r4,0x8000 /* BW=0x0( 8 bits) */
|
||||
mtdcr ebccfgd,r4
|
||||
addi r4,0,pb0cr
|
||||
mtdcr ebccfga,r4
|
||||
/* BS=0x010(4MB),BU=0x3(R/W), */
|
||||
addis r4,0,(MPS_CR_B)@h
|
||||
ori r4,r4,(MPS_CR_B)@l
|
||||
mtdcr ebccfgd,r4
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
* Memory Bank 1 (Flash) initialization
|
||||
*-----------------------------------------------------------------------*/
|
||||
addi r4,0,pb1ap
|
||||
mtdcr ebccfga,r4
|
||||
addis r4,0,0x0281
|
||||
ori r4,r4,0x5480
|
||||
mtdcr ebccfgd,r4
|
||||
|
||||
addi r4,0,pb1cr
|
||||
mtdcr ebccfga,r4
|
||||
/* BS=0x011(8MB),BU=0x3(R/W), */
|
||||
addis r4,0,((MULTI_PURPOSE_SOCKET_ADDR & 0xFFF00000) | 0x00050000)@h
|
||||
ori r4,r4,0xA000 /* BW=0x0( 8 bits) */
|
||||
mtdcr ebccfgd,r4
|
||||
|
||||
1:
|
||||
/*-----------------------------------------------------------------------
|
||||
* Memory Bank 2-3-4-5-6 (not used) initialization
|
||||
*-----------------------------------------------------------------------*/
|
||||
addi r4,0,pb1cr
|
||||
mtdcr ebccfga,r4
|
||||
addis r4,0,0x0000
|
||||
ori r4,r4,0x0000
|
||||
mtdcr ebccfgd,r4
|
||||
|
||||
addi r4,0,pb2cr
|
||||
mtdcr ebccfga,r4
|
||||
addis r4,0,0x0000
|
||||
@@ -182,28 +161,18 @@ ext_bus_cntlr_init:
|
||||
ori r4,r4,0x0000
|
||||
mtdcr ebccfgd,r4
|
||||
|
||||
addi r4,0,pb6cr
|
||||
addi r4,0,pb6cr
|
||||
mtdcr ebccfga,r4
|
||||
addis r4,0,0x0000
|
||||
ori r4,r4,0x0000
|
||||
mtdcr ebccfgd,r4
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
* Memory Bank 7 (Config Register) initialization
|
||||
*----------------------------------------------------------------------- */
|
||||
addi r4,0,pb7ap
|
||||
mtdcr ebccfga,r4
|
||||
addis r4,0,0x0181 /* Doc says TWT=3 and Openios TWT=3!! */
|
||||
ori r4,r4,0x5280 /* disable Ready, BEM=0 */
|
||||
mtdcr ebccfgd,r4
|
||||
|
||||
addi r4,0,pb7cr
|
||||
mtdcr ebccfga,r4
|
||||
/* BS=0x0(1MB),BU=0x3(R/W), */
|
||||
addis r4,0,((CONFIG_PORT_ADDR & 0xFFF00000) | 0x00010000)@h
|
||||
ori r4,r4,0x8000 /* BW=0x0(8 bits) */
|
||||
addis r4,0,0x0000
|
||||
ori r4,r4,0x0000
|
||||
mtdcr ebccfgd,r4
|
||||
nop /* pass2 DCR errata #8 */
|
||||
nop /* pass2 DCR errata #8 */
|
||||
blr
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
@@ -217,3 +186,45 @@ sdram_init:
|
||||
|
||||
|
||||
blr
|
||||
|
||||
|
||||
#if defined(CONFIG_BOOT_PCI)
|
||||
.section .bootpg,"ax"
|
||||
.globl _start_pci
|
||||
/*******************************************
|
||||
*/
|
||||
|
||||
_start_pci:
|
||||
/* first handle errata #68 / PCI_18 */
|
||||
iccci r0, r0 /* invalidate I-cache */
|
||||
lis r31, 0
|
||||
mticcr r31 /* ICCR = 0 (all uncachable) */
|
||||
isync
|
||||
|
||||
mfccr0 r28 /* set CCR0[24] = 1 */
|
||||
ori r28, r28, 0x0080
|
||||
mtccr0 r28
|
||||
|
||||
/* setup PMM0MA (0xEF400004) and PMM0PCIHA (0xEF40000C) */
|
||||
lis r28, 0xEF40
|
||||
addi r28, r28, 0x0004
|
||||
stw r31, 0x0C(r28) /* clear PMM0PCIHA */
|
||||
lis r29, 0xFFF8 /* open 512 kByte */
|
||||
addi r29, r29, 0x0001/* and enable this region */
|
||||
stwbrx r29, r0, r28 /* write PMM0MA */
|
||||
|
||||
lis r28, 0xEEC0 /* address of PCIC0_CFGADDR */
|
||||
addi r29, r28, 4 /* add 4 to r29 -> PCIC0_CFGDATA */
|
||||
|
||||
lis r31, 0x8000 /* set en bit bus 0 */
|
||||
ori r31, r31, 0x304C/* device 6 func 0 reg 4C (XBCS register) */
|
||||
stwbrx r31, r0, r28 /* write it */
|
||||
|
||||
lwbrx r31, r0, r29 /* load XBCS register */
|
||||
oris r31, r31, 0x02C4/* clear BIOSCS WPE, set lower, extended and 1M extended BIOS enable */
|
||||
stwbrx r31, r0, r29 /* write back XBCS register */
|
||||
|
||||
nop
|
||||
nop
|
||||
b _start /* normal start */
|
||||
#endif
|
||||
|
||||
@@ -194,6 +194,11 @@ int board_pre_init (void)
|
||||
#ifdef SDRAM_DEBUG
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
#endif
|
||||
/* set up the config port */
|
||||
mtdcr (ebccfga, pb7ap);
|
||||
mtdcr (ebccfgd, CONFIG_PORT_AP);
|
||||
mtdcr (ebccfga, pb7cr);
|
||||
mtdcr (ebccfgd, CONFIG_PORT_CR);
|
||||
|
||||
memclk = get_bus_freq (tmemclk);
|
||||
tmemclk = 1000000000 / (memclk / 100); /* in 10 ps units */
|
||||
@@ -657,8 +662,20 @@ static int test_dram (unsigned long ramsize)
|
||||
}
|
||||
|
||||
|
||||
extern flash_info_t flash_info[]; /* info for FLASH chips */
|
||||
|
||||
int misc_init_r (void)
|
||||
{
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
/* adjust flash start and size as well as the offset */
|
||||
gd->bd->bi_flashstart=0-flash_info[0].size;
|
||||
gd->bd->bi_flashsize=flash_info[0].size-CFG_MONITOR_LEN;
|
||||
gd->bd->bi_flashoffset=0;
|
||||
|
||||
/* if PIP405 has booted from PCI, reset CCR0[24] as described in errata PCI_18 */
|
||||
if (mfdcr(strap) & PSR_ROM_LOC)
|
||||
mtspr(ccr0, (mfspr(ccr0) & ~0x80));
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
* Global routines used for PIP405
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
extern int mem_test(unsigned long start, unsigned long ramsize,int mode);
|
||||
|
||||
@@ -35,13 +36,13 @@ void user_led1(unsigned char on);
|
||||
|
||||
|
||||
#define PLD_BASE_ADDRESS CFG_ISA_IO_BASE_ADDRESS + 0x800
|
||||
#define PLD_PART_REG PLD_BASE_ADDRESS + 0
|
||||
#define PLD_VERS_REG PLD_BASE_ADDRESS + 1
|
||||
#define PLD_PART_REG PLD_BASE_ADDRESS + 0
|
||||
#define PLD_VERS_REG PLD_BASE_ADDRESS + 1
|
||||
#define PLD_BOARD_CFG_REG PLD_BASE_ADDRESS + 2
|
||||
#define PLD_LED_USER_REG PLD_BASE_ADDRESS + 3
|
||||
#define PLD_SYS_MAN_REG PLD_BASE_ADDRESS + 4
|
||||
#define PLD_FLASH_COM_REG PLD_BASE_ADDRESS + 5
|
||||
#define PLD_CAN_REG PLD_BASE_ADDRESS + 6
|
||||
#define PLD_CAN_REG PLD_BASE_ADDRESS + 6
|
||||
#define PLD_SER_PWR_REG PLD_BASE_ADDRESS + 7
|
||||
#define PLD_COM_PWR_REG PLD_BASE_ADDRESS + 8
|
||||
#define PLD_NIC_VGA_REG PLD_BASE_ADDRESS + 9
|
||||
@@ -50,86 +51,32 @@ void user_led1(unsigned char on);
|
||||
#define PIIX4_VENDOR_ID 0x8086
|
||||
#define PIIX4_IDE_DEV_ID 0x7111
|
||||
|
||||
|
||||
/* timings */
|
||||
/* PLD (CS7) */
|
||||
#define PLD_BME 0 /* Burst disable */
|
||||
#define PLD_TWE 5 /* 5 * 30ns 120ns Waitstates (access=TWT+1+TH) */
|
||||
#define PLD_CSN 1 /* Chipselect is driven inactive for 1 Cycle BTW transfers */
|
||||
#define PLD_OEN 1 /* Cycles from CS low to OE low */
|
||||
#define PLD_WBN 1 /* Cycles from CS low to WE low */
|
||||
#define PLD_WBF 1 /* Cycles from WE high to CS high */
|
||||
#define PLD_TH 2 /* Number of hold cycles after transfer */
|
||||
#define PLD_RE 0 /* Ready disabled */
|
||||
#define PLD_SOR 1 /* Sample on Ready disabled */
|
||||
#define PLD_BEM 0 /* Byte Write only active on Write cycles */
|
||||
#define PLD_PEN 0 /* Parity disable */
|
||||
#define PLD_AP ((PLD_BME << 31) + (PLD_TWE << 23) + (PLD_CSN << 18) + (PLD_OEN << 16) + (PLD_WBN << 14) + \
|
||||
(PLD_WBF << 12) + (PLD_TH << 9) + (PLD_RE << 8) + (PLD_SOR << 7) + (PLD_BEM << 6) + (PLD_PEN << 5))
|
||||
|
||||
/* Size: 0=1MB, 1=2MB, 2=4MB, 3=8MB, 4=16MB, 5=32MB, 6=64MB, 7=128MB */
|
||||
#define PLD_BS 0 /* 1 MByte */
|
||||
/* Usage: 0=disabled, 1=Read only, 2=Write Only, 3=R/W */
|
||||
#define PLD_BU 3 /* R/W */
|
||||
/* Bus width: 0=8Bit, 1=16Bit, 2=32Bit, 3=Reserved */
|
||||
#define PLD_BW 0 /* 16Bit */
|
||||
#define PLD_CR ((PER_PLD_ADDR & 0xfff00000) + (PLD_BS << 17) + (PLD_BU << 15) + (PLD_BW << 13))
|
||||
|
||||
#endif
|
||||
|
||||
/* timings */
|
||||
|
||||
#define PER_BOARD_ADDR (PER_UART1_ADDR+(1024*1024))
|
||||
/* Dummy CS to get the board revision */
|
||||
#define BOARD_BME 0 /* Burst disable */
|
||||
#define BOARD_TWE 255 /* 255 * 30ns 120ns Waitstates (access=TWT+1+TH) */
|
||||
#define BOARD_CSN 1 /* Chipselect is driven inactive for 1 Cycle BTW transfers */
|
||||
#define BOARD_OEN 1 /* Cycles from CS low to OE low */
|
||||
#define BOARD_WBN 1 /* Cycles from CS low to WE low */
|
||||
#define BOARD_WBF 1 /* Cycles from WE high to CS high */
|
||||
#define BOARD_TH 2 /* Number of hold cycles after transfer */
|
||||
#define BOARD_RE 0 /* Ready disabled */
|
||||
#define BOARD_SOR 1 /* Sample on Ready disabled */
|
||||
#define BOARD_BEM 0 /* Byte Write only active on Write cycles */
|
||||
#define BOARD_PEN 0 /* Parity disable */
|
||||
#define BOARD_AP ((BOARD_BME << 31) + (BOARD_TWE << 23) + (BOARD_CSN << 18) + (BOARD_OEN << 16) + (BOARD_WBN << 14) + \
|
||||
(BOARD_WBF << 12) + (BOARD_TH << 9) + (BOARD_RE << 8) + (BOARD_SOR << 7) + (BOARD_BEM << 6) + (BOARD_PEN << 5))
|
||||
/* CS Config register (CS7) */
|
||||
#define CONFIG_PORT_BME 0 /* Burst disable */
|
||||
#define CONFIG_PORT_TWE 255 /* 255 * 30ns 120ns Waitstates (access=TWT+1+TH) */
|
||||
#define CONFIG_PORT_CSN 1 /* Chipselect is driven inactive for 1 Cycle BTW transfers */
|
||||
#define CONFIG_PORT_OEN 1 /* Cycles from CS low to OE low */
|
||||
#define CONFIG_PORT_WBN 1 /* Cycles from CS low to WE low */
|
||||
#define CONFIG_PORT_WBF 1 /* Cycles from WE high to CS high */
|
||||
#define CONFIG_PORT_TH 2 /* Number of hold cycles after transfer */
|
||||
#define CONFIG_PORT_RE 0 /* Ready disabled */
|
||||
#define CONFIG_PORT_SOR 1 /* Sample on Ready disabled */
|
||||
#define CONFIG_PORT_BEM 0 /* Byte Write only active on Write cycles */
|
||||
#define CONFIG_PORT_PEN 0 /* Parity disable */
|
||||
#define CONFIG_PORT_AP ((CONFIG_PORT_BME << 31) + (CONFIG_PORT_TWE << 23) + (CONFIG_PORT_CSN << 18) + (CONFIG_PORT_OEN << 16) + (CONFIG_PORT_WBN << 14) + \
|
||||
(CONFIG_PORT_WBF << 12) + (CONFIG_PORT_TH << 9) + (CONFIG_PORT_RE << 8) + (CONFIG_PORT_SOR << 7) + (CONFIG_PORT_BEM << 6) + (CONFIG_PORT_PEN << 5))
|
||||
|
||||
/* Size: 0=1MB, 1=2MB, 2=4MB, 3=8MB, 4=16MB, 5=32MB, 6=64MB, 7=128MB */
|
||||
#define BOARD_BS 0 /* 1 MByte */
|
||||
#define CONFIG_PORT_BS 0 /* 1 MByte */
|
||||
/* Usage: 0=disabled, 1=Read only, 2=Write Only, 3=R/W */
|
||||
#define BOARD_BU 3 /* R/W */
|
||||
#define CONFIG_PORT_BU 3 /* R/W */
|
||||
/* Bus width: 0=8Bit, 1=16Bit, 2=32Bit, 3=Reserved */
|
||||
#define BOARD_BW 0 /* 16Bit */
|
||||
#define BOARD_CR ((PER_BOARD_ADDR & 0xfff00000) + (BOARD_BS << 17) + (BOARD_BU << 15) + (BOARD_BW << 13))
|
||||
|
||||
|
||||
/* UART0 CS2 */
|
||||
#define UART0_BME 0 /* Burst disable */
|
||||
#define UART0_TWE 7 /* 7 * 30ns 210ns Waitstates (access=TWT+1+TH) */
|
||||
#define UART0_CSN 1 /* Chipselect is driven inactive for 1 Cycle BTW transfers */
|
||||
#define UART0_OEN 1 /* Cycles from CS low to OE low */
|
||||
#define UART0_WBN 1 /* Cycles from CS low to WE low */
|
||||
#define UART0_WBF 1 /* Cycles from WE high to CS high */
|
||||
#define UART0_TH 2 /* Number of hold cycles after transfer */
|
||||
#define UART0_RE 0 /* Ready disabled */
|
||||
#define UART0_SOR 1 /* Sample on Ready disabled */
|
||||
#define UART0_BEM 0 /* Byte Write only active on Write cycles */
|
||||
#define UART0_PEN 0 /* Parity disable */
|
||||
#define UART0_AP ((UART0_BME << 31) + (UART0_TWE << 23) + (UART0_CSN << 18) + (UART0_OEN << 16) + (UART0_WBN << 14) + \
|
||||
(UART0_WBF << 12) + (UART0_TH << 9) + (UART0_RE << 8) + (UART0_SOR << 7) + (UART0_BEM << 6) + (UART0_PEN << 5))
|
||||
|
||||
/* Size: 0=1MB, 1=2MB, 2=4MB, 3=8MB, 4=16MB, 5=32MB, 6=64MB, 7=128MB */
|
||||
#define UART0_BS 0 /* 1 MByte */
|
||||
/* Usage: 0=disabled, 1=Read only, 2=Write Only, 3=R/W */
|
||||
#define UART0_BU 3 /* R/W */
|
||||
/* Bus width: 0=8Bit, 1=16Bit, 2=32Bit, 3=Reserved */
|
||||
#define UART0_BW 0 /* 8Bit */
|
||||
#define UART0_CR ((PER_UART0_ADDR & 0xfff00000) + (UART0_BS << 17) + (UART0_BU << 15) + (UART0_BW << 13))
|
||||
|
||||
/* UART1 CS3 */
|
||||
#define UART1_AP UART0_AP /* same timing as UART0 */
|
||||
#define UART1_CR ((PER_UART1_ADDR & 0xfff00000) + (UART0_BS << 17) + (UART0_BU << 15) + (UART0_BW << 13))
|
||||
|
||||
#define CONFIG_PORT_BW 0 /* 16Bit */
|
||||
#define CONFIG_PORT_CR ((CONFIG_PORT_ADDR & 0xfff00000) + (CONFIG_PORT_BS << 17) + (CONFIG_PORT_BU << 15) + (CONFIG_PORT_BW << 13))
|
||||
|
||||
/* Flash CS0 or CS 1 */
|
||||
/* 0x7F8FFE80 slowest timing at all... */
|
||||
@@ -149,19 +96,19 @@ void user_led1(unsigned char on);
|
||||
#define FLASH_PEN 0 /* Parity disable */
|
||||
/* Access Parameter Register for non Boot */
|
||||
#define FLASH_AP ((FLASH_BME << 31) + (FLASH_TWE << 23) + (FLASH_CSN << 18) + (FLASH_OEN << 16) + (FLASH_WBN << 14) + \
|
||||
(FLASH_WBF << 12) + (FLASH_TH << 9) + (FLASH_RE << 8) + (FLASH_SOR << 7) + (FLASH_BEM << 6) + (FLASH_PEN << 5))
|
||||
(FLASH_WBF << 12) + (FLASH_TH << 9) + (FLASH_RE << 8) + (FLASH_SOR << 7) + (FLASH_BEM << 6) + (FLASH_PEN << 5))
|
||||
/* Access Parameter Register for Boot */
|
||||
#define FLASH_AP_B ((FLASH_BME_B << 31) + (FLASH_FWT_B << 26) + (FLASH_BWT_B << 23) + (FLASH_CSN << 18) + (FLASH_OEN << 16) + (FLASH_WBN << 14) + \
|
||||
(FLASH_WBF << 12) + (FLASH_TH << 9) + (FLASH_RE << 8) + (FLASH_SOR << 7) + (FLASH_BEM << 6) + (FLASH_PEN << 5))
|
||||
(FLASH_WBF << 12) + (FLASH_TH << 9) + (FLASH_RE << 8) + (FLASH_SOR << 7) + (FLASH_BEM << 6) + (FLASH_PEN << 5))
|
||||
|
||||
/* Size: 0=1MB, 1=2MB, 2=4MB, 3=8MB, 4=16MB, 5=32MB, 6=64MB, 7=128MB */
|
||||
#define FLASH_BS 2 /* 4 MByte */
|
||||
#define FLASH_BS FLASH_SIZE_PRELIM /* 4 MByte */
|
||||
/* Usage: 0=disabled, 1=Read only, 2=Write Only, 3=R/W */
|
||||
#define FLASH_BU 3 /* R/W */
|
||||
/* Bus width: 0=8Bit, 1=16Bit, 2=32Bit, 3=Reserved */
|
||||
#define FLASH_BW 1 /* 16Bit */
|
||||
/* CR register for Boot */
|
||||
#define FLASH_CR_B ((FLASH_BASE0_PRELIM & 0xfff00000) + (FLASH_BS << 17) + (FLASH_BU << 15) + (FLASH_BW << 13))
|
||||
#define FLASH_CR_B ((FLASH_BASE_PRELIM & 0xfff00000) + (FLASH_BS << 17) + (FLASH_BU << 15) + (FLASH_BW << 13))
|
||||
/* CR register for non Boot */
|
||||
#define FLASH_CR ((MULTI_PURPOSE_SOCKET_ADDR & 0xfff00000) + (FLASH_BS << 17) + (FLASH_BU << 15) + (FLASH_BW << 13))
|
||||
|
||||
@@ -183,18 +130,19 @@ void user_led1(unsigned char on);
|
||||
#define MPS_PEN 0 /* Parity disable */
|
||||
/* Access Parameter Register for non Boot */
|
||||
#define MPS_AP ((MPS_BME << 31) + (MPS_TWE << 23) + (MPS_CSN << 18) + (MPS_OEN << 16) + (MPS_WBN << 14) + \
|
||||
(MPS_WBF << 12) + (MPS_TH << 9) + (MPS_RE << 8) + (MPS_SOR << 7) + (MPS_BEM << 6) + (MPS_PEN << 5))
|
||||
(MPS_WBF << 12) + (MPS_TH << 9) + (MPS_RE << 8) + (MPS_SOR << 7) + (MPS_BEM << 6) + (MPS_PEN << 5))
|
||||
/* Access Parameter Register for Boot */
|
||||
#define MPS_AP_B ((MPS_BME_B << 31) + (MPS_FWT_B << 26) + (MPS_BWT_B << 23) + (MPS_CSN << 18) + (MPS_OEN << 16) + (MPS_WBN << 14) + \
|
||||
(MPS_WBF << 12) + (MPS_TH << 9) + (MPS_RE << 8) + (MPS_SOR << 7) + (MPS_BEM << 6) + (MPS_PEN << 5))
|
||||
#define MPS_AP_B ((MPS_BME_B << 31) + (MPS_FWT_B << 26) + (MPS_BWT_B << 23) + (MPS_CSN << 18) + (MPS_OEN << 16) + (MPS_WBN << 14) + \
|
||||
(MPS_WBF << 12) + (MPS_TH << 9) + (MPS_RE << 8) + (MPS_SOR << 7) + (MPS_BEM << 6) + (MPS_PEN << 5))
|
||||
|
||||
/* Size: 0=1MB, 1=2MB, 2=4MB, 3=8MB, 4=16MB, 5=32MB, 6=64MB, 7=128MB */
|
||||
#define MPS_BS 2 /* 4 MByte */
|
||||
#define MPS_BS_B FLASH_SIZE_PRELIM /* 1 MByte */
|
||||
/* Usage: 0=disabled, 1=Read only, 2=Write Only, 3=R/W */
|
||||
#define MPS_BU 3 /* R/W */
|
||||
/* Bus width: 0=8Bit, 1=16Bit, 2=32Bit, 3=Reserved */
|
||||
#define MPS_BW 0 /* 8Bit */
|
||||
/* CR register for Boot */
|
||||
#define MPS_CR_B ((FLASH_BASE0_PRELIM & 0xfff00000) + (MPS_BS << 17) + (MPS_BU << 15) + (MPS_BW << 13))
|
||||
#define MPS_CR_B ((FLASH_BASE_PRELIM & 0xfff00000) + (MPS_BS << 17) + (MPS_BU << 15) + (MPS_BW << 13))
|
||||
/* CR register for non Boot */
|
||||
#define MPS_CR ((MULTI_PURPOSE_SOCKET_ADDR & 0xfff00000) + (MPS_BS << 17) + (MPS_BU << 15) + (MPS_BW << 13))
|
||||
|
||||
@@ -144,7 +144,7 @@ int dram_init(void)
|
||||
* NAND flash initialization.
|
||||
*/
|
||||
#if (CONFIG_COMMANDS & CFG_CMD_NAND)
|
||||
extern void
|
||||
extern ulong
|
||||
nand_probe(ulong physadr);
|
||||
|
||||
|
||||
@@ -177,10 +177,15 @@ void
|
||||
nand_init(void)
|
||||
{
|
||||
S3C2410_NAND * const nand = S3C2410_GetBase_NAND();
|
||||
unsigned totlen;
|
||||
|
||||
NF_Init();
|
||||
#ifdef DEBUG
|
||||
printf("NAND flash probing at 0x%.8lX\n", (ulong)nand);
|
||||
nand_probe((ulong)nand);
|
||||
#endif
|
||||
totlen = nand_probe((ulong)nand) >> 20;
|
||||
|
||||
printf ("%4lu MB\n", totlen >> 20);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -420,16 +420,13 @@ int board_pre_init(void)
|
||||
|
||||
#include <linux/mtd/nand.h>
|
||||
|
||||
extern void nand_probe(ulong physadr);
|
||||
extern ulong nand_probe(ulong physadr);
|
||||
extern struct nand_chip nand_dev_desc[CFG_MAX_NAND_DEVICE];
|
||||
|
||||
void nand_init(void)
|
||||
{
|
||||
nand_probe(CFG_NAND_BASE);
|
||||
if (nand_dev_desc[0].ChipID != NAND_ChipID_UNKNOWN) {
|
||||
nand_dev_desc[0].name = "NetVia NAND flash";
|
||||
puts("NAND: ");
|
||||
print_size(nand_dev_desc[0].totlen, "\n");
|
||||
}
|
||||
unsigned long totlen = nand_probe(CFG_NAND_BASE);
|
||||
|
||||
printf ("%4lu MB\n", totlen >> 20);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -84,6 +84,9 @@ platformsetup:
|
||||
ldr r0, REG_FUNC_MUX_CTRL_C
|
||||
ldr r1, VAL_FUNC_MUX_CTRL_C
|
||||
str r1, [r0]
|
||||
ldr r0, REG_FUNC_MUX_CTRL_D
|
||||
ldr r1, VAL_FUNC_MUX_CTRL_D
|
||||
str r1, [r0]
|
||||
ldr r0, REG_VOLTAGE_CTRL_0
|
||||
ldr r1, VAL_VOLTAGE_CTRL_0
|
||||
str r1, [r0]
|
||||
@@ -352,9 +355,9 @@ VAL_PULL_DWN_CTRL_0:
|
||||
VAL_PULL_DWN_CTRL_1:
|
||||
.word 0x2e047fff
|
||||
VAL_PULL_DWN_CTRL_2:
|
||||
.word 0xffd7d3e6
|
||||
.word 0xffd603a6
|
||||
VAL_PULL_DWN_CTRL_3:
|
||||
.word 0x00003f03
|
||||
.word 0x00003e03
|
||||
VAL_VOLTAGE_CTRL_0:
|
||||
.word 0x00000007
|
||||
VAL_TEST_DBG_CTRL_0:
|
||||
|
||||
47
board/omap1610inn/Makefile
Normal file
47
board/omap1610inn/Makefile
Normal file
@@ -0,0 +1,47 @@
|
||||
#
|
||||
# (C) Copyright 2000, 2001, 2002
|
||||
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
#
|
||||
# See file CREDITS for list of people who contributed to this
|
||||
# project.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License as
|
||||
# published by the Free Software Foundation; either version 2 of
|
||||
# the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
# MA 02111-1307 USA
|
||||
#
|
||||
|
||||
include $(TOPDIR)/config.mk
|
||||
|
||||
LIB = lib$(BOARD).a
|
||||
|
||||
OBJS := omap1610innovator.o flash.o
|
||||
SOBJS := platform.o
|
||||
|
||||
$(LIB): $(OBJS) $(SOBJS)
|
||||
$(AR) crv $@ $^
|
||||
|
||||
clean:
|
||||
rm -f $(SOBJS) $(OBJS)
|
||||
|
||||
distclean: clean
|
||||
rm -f $(LIB) core *.bak .depend
|
||||
|
||||
#########################################################################
|
||||
|
||||
.depend: Makefile $(SOBJS:.o=.S) $(OBJS:.o=.c)
|
||||
$(CC) -M $(CPPFLAGS) $(SOBJS:.o=.S) $(OBJS:.o=.c) > $@
|
||||
|
||||
-include .depend
|
||||
|
||||
#########################################################################
|
||||
26
board/omap1610inn/config.mk
Normal file
26
board/omap1610inn/config.mk
Normal file
@@ -0,0 +1,26 @@
|
||||
#
|
||||
# (C) Copyright 2002
|
||||
# Gary Jennejohn, DENX Software Engineering, <gj@denx.de>
|
||||
# David Mueller, ELSOFT AG, <d.mueller@elsoft.ch>
|
||||
#
|
||||
# (C) Copyright 2003
|
||||
# Texas Instruments, <www.ti.com>
|
||||
# Kshitij Gupta <Kshitij@ti.com>
|
||||
#
|
||||
# TI Innovator board with OMAP1610 (ARM925EJS) cpu
|
||||
# see http://www.ti.com/ for more information on Texas Instruments
|
||||
#
|
||||
# Innovator has 1 bank of 256 MB SDRAM
|
||||
# Physical Address:
|
||||
# 1000'0000 to 2000'0000
|
||||
#
|
||||
#
|
||||
# Linux-Kernel is expected to be at 1000'8000, entry 1000'8000
|
||||
# (mem base + reserved)
|
||||
#
|
||||
# we load ourself to 1100'0000
|
||||
#
|
||||
#
|
||||
|
||||
|
||||
TEXT_BASE = 0x11000000
|
||||
482
board/omap1610inn/flash.c
Normal file
482
board/omap1610inn/flash.c
Normal file
@@ -0,0 +1,482 @@
|
||||
/*
|
||||
* (C) Copyright 2001
|
||||
* Kyle Harris, Nexus Technologies, Inc. kharris@nexus-tech.net
|
||||
*
|
||||
* (C) Copyright 2001
|
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
*
|
||||
* (C) Copyright 2003
|
||||
* Texas Instruments, <www.ti.com>
|
||||
* Kshitij Gupta <Kshitij@ti.com>
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <linux/byteorder/swab.h>
|
||||
|
||||
#define PHYS_FLASH_SECT_SIZE 0x00020000 /* 256 KB sectors (x2) */
|
||||
flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */
|
||||
|
||||
/* Board support for 1 or 2 flash devices */
|
||||
#undef FLASH_PORT_WIDTH32
|
||||
#define FLASH_PORT_WIDTH16
|
||||
|
||||
#ifdef FLASH_PORT_WIDTH16
|
||||
#define FLASH_PORT_WIDTH ushort
|
||||
#define FLASH_PORT_WIDTHV vu_short
|
||||
#define SWAP(x) __swab16(x)
|
||||
#else
|
||||
#define FLASH_PORT_WIDTH ulong
|
||||
#define FLASH_PORT_WIDTHV vu_long
|
||||
#define SWAP(x) __swab32(x)
|
||||
#endif
|
||||
|
||||
#define FPW FLASH_PORT_WIDTH
|
||||
#define FPWV FLASH_PORT_WIDTHV
|
||||
|
||||
#define mb() __asm__ __volatile__ ("" : : : "memory")
|
||||
|
||||
|
||||
|
||||
/* Flash Organization Structure */
|
||||
typedef struct OrgDef {
|
||||
unsigned int sector_number;
|
||||
unsigned int sector_size;
|
||||
} OrgDef;
|
||||
|
||||
|
||||
/* Flash Organizations */
|
||||
OrgDef OrgIntel_28F256L18T[] = {
|
||||
{4, 32 * 1024}, /* 4 * 32kBytes sectors */
|
||||
{255, 128 * 1024}, /* 255 * 128kBytes sectors */
|
||||
};
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
* Functions
|
||||
*/
|
||||
unsigned long flash_init (void);
|
||||
static ulong flash_get_size (FPW * addr, flash_info_t * info);
|
||||
static int write_data (flash_info_t * info, ulong dest, FPW data);
|
||||
static void flash_get_offsets (ulong base, flash_info_t * info);
|
||||
void inline spin_wheel (void);
|
||||
void flash_print_info (flash_info_t * info);
|
||||
void flash_unprotect_sectors (FPWV * addr);
|
||||
int flash_erase (flash_info_t * info, int s_first, int s_last);
|
||||
int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt);
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
unsigned long flash_init (void)
|
||||
{
|
||||
int i;
|
||||
ulong size = 0;
|
||||
for (i = 0; i < CFG_MAX_FLASH_BANKS; i++) {
|
||||
switch (i) {
|
||||
case 0:
|
||||
flash_get_size ((FPW *) PHYS_FLASH_1, &flash_info[i]);
|
||||
flash_get_offsets (PHYS_FLASH_1, &flash_info[i]);
|
||||
break;
|
||||
default:
|
||||
panic ("configured to many flash banks!\n");
|
||||
break;
|
||||
}
|
||||
size += flash_info[i].size;
|
||||
}
|
||||
|
||||
/* Protect monitor and environment sectors
|
||||
*/
|
||||
flash_protect (FLAG_PROTECT_SET,
|
||||
CFG_FLASH_BASE,
|
||||
CFG_FLASH_BASE + monitor_flash_len - 1, &flash_info[0]);
|
||||
|
||||
flash_protect (FLAG_PROTECT_SET,
|
||||
CFG_ENV_ADDR,
|
||||
CFG_ENV_ADDR + CFG_ENV_SIZE - 1, &flash_info[0]);
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
*/
|
||||
static void flash_get_offsets (ulong base, flash_info_t * info)
|
||||
{
|
||||
int i;
|
||||
OrgDef *pOrgDef;
|
||||
|
||||
pOrgDef = OrgIntel_28F256L18T;
|
||||
if (info->flash_id == FLASH_UNKNOWN) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL) {
|
||||
for (i = 0; i < info->sector_count; i++) {
|
||||
if (i > 255) {
|
||||
info->start[i] = base + (i * 0x8000);
|
||||
info->protect[i] = 0;
|
||||
} else {
|
||||
info->start[i] = base +
|
||||
(i * PHYS_FLASH_SECT_SIZE);
|
||||
info->protect[i] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
*/
|
||||
void flash_print_info (flash_info_t * info)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (info->flash_id == FLASH_UNKNOWN) {
|
||||
printf ("missing or unknown FLASH type\n");
|
||||
return;
|
||||
}
|
||||
|
||||
switch (info->flash_id & FLASH_VENDMASK) {
|
||||
case FLASH_MAN_INTEL:
|
||||
printf ("INTEL ");
|
||||
break;
|
||||
default:
|
||||
printf ("Unknown Vendor ");
|
||||
break;
|
||||
}
|
||||
|
||||
switch (info->flash_id & FLASH_TYPEMASK) {
|
||||
case FLASH_28F256L18T:
|
||||
printf ("FLASH 28F256L18T\n");
|
||||
break;
|
||||
default:
|
||||
printf ("Unknown Chip Type\n");
|
||||
break;
|
||||
}
|
||||
|
||||
printf (" Size: %ld MB in %d Sectors\n",
|
||||
info->size >> 20, info->sector_count);
|
||||
|
||||
printf (" Sector Start Addresses:");
|
||||
for (i = 0; i < info->sector_count; ++i) {
|
||||
if ((i % 5) == 0)
|
||||
printf ("\n ");
|
||||
printf (" %08lX%s",
|
||||
info->start[i], info->protect[i] ? " (RO)" : " ");
|
||||
}
|
||||
printf ("\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* The following code cannot be run from FLASH!
|
||||
*/
|
||||
static ulong flash_get_size (FPW * addr, flash_info_t * info)
|
||||
{
|
||||
volatile FPW value;
|
||||
|
||||
/* Write auto select command: read Manufacturer ID */
|
||||
addr[0x5555] = (FPW) 0x00AA00AA;
|
||||
addr[0x2AAA] = (FPW) 0x00550055;
|
||||
addr[0x5555] = (FPW) 0x00900090;
|
||||
|
||||
mb ();
|
||||
value = addr[0];
|
||||
|
||||
switch (value) {
|
||||
|
||||
case (FPW) INTEL_MANUFACT:
|
||||
info->flash_id = FLASH_MAN_INTEL;
|
||||
break;
|
||||
|
||||
default:
|
||||
info->flash_id = FLASH_UNKNOWN;
|
||||
info->sector_count = 0;
|
||||
info->size = 0;
|
||||
addr[0] = (FPW) 0x00FF00FF; /* restore read mode */
|
||||
return (0); /* no or unknown flash */
|
||||
}
|
||||
|
||||
mb ();
|
||||
value = addr[1]; /* device ID */
|
||||
switch (value) {
|
||||
|
||||
case (FPW) (INTEL_ID_28F256L18T):
|
||||
info->flash_id += FLASH_28F256L18T;
|
||||
info->sector_count = 259;
|
||||
info->size = 0x02000000;
|
||||
break; /* => 32 MB */
|
||||
|
||||
default:
|
||||
info->flash_id = FLASH_UNKNOWN;
|
||||
break;
|
||||
}
|
||||
|
||||
if (info->sector_count > CFG_MAX_FLASH_SECT) {
|
||||
printf ("** ERROR: sector count %d > max (%d) **\n",
|
||||
info->sector_count, CFG_MAX_FLASH_SECT);
|
||||
info->sector_count = CFG_MAX_FLASH_SECT;
|
||||
}
|
||||
|
||||
addr[0] = (FPW) 0x00FF00FF; /* restore read mode */
|
||||
|
||||
return (info->size);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* unprotects a sector for write and erase
|
||||
* on some intel parts, this unprotects the entire chip, but it
|
||||
* wont hurt to call this additional times per sector...
|
||||
*/
|
||||
void flash_unprotect_sectors (FPWV * addr)
|
||||
{
|
||||
#define PD_FINTEL_WSMS_READY_MASK 0x0080
|
||||
|
||||
*addr = (FPW) 0x00500050; /* clear status register */
|
||||
|
||||
/* this sends the clear lock bit command */
|
||||
*addr = (FPW) 0x00600060;
|
||||
*addr = (FPW) 0x00D000D0;
|
||||
}
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
int flash_erase (flash_info_t * info, int s_first, int s_last)
|
||||
{
|
||||
int flag, prot, sect;
|
||||
ulong type, start, last;
|
||||
int rcode = 0;
|
||||
|
||||
if ((s_first < 0) || (s_first > s_last)) {
|
||||
if (info->flash_id == FLASH_UNKNOWN) {
|
||||
printf ("- missing\n");
|
||||
} else {
|
||||
printf ("- no sectors to erase\n");
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
type = (info->flash_id & FLASH_VENDMASK);
|
||||
if ((type != FLASH_MAN_INTEL)) {
|
||||
printf ("Can't erase unknown flash type %08lx - aborted\n",
|
||||
info->flash_id);
|
||||
return 1;
|
||||
}
|
||||
|
||||
prot = 0;
|
||||
for (sect = s_first; sect <= s_last; ++sect) {
|
||||
if (info->protect[sect]) {
|
||||
prot++;
|
||||
}
|
||||
}
|
||||
|
||||
if (prot) {
|
||||
printf ("- Warning: %d protected sectors will not be erased!\n",
|
||||
prot);
|
||||
} else {
|
||||
printf ("\n");
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
start = get_timer (0);
|
||||
last = start;
|
||||
|
||||
/* Disable interrupts which might cause a timeout here */
|
||||
flag = disable_interrupts ();
|
||||
|
||||
/* Start erase on unprotected sectors */
|
||||
for (sect = s_first; sect <= s_last; sect++) {
|
||||
if (info->protect[sect] == 0) { /* not protected */
|
||||
FPWV *addr = (FPWV *) (info->start[sect]);
|
||||
FPW status;
|
||||
|
||||
printf ("Erasing sector %2d ... ", sect);
|
||||
|
||||
flash_unprotect_sectors (addr);
|
||||
|
||||
/* arm simple, non interrupt dependent timer */
|
||||
reset_timer_masked ();
|
||||
|
||||
*addr = (FPW) 0x00500050;/* clear status register */
|
||||
*addr = (FPW) 0x00200020;/* erase setup */
|
||||
*addr = (FPW) 0x00D000D0;/* erase confirm */
|
||||
|
||||
while (((status =
|
||||
*addr) & (FPW) 0x00800080) !=
|
||||
(FPW) 0x00800080) {
|
||||
if (get_timer_masked () >
|
||||
CFG_FLASH_ERASE_TOUT) {
|
||||
printf ("Timeout\n");
|
||||
/* suspend erase */
|
||||
*addr = (FPW) 0x00B000B0;
|
||||
/* reset to read mode */
|
||||
*addr = (FPW) 0x00FF00FF;
|
||||
rcode = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* clear status register cmd. */
|
||||
*addr = (FPW) 0x00500050;
|
||||
*addr = (FPW) 0x00FF00FF;/* resest to read mode */
|
||||
printf (" done\n");
|
||||
}
|
||||
}
|
||||
return rcode;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
* Copy memory to flash, returns:
|
||||
* 0 - OK
|
||||
* 1 - write timeout
|
||||
* 2 - Flash not erased
|
||||
* 4 - Flash not identified
|
||||
*/
|
||||
|
||||
int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt)
|
||||
{
|
||||
ulong cp, wp;
|
||||
FPW data;
|
||||
int count, i, l, rc, port_width;
|
||||
|
||||
if (info->flash_id == FLASH_UNKNOWN) {
|
||||
return 4;
|
||||
}
|
||||
/* get lower word aligned address */
|
||||
#ifdef FLASH_PORT_WIDTH16
|
||||
wp = (addr & ~1);
|
||||
port_width = 2;
|
||||
#else
|
||||
wp = (addr & ~3);
|
||||
port_width = 4;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* handle unaligned start bytes
|
||||
*/
|
||||
if ((l = addr - wp) != 0) {
|
||||
data = 0;
|
||||
for (i = 0, cp = wp; i < l; ++i, ++cp) {
|
||||
data = (data << 8) | (*(uchar *) cp);
|
||||
}
|
||||
for (; i < port_width && cnt > 0; ++i) {
|
||||
data = (data << 8) | *src++;
|
||||
--cnt;
|
||||
++cp;
|
||||
}
|
||||
for (; cnt == 0 && i < port_width; ++i, ++cp) {
|
||||
data = (data << 8) | (*(uchar *) cp);
|
||||
}
|
||||
|
||||
if ((rc = write_data (info, wp, SWAP (data))) != 0) {
|
||||
return (rc);
|
||||
}
|
||||
wp += port_width;
|
||||
}
|
||||
|
||||
/*
|
||||
* handle word aligned part
|
||||
*/
|
||||
count = 0;
|
||||
while (cnt >= port_width) {
|
||||
data = 0;
|
||||
for (i = 0; i < port_width; ++i) {
|
||||
data = (data << 8) | *src++;
|
||||
}
|
||||
if ((rc = write_data (info, wp, SWAP (data))) != 0) {
|
||||
return (rc);
|
||||
}
|
||||
wp += port_width;
|
||||
cnt -= port_width;
|
||||
if (count++ > 0x800) {
|
||||
spin_wheel ();
|
||||
count = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (cnt == 0) {
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* handle unaligned tail bytes
|
||||
*/
|
||||
data = 0;
|
||||
for (i = 0, cp = wp; i < port_width && cnt > 0; ++i, ++cp) {
|
||||
data = (data << 8) | *src++;
|
||||
--cnt;
|
||||
}
|
||||
for (; i < port_width; ++i, ++cp) {
|
||||
data = (data << 8) | (*(uchar *) cp);
|
||||
}
|
||||
|
||||
return (write_data (info, wp, SWAP (data)));
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
* Write a word or halfword to Flash, returns:
|
||||
* 0 - OK
|
||||
* 1 - write timeout
|
||||
* 2 - Flash not erased
|
||||
*/
|
||||
static int write_data (flash_info_t * info, ulong dest, FPW data)
|
||||
{
|
||||
FPWV *addr = (FPWV *) dest;
|
||||
ulong status;
|
||||
int flag;
|
||||
|
||||
/* Check if Flash is (sufficiently) erased */
|
||||
if ((*addr & data) != data) {
|
||||
printf ("not erased at %08lx (%x)\n", (ulong) addr, *addr);
|
||||
return (2);
|
||||
}
|
||||
flash_unprotect_sectors (addr);
|
||||
/* Disable interrupts which might cause a timeout here */
|
||||
flag = disable_interrupts ();
|
||||
*addr = (FPW) 0x00400040; /* write setup */
|
||||
*addr = data;
|
||||
|
||||
/* arm simple, non interrupt dependent timer */
|
||||
reset_timer_masked ();
|
||||
|
||||
/* wait while polling the status register */
|
||||
while (((status = *addr) & (FPW) 0x00800080) != (FPW) 0x00800080) {
|
||||
if (get_timer_masked () > CFG_FLASH_WRITE_TOUT) {
|
||||
*addr = (FPW) 0x00FF00FF; /* restore read mode */
|
||||
return (1);
|
||||
}
|
||||
}
|
||||
*addr = (FPW) 0x00FF00FF; /* restore read mode */
|
||||
return (0);
|
||||
}
|
||||
|
||||
void inline spin_wheel (void)
|
||||
{
|
||||
static int p = 0;
|
||||
static char w[] = "\\/-";
|
||||
|
||||
printf ("\010%c", w[p]);
|
||||
(++p == 3) ? (p = 0) : 0;
|
||||
}
|
||||
270
board/omap1610inn/omap1610innovator.c
Normal file
270
board/omap1610inn/omap1610innovator.c
Normal file
@@ -0,0 +1,270 @@
|
||||
/*
|
||||
* (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>
|
||||
*
|
||||
* (C) Copyright 2003
|
||||
* Texas Instruments, <www.ti.com>
|
||||
* Kshitij Gupta <Kshitij@ti.com>
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#if defined(CONFIG_OMAP1610)
|
||||
#include <./configs/omap1510.h>
|
||||
#endif
|
||||
|
||||
void flash__init (void);
|
||||
void ether__init (void);
|
||||
void set_muxconf_regs (void);
|
||||
void peripheral_power_enable (void);
|
||||
|
||||
#define COMP_MODE_ENABLE ((unsigned int)0x0000EAEF)
|
||||
|
||||
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;
|
||||
|
||||
/* arch number of OMAP 1510-Board */
|
||||
/* to be changed for OMAP 1610 Board */
|
||||
gd->bd->bi_arch_number = 234;
|
||||
|
||||
/* adress of boot parameters */
|
||||
gd->bd->bi_boot_params = 0x10000100;
|
||||
|
||||
/* Configure MUX settings */
|
||||
set_muxconf_regs ();
|
||||
peripheral_power_enable ();
|
||||
|
||||
/* this speeds up your boot a quite a bit. However to make it
|
||||
* work, you need make sure your kernel startup flush bug is fixed.
|
||||
* ... rkw ...
|
||||
*/
|
||||
icache_enable ();
|
||||
|
||||
flash__init ();
|
||||
ether__init ();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int misc_init_r (void)
|
||||
{
|
||||
/* currently empty */
|
||||
return (0);
|
||||
}
|
||||
|
||||
/******************************
|
||||
Routine:
|
||||
Description:
|
||||
******************************/
|
||||
void flash__init (void)
|
||||
{
|
||||
#define EMIFS_GlB_Config_REG 0xfffecc0c
|
||||
unsigned int regval;
|
||||
regval = *((volatile unsigned int *) EMIFS_GlB_Config_REG);
|
||||
/* Turn off write protection for flash devices. */
|
||||
regval = regval | 0x0001;
|
||||
*((volatile unsigned int *) EMIFS_GlB_Config_REG) = regval;
|
||||
}
|
||||
/*************************************************************
|
||||
Routine:ether__init
|
||||
Description: take the Ethernet controller out of reset and wait
|
||||
for the EEPROM load to complete.
|
||||
*************************************************************/
|
||||
void ether__init (void)
|
||||
{
|
||||
#define ETH_CONTROL_REG 0x0400000b
|
||||
|
||||
*((volatile unsigned char *) ETH_CONTROL_REG) &= ~0x01;
|
||||
udelay (3);
|
||||
}
|
||||
|
||||
/******************************
|
||||
Routine:
|
||||
Description:
|
||||
******************************/
|
||||
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;
|
||||
}
|
||||
|
||||
/******************************************************
|
||||
Routine: set_muxconf_regs
|
||||
Description: Setting up the configuration Mux registers
|
||||
specific to the hardware
|
||||
*******************************************************/
|
||||
void set_muxconf_regs (void)
|
||||
{
|
||||
volatile unsigned int *MuxConfReg;
|
||||
/* set each registers to its reset value; */
|
||||
MuxConfReg =
|
||||
(volatile unsigned int *) ((unsigned int) FUNC_MUX_CTRL_0);
|
||||
/* setup for UART1 */
|
||||
*MuxConfReg &= ~(0x02000000); /* bit 25 */
|
||||
/* setup for UART2 */
|
||||
*MuxConfReg &= ~(0x01000000); /* bit 24 */
|
||||
/* Disable Uwire CS Hi-Z */
|
||||
*MuxConfReg |= 0x08000000;
|
||||
MuxConfReg =
|
||||
(volatile unsigned int *) ((unsigned int) FUNC_MUX_CTRL_3);
|
||||
*MuxConfReg = 0x00000000;
|
||||
MuxConfReg =
|
||||
(volatile unsigned int *) ((unsigned int) FUNC_MUX_CTRL_4);
|
||||
*MuxConfReg = 0x00000000;
|
||||
MuxConfReg =
|
||||
(volatile unsigned int *) ((unsigned int) FUNC_MUX_CTRL_5);
|
||||
*MuxConfReg = 0x00000000;
|
||||
MuxConfReg =
|
||||
(volatile unsigned int *) ((unsigned int) FUNC_MUX_CTRL_6);
|
||||
/*setup mux for UART3 */
|
||||
*MuxConfReg |= 0x00000001; /* bit3, 1, 0 (mux0 5,5,26) */
|
||||
*MuxConfReg &= ~0x0000003e;
|
||||
MuxConfReg =
|
||||
(volatile unsigned int *) ((unsigned int) FUNC_MUX_CTRL_7);
|
||||
*MuxConfReg = 0x00000000;
|
||||
MuxConfReg =
|
||||
(volatile unsigned int *) ((unsigned int) FUNC_MUX_CTRL_8);
|
||||
/* Disable Uwire CS Hi-Z */
|
||||
*MuxConfReg |= 0x00001200; /*bit 9 for CS0 12 for CS3 */
|
||||
MuxConfReg =
|
||||
(volatile unsigned int *) ((unsigned int) FUNC_MUX_CTRL_9);
|
||||
/* Need to turn on bits 21 and 12 in FUNC_MUX_CTRL_9 so the */
|
||||
/* hardware will actually use TX and RTS based on bit 25 in */
|
||||
/* FUNC_MUX_CTRL_0. I told you this thing was screwy! */
|
||||
*MuxConfReg |= 0x00201000;
|
||||
MuxConfReg =
|
||||
(volatile unsigned int *) ((unsigned int) FUNC_MUX_CTRL_A);
|
||||
*MuxConfReg = 0x00000000;
|
||||
MuxConfReg =
|
||||
(volatile unsigned int *) ((unsigned int) FUNC_MUX_CTRL_B);
|
||||
*MuxConfReg = 0x00000000;
|
||||
MuxConfReg =
|
||||
(volatile unsigned int *) ((unsigned int) FUNC_MUX_CTRL_C);
|
||||
/* setup for UART2 */
|
||||
/* Need to turn on bits 27 and 24 in FUNC_MUX_CTRL_C so the */
|
||||
/* hardware will actually use TX and RTS based on bit 24 in */
|
||||
/* FUNC_MUX_CTRL_0. */
|
||||
*MuxConfReg |= 0x09000000;
|
||||
MuxConfReg =
|
||||
(volatile unsigned int *) ((unsigned int) PULL_DWN_CTRL_0);
|
||||
*MuxConfReg = 0x00000000;
|
||||
MuxConfReg =
|
||||
(volatile unsigned int *) ((unsigned int) PULL_DWN_CTRL_1);
|
||||
*MuxConfReg = 0x00000000;
|
||||
/* mux setup for SD/MMC driver */
|
||||
MuxConfReg =
|
||||
(volatile unsigned int *) ((unsigned int) PULL_DWN_CTRL_2);
|
||||
*MuxConfReg &= 0xFFFE0FFF;
|
||||
MuxConfReg =
|
||||
(volatile unsigned int *) ((unsigned int) PULL_DWN_CTRL_3);
|
||||
*MuxConfReg = 0x00000000;
|
||||
MuxConfReg =
|
||||
(volatile unsigned int *) ((unsigned int) MOD_CONF_CTRL_0);
|
||||
/* bit 13 for MMC2 XOR_CLK */
|
||||
*MuxConfReg &= ~(0x00002000);
|
||||
/* bit 29 for UART 1 */
|
||||
*MuxConfReg &= ~(0x00002000);
|
||||
MuxConfReg =
|
||||
(volatile unsigned int *) ((unsigned int) FUNC_MUX_CTRL_0);
|
||||
/* Configure for USB. Turn on VBUS_CTRL and VBUS_MODE. */
|
||||
*MuxConfReg |= 0x000C0000;
|
||||
MuxConfReg =
|
||||
(volatile unsigned int *) ((unsigned int)USB_TRANSCEIVER_CTRL);
|
||||
*MuxConfReg &= ~(0x00000070);
|
||||
*MuxConfReg &= ~(0x00000008);
|
||||
*MuxConfReg |= 0x00000003;
|
||||
*MuxConfReg |= 0x00000180;
|
||||
MuxConfReg =
|
||||
(volatile unsigned int *) ((unsigned int) MOD_CONF_CTRL_0);
|
||||
/* bit 17, software controls VBUS */
|
||||
*MuxConfReg &= ~(0x00020000);
|
||||
/* Enable USB 48 and 12M clocks */
|
||||
*MuxConfReg |= 0x00000200;
|
||||
*MuxConfReg &= ~(0x00000180);
|
||||
/*2.75V for MMCSDIO1 */
|
||||
MuxConfReg =
|
||||
(volatile unsigned int *) ((unsigned int) VOLTAGE_CTRL_0);
|
||||
*MuxConfReg = 0x00001FE7;
|
||||
MuxConfReg =
|
||||
(volatile unsigned int *) ((unsigned int) PU_PD_SEL_0);
|
||||
*MuxConfReg = 0x00000000;
|
||||
MuxConfReg =
|
||||
(volatile unsigned int *) ((unsigned int) PU_PD_SEL_1);
|
||||
*MuxConfReg = 0x00000000;
|
||||
MuxConfReg =
|
||||
(volatile unsigned int *) ((unsigned int) PU_PD_SEL_2);
|
||||
*MuxConfReg = 0x00000000;
|
||||
MuxConfReg =
|
||||
(volatile unsigned int *) ((unsigned int) PU_PD_SEL_3);
|
||||
*MuxConfReg = 0x00000000;
|
||||
MuxConfReg =
|
||||
(volatile unsigned int *) ((unsigned int) PU_PD_SEL_4);
|
||||
*MuxConfReg = 0x00000000;
|
||||
MuxConfReg =
|
||||
(volatile unsigned int *) ((unsigned int) PULL_DWN_CTRL_4);
|
||||
*MuxConfReg = 0x00000000;
|
||||
/* Turn on UART2 48 MHZ clock */
|
||||
MuxConfReg =
|
||||
(volatile unsigned int *) ((unsigned int) MOD_CONF_CTRL_0);
|
||||
*MuxConfReg |= 0x40000000;
|
||||
MuxConfReg =
|
||||
(volatile unsigned int *) ((unsigned int) USB_OTG_CTRL);
|
||||
/* setup for USB VBus detection OMAP161x */
|
||||
*MuxConfReg |= 0x00040000; /* bit 18 */
|
||||
MuxConfReg =
|
||||
(volatile unsigned int *) ((unsigned int) PU_PD_SEL_2);
|
||||
/* PullUps for SD/MMC driver */
|
||||
*MuxConfReg |= ~(0xFFFE0FFF);
|
||||
MuxConfReg =
|
||||
(volatile unsigned int *) ((unsigned int)COMP_MODE_CTRL_0);
|
||||
*MuxConfReg = COMP_MODE_ENABLE;
|
||||
}
|
||||
|
||||
/******************************************************
|
||||
Routine: peripheral_power_enable
|
||||
Description: Enable the power for UART1
|
||||
*******************************************************/
|
||||
void peripheral_power_enable (void)
|
||||
{
|
||||
#define UART1_48MHZ_ENABLE ((unsigned short)0x0200)
|
||||
#define SW_CLOCK_REQUEST ((volatile unsigned short *)0xFFFE0834)
|
||||
|
||||
*SW_CLOCK_REQUEST |= UART1_48MHZ_ENABLE;
|
||||
}
|
||||
385
board/omap1610inn/platform.S
Normal file
385
board/omap1610inn/platform.S
Normal file
@@ -0,0 +1,385 @@
|
||||
/*
|
||||
* Board specific setup info
|
||||
*
|
||||
* (C) Copyright 2003
|
||||
* Texas Instruments, <www.ti.com>
|
||||
* Kshitij Gupta <Kshitij@ti.com>
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <version.h>
|
||||
|
||||
#if defined(CONFIG_OMAP1610)
|
||||
#include <./configs/omap1510.h>
|
||||
#endif
|
||||
|
||||
|
||||
_TEXT_BASE:
|
||||
.word TEXT_BASE /* sdram load addr from config.mk */
|
||||
|
||||
.globl platformsetup
|
||||
platformsetup:
|
||||
|
||||
|
||||
/*------------------------------------------------------*
|
||||
* Set up ARM CLM registers (IDLECT1) *
|
||||
*------------------------------------------------------*/
|
||||
ldr r0, REG_ARM_IDLECT1
|
||||
ldr r1, VAL_ARM_IDLECT1
|
||||
str r1, [r0]
|
||||
|
||||
/*------------------------------------------------------*
|
||||
* Set up ARM CLM registers (IDLECT2) *
|
||||
*------------------------------------------------------*/
|
||||
ldr r0, REG_ARM_IDLECT2
|
||||
ldr r1, VAL_ARM_IDLECT2
|
||||
str r1, [r0]
|
||||
|
||||
/*------------------------------------------------------*
|
||||
* Set up ARM CLM registers (IDLECT3) *
|
||||
*------------------------------------------------------*/
|
||||
ldr r0, REG_ARM_IDLECT3
|
||||
ldr r1, VAL_ARM_IDLECT3
|
||||
str r1, [r0]
|
||||
|
||||
|
||||
mov r1, #0x01 /* PER_EN bit */
|
||||
ldr r0, REG_ARM_RSTCT2
|
||||
strh r1, [r0] /* CLKM; Peripheral reset. */
|
||||
|
||||
/* Set CLKM to Sync-Scalable */
|
||||
/* I supposedly need to enable the dsp clock before switching */
|
||||
mov r1, #0x0000
|
||||
ldr r0, REG_ARM_SYSST
|
||||
strh r1, [r0]
|
||||
mov r0, #0x400
|
||||
1:
|
||||
subs r0, r0, #0x1 /* wait for any bubbles to finish */
|
||||
bne 1b
|
||||
ldr r1, VAL_ARM_CKCTL
|
||||
ldr r0, REG_ARM_CKCTL
|
||||
strh r1, [r0]
|
||||
|
||||
/* a few nops to let settle */
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
|
||||
/* setup DPLL 1 */
|
||||
/* Ramp up the clock to 96Mhz */
|
||||
ldr r1, VAL_DPLL1_CTL
|
||||
ldr r0, REG_DPLL1_CTL
|
||||
strh r1, [r0]
|
||||
ands r1, r1, #0x10 /* Check if PLL is enabled. */
|
||||
beq lock_end /* Do not look for lock if BYPASS selected */
|
||||
2:
|
||||
ldrh r1, [r0]
|
||||
ands r1, r1, #0x01 /* Check the LOCK bit.*/
|
||||
beq 2b /* loop until bit goes hi. */
|
||||
lock_end:
|
||||
|
||||
|
||||
/*------------------------------------------------------*
|
||||
* Turn off the watchdog during init... *
|
||||
*------------------------------------------------------*/
|
||||
ldr r0, REG_WATCHDOG
|
||||
ldr r1, WATCHDOG_VAL1
|
||||
str r1, [r0]
|
||||
ldr r1, WATCHDOG_VAL2
|
||||
str r1, [r0]
|
||||
ldr r0, REG_WSPRDOG
|
||||
ldr r1, WSPRDOG_VAL1
|
||||
str r1, [r0]
|
||||
ldr r0, REG_WWPSDOG
|
||||
|
||||
watch1Wait:
|
||||
ldr r1, [r0]
|
||||
tst r1, #0x10
|
||||
bne watch1Wait
|
||||
|
||||
ldr r0, REG_WSPRDOG
|
||||
ldr r1, WSPRDOG_VAL2
|
||||
str r1, [r0]
|
||||
ldr r0, REG_WWPSDOG
|
||||
watch2Wait:
|
||||
ldr r1, [r0]
|
||||
tst r1, #0x10
|
||||
bne watch2Wait
|
||||
|
||||
|
||||
|
||||
|
||||
/* Set memory timings corresponding to the new clock speed */
|
||||
|
||||
/* Check execution location to determine current execution location
|
||||
* and branch to appropriate initialization code.
|
||||
*/
|
||||
/* Load physical SDRAM base. */
|
||||
mov r0, #0x10000000
|
||||
/* Get current execution location. */
|
||||
mov r1, pc
|
||||
/* Compare. */
|
||||
cmp r1, r0
|
||||
/* Skip over EMIF-fast initialization if running from SDRAM. */
|
||||
bge skip_sdram
|
||||
|
||||
/*
|
||||
* Delay for SDRAM initialization.
|
||||
*/
|
||||
mov r3, #0x1800 /* value should be checked */
|
||||
3:
|
||||
subs r3, r3, #0x1 /* Decrement count */
|
||||
bne 3b
|
||||
|
||||
|
||||
/*
|
||||
* Set SDRAM control values. Disable refresh before MRS command.
|
||||
*/
|
||||
|
||||
/* mobile ddr operation */
|
||||
ldr r0, REG_SDRAM_OPERATION
|
||||
mov r2, #07
|
||||
str r2, [r0]
|
||||
|
||||
/* config register */
|
||||
ldr r0, REG_SDRAM_CONFIG
|
||||
ldr r1, SDRAM_CONFIG_VAL
|
||||
str r1, [r0]
|
||||
|
||||
/* manual command register */
|
||||
ldr r0, REG_SDRAM_MANUAL_CMD
|
||||
/* issue set cke high */
|
||||
mov r1, #CMD_SDRAM_CKE_SET_HIGH
|
||||
str r1, [r0]
|
||||
/* issue nop */
|
||||
mov r1, #CMD_SDRAM_NOP
|
||||
str r1, [r0]
|
||||
|
||||
mov r2, #0x0100
|
||||
waitMDDR1:
|
||||
subs r2, r2, #1
|
||||
bne waitMDDR1 /* delay loop */
|
||||
|
||||
/* issue precharge */
|
||||
mov r1, #CMD_SDRAM_PRECHARGE
|
||||
str r1, [r0]
|
||||
|
||||
/* issue autorefresh x 2 */
|
||||
mov r1, #CMD_SDRAM_AUTOREFRESH
|
||||
str r1, [r0]
|
||||
str r1, [r0]
|
||||
|
||||
/* mrs register ddr mobile */
|
||||
ldr r0, REG_SDRAM_MRS
|
||||
mov r1, #0x33
|
||||
str r1, [r0]
|
||||
|
||||
/* emrs1 low-power register */
|
||||
ldr r0, REG_SDRAM_EMRS1
|
||||
/* self refresh on all banks */
|
||||
mov r1, #0
|
||||
str r1, [r0]
|
||||
|
||||
ldr r0, REG_DLL_URD_CONTROL
|
||||
ldr r1, DLL_URD_CONTROL_VAL
|
||||
str r1, [r0]
|
||||
|
||||
ldr r0, REG_DLL_LRD_CONTROL
|
||||
ldr r1, DLL_LRD_CONTROL_VAL
|
||||
str r1, [r0]
|
||||
|
||||
ldr r0, REG_DLL_WRT_CONTROL
|
||||
ldr r1, DLL_WRT_CONTROL_VAL
|
||||
str r1, [r0]
|
||||
|
||||
/* delay loop */
|
||||
mov r2, #0x0100
|
||||
waitMDDR2:
|
||||
subs r2, r2, #1
|
||||
bne waitMDDR2
|
||||
|
||||
/*
|
||||
* Delay for SDRAM initialization.
|
||||
*/
|
||||
mov r3, #0x1800
|
||||
4:
|
||||
subs r3, r3, #1 /* Decrement count. */
|
||||
bne 4b
|
||||
b common_tc
|
||||
|
||||
skip_sdram:
|
||||
|
||||
ldr r0, REG_SDRAM_CONFIG
|
||||
ldr r1, SDRAM_CONFIG_VAL
|
||||
str r1, [r0]
|
||||
|
||||
common_tc:
|
||||
/* slow interface */
|
||||
ldr r1, VAL_TC_EMIFS_CS0_CONFIG
|
||||
ldr r0, REG_TC_EMIFS_CS0_CONFIG
|
||||
str r1, [r0] /* Chip Select 0 */
|
||||
|
||||
ldr r1, VAL_TC_EMIFS_CS1_CONFIG
|
||||
ldr r0, REG_TC_EMIFS_CS1_CONFIG
|
||||
str r1, [r0] /* Chip Select 1 */
|
||||
ldr r1, VAL_TC_EMIFS_CS3_CONFIG
|
||||
ldr r0, REG_TC_EMIFS_CS3_CONFIG
|
||||
str r1, [r0] /* Chip Select 3 */
|
||||
/* back to arch calling code */
|
||||
mov pc, lr
|
||||
|
||||
/* the literal pools origin */
|
||||
.ltorg
|
||||
|
||||
|
||||
REG_TC_EMIFS_CONFIG: /* 32 bits */
|
||||
.word 0xfffecc0c
|
||||
REG_TC_EMIFS_CS0_CONFIG: /* 32 bits */
|
||||
.word 0xfffecc10
|
||||
REG_TC_EMIFS_CS1_CONFIG: /* 32 bits */
|
||||
.word 0xfffecc14
|
||||
REG_TC_EMIFS_CS2_CONFIG: /* 32 bits */
|
||||
.word 0xfffecc18
|
||||
REG_TC_EMIFS_CS3_CONFIG: /* 32 bits */
|
||||
.word 0xfffecc1c
|
||||
|
||||
/* MPU clock/reset/power mode control registers */
|
||||
REG_ARM_CKCTL: /* 16 bits */
|
||||
.word 0xfffece00
|
||||
|
||||
REG_ARM_IDLECT3: /* 16 bits */
|
||||
.word 0xfffece24
|
||||
REG_ARM_IDLECT2: /* 16 bits */
|
||||
.word 0xfffece08
|
||||
REG_ARM_IDLECT1: /* 16 bits */
|
||||
.word 0xfffece04
|
||||
|
||||
REG_ARM_RSTCT2: /* 16 bits */
|
||||
.word 0xfffece14
|
||||
REG_ARM_SYSST: /* 16 bits */
|
||||
.word 0xfffece18
|
||||
/* DPLL control registers */
|
||||
REG_DPLL1_CTL: /* 16 bits */
|
||||
.word 0xfffecf00
|
||||
|
||||
/* Watch Dog register */
|
||||
/* secure watchdog stop */
|
||||
REG_WSPRDOG:
|
||||
.word 0xfffeb048
|
||||
/* watchdog write pending */
|
||||
REG_WWPSDOG:
|
||||
.word 0xfffeb034
|
||||
|
||||
WSPRDOG_VAL1:
|
||||
.word 0x0000aaaa
|
||||
WSPRDOG_VAL2:
|
||||
.word 0x00005555
|
||||
|
||||
/* SDRAM config is: auto refresh enabled, 16 bit 4 bank,
|
||||
counter @8192 rows, 10 ns, 8 burst */
|
||||
REG_SDRAM_CONFIG:
|
||||
.word 0xfffecc20
|
||||
|
||||
/* Operation register */
|
||||
REG_SDRAM_OPERATION:
|
||||
.word 0xfffecc80
|
||||
|
||||
/* Manual command register */
|
||||
REG_SDRAM_MANUAL_CMD:
|
||||
.word 0xfffecc84
|
||||
|
||||
/* SDRAM MRS (New) config is: CAS latency is 2, burst length 8 */
|
||||
REG_SDRAM_MRS:
|
||||
.word 0xfffecc70
|
||||
|
||||
/* SDRAM MRS (New) config is: CAS latency is 2, burst length 8 */
|
||||
REG_SDRAM_EMRS1:
|
||||
.word 0xfffecc78
|
||||
|
||||
/* WRT DLL register */
|
||||
REG_DLL_WRT_CONTROL:
|
||||
.word 0xfffecc68
|
||||
DLL_WRT_CONTROL_VAL:
|
||||
.word 0x03f00002
|
||||
|
||||
/* URD DLL register */
|
||||
REG_DLL_URD_CONTROL:
|
||||
.word 0xfffeccc0
|
||||
DLL_URD_CONTROL_VAL:
|
||||
.word 0x00800002
|
||||
|
||||
/* LRD DLL register */
|
||||
REG_DLL_LRD_CONTROL:
|
||||
.word 0xfffecccc
|
||||
|
||||
REG_WATCHDOG:
|
||||
.word 0xfffec808
|
||||
|
||||
/* 96 MHz Samsung Mobile DDR */
|
||||
SDRAM_CONFIG_VAL:
|
||||
.word 0x001200f4
|
||||
|
||||
DLL_LRD_CONTROL_VAL:
|
||||
.word 0x00800002
|
||||
|
||||
VAL_ARM_CKCTL:
|
||||
.word 0x3000
|
||||
VAL_DPLL1_CTL:
|
||||
.word 0x2830
|
||||
|
||||
VAL_TC_EMIFS_CS0_CONFIG:
|
||||
.word 0x002130b0
|
||||
VAL_TC_EMIFS_CS1_CONFIG:
|
||||
.word 0x00001131
|
||||
VAL_TC_EMIFS_CS2_CONFIG:
|
||||
.word 0x000055f0
|
||||
VAL_TC_EMIFS_CS3_CONFIG:
|
||||
.word 0x88011131
|
||||
VAL_TC_EMIFF_SDRAM_CONFIG:
|
||||
.word 0x010290fc
|
||||
VAL_TC_EMIFF_MRS:
|
||||
.word 0x00000027
|
||||
|
||||
VAL_ARM_IDLECT1:
|
||||
.word 0x00000400
|
||||
|
||||
VAL_ARM_IDLECT2:
|
||||
.word 0x00000886
|
||||
VAL_ARM_IDLECT3:
|
||||
.word 0x00000015
|
||||
|
||||
WATCHDOG_VAL1:
|
||||
.word 0x000000f5
|
||||
WATCHDOG_VAL2:
|
||||
.word 0x000000a0
|
||||
|
||||
/* command values */
|
||||
.equ CMD_SDRAM_NOP, 0x00000000
|
||||
.equ CMD_SDRAM_PRECHARGE, 0x00000001
|
||||
.equ CMD_SDRAM_AUTOREFRESH, 0x00000002
|
||||
.equ CMD_SDRAM_CKE_SET_HIGH, 0x00000007
|
||||
51
board/omap1610inn/u-boot.lds
Normal file
51
board/omap1610inn/u-boot.lds
Normal file
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* (C) Copyright 2002
|
||||
* Gary Jennejohn, DENX Software Engineering, <gj@denx.de>
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
|
||||
OUTPUT_ARCH(arm)
|
||||
ENTRY(_start)
|
||||
SECTIONS
|
||||
{
|
||||
. = 0x00000000;
|
||||
. = ALIGN(4);
|
||||
.text :
|
||||
{
|
||||
cpu/arm926ejs/start.o (.text)
|
||||
*(.text)
|
||||
}
|
||||
. = ALIGN(4);
|
||||
.rodata : { *(.rodata) }
|
||||
. = ALIGN(4);
|
||||
.data : { *(.data) }
|
||||
. = ALIGN(4);
|
||||
.got : { *(.got) }
|
||||
|
||||
__u_boot_cmd_start = .;
|
||||
.u_boot_cmd : { *(.u_boot_cmd) }
|
||||
__u_boot_cmd_end = .;
|
||||
|
||||
armboot_end_data = .;
|
||||
. = ALIGN(4);
|
||||
.bss : { *(.bss) }
|
||||
armboot_end = .;
|
||||
}
|
||||
@@ -96,7 +96,7 @@ long int initdram (int board_type)
|
||||
{
|
||||
volatile immap_t *immap = (immap_t *)CFG_IMMR;
|
||||
volatile memctl8xx_t *memctl = &immap->im_memctl;
|
||||
long int size10 ;
|
||||
long int size9 ;
|
||||
|
||||
upmconfig(UPMA, (uint *)sdram_table, sizeof(sdram_table)/sizeof(uint));
|
||||
|
||||
@@ -109,7 +109,7 @@ long int initdram (int board_type)
|
||||
memctl->memc_or1 = CFG_OR1_PRELIM;
|
||||
memctl->memc_br1 = CFG_BR1_PRELIM;
|
||||
|
||||
memctl->memc_mamr = CFG_MAMR_10COL & (~(MAMR_PTAE)); /* no refresh yet */
|
||||
memctl->memc_mamr = CFG_MAMR_9COL & (~(MAMR_PTAE)); /* no refresh yet */
|
||||
|
||||
udelay(200);
|
||||
|
||||
@@ -122,13 +122,20 @@ long int initdram (int board_type)
|
||||
|
||||
udelay (1000);
|
||||
|
||||
/* Check Bank 0 Memory Size
|
||||
* try 10 column mode
|
||||
/* Check Bank 0 Memory Size,
|
||||
* 9 column mode
|
||||
*/
|
||||
|
||||
size10 = dram_size (CFG_MAMR_10COL, (ulong *)SDRAM_BASE_PRELIM, SDRAM_MAX_SIZE) ;
|
||||
size9 = dram_size (CFG_MAMR_9COL, (ulong *)SDRAM_BASE_PRELIM, SDRAM_MAX_SIZE) ;
|
||||
|
||||
return (size10);
|
||||
/*
|
||||
* Final mapping:
|
||||
*/
|
||||
|
||||
memctl->memc_or1 = ((-size9) & 0xFFFF0000) | CFG_OR_TIMING_SDRAM;
|
||||
udelay (1000);
|
||||
|
||||
return (size9);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
@@ -23,6 +23,10 @@
|
||||
|
||||
#include <common.h>
|
||||
#include <mpc8xx.h>
|
||||
/* environment.h defines the various CFG_ENV_... values in terms
|
||||
* of whichever ones are given in the configuration file.
|
||||
*/
|
||||
#include <environment.h>
|
||||
|
||||
flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */
|
||||
|
||||
@@ -104,6 +108,19 @@ unsigned long flash_init (void)
|
||||
&flash_info[0]);
|
||||
#endif
|
||||
|
||||
#ifdef CFG_ENV_ADDR
|
||||
flash_protect ( FLAG_PROTECT_SET,
|
||||
CFG_ENV_ADDR,
|
||||
CFG_ENV_ADDR + CFG_ENV_SIZE - 1, &flash_info[0]);
|
||||
#endif
|
||||
|
||||
#ifdef CFG_ENV_ADDR_REDUND
|
||||
flash_protect ( FLAG_PROTECT_SET,
|
||||
CFG_ENV_ADDR_REDUND,
|
||||
CFG_ENV_ADDR_REDUND + CFG_ENV_SIZE_REDUND - 1,
|
||||
&flash_info[0]);
|
||||
#endif
|
||||
|
||||
return (size_b);
|
||||
}
|
||||
|
||||
@@ -154,6 +171,21 @@ static void flash_get_offsets (ulong base, flash_info_t *info)
|
||||
for( i = 0; i < info->sector_count; i++ )
|
||||
info->start[i] = base + (i * sect_size);
|
||||
}
|
||||
else if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_AMD
|
||||
&& (info->flash_id & FLASH_TYPEMASK) == FLASH_AM800T) {
|
||||
|
||||
int sect_size; /* number of bytes/sector */
|
||||
|
||||
sect_size = 0x00010000 * (sizeof(FPW)/2);
|
||||
|
||||
/* set up sector start address table (top boot sector type) */
|
||||
for (i = 0; i < info->sector_count - 3; i++)
|
||||
info->start[i] = base + (i * sect_size);
|
||||
i = info->sector_count - 1;
|
||||
info->start[i--] = base + (info->size - 0x00004000) * (sizeof(FPW)/2);
|
||||
info->start[i--] = base + (info->size - 0x00006000) * (sizeof(FPW)/2);
|
||||
info->start[i--] = base + (info->size - 0x00008000) * (sizeof(FPW)/2);
|
||||
}
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
@@ -196,6 +228,9 @@ void flash_print_info (flash_info_t *info)
|
||||
}
|
||||
|
||||
switch (info->flash_id & FLASH_TYPEMASK) {
|
||||
case FLASH_AM800T:
|
||||
fmt = "29LV800B%s (8 Mbit, %s)\n";
|
||||
break;
|
||||
case FLASH_AM640U:
|
||||
fmt = "29LV641D (64 Mbit, uniform sectors)\n";
|
||||
break;
|
||||
@@ -295,6 +330,12 @@ ulong flash_get_size (FPWV *addr, flash_info_t *info)
|
||||
/* Check 16 bits or 32 bits of ID so work on 32 or 16 bit bus. */
|
||||
if (info->flash_id != FLASH_UNKNOWN) switch (addr[1]) {
|
||||
|
||||
case (FPW)AMD_ID_LV800T:
|
||||
info->flash_id += FLASH_AM800T;
|
||||
info->sector_count = 19;
|
||||
info->size = 0x00100000 * (sizeof(FPW)/2);
|
||||
break; /* => 1 or 2 MiB */
|
||||
|
||||
case (FPW)AMD_ID_LV640U: /* 29LV640 and 29LV641 have same ID */
|
||||
info->flash_id += FLASH_AM640U;
|
||||
info->sector_count = 128;
|
||||
@@ -401,6 +442,7 @@ static void flash_sync_real_protect(flash_info_t *info)
|
||||
break;
|
||||
|
||||
case FLASH_AM640U:
|
||||
case FLASH_AM800T:
|
||||
default:
|
||||
/* no hardware protect that we support */
|
||||
break;
|
||||
@@ -438,6 +480,7 @@ int flash_erase (flash_info_t *info, int s_first, int s_last)
|
||||
case FLASH_28F320C3B:
|
||||
case FLASH_28F640C3B:
|
||||
case FLASH_AM640U:
|
||||
case FLASH_AM800T:
|
||||
break;
|
||||
case FLASH_UNKNOWN:
|
||||
default:
|
||||
@@ -735,6 +778,7 @@ int flash_real_protect (flash_info_t * info, long sector, int prot)
|
||||
break;
|
||||
|
||||
case FLASH_AM640U:
|
||||
case FLASH_AM800T:
|
||||
default:
|
||||
/* no hardware protect that we support */
|
||||
info->protect[sector] = prot;
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
|
||||
#include <common.h>
|
||||
#include <config.h>
|
||||
#include <jffs2/jffs2.h>
|
||||
#include <mpc8xx.h>
|
||||
#include <net.h> /* for eth_init() */
|
||||
#include <rtc.h>
|
||||
@@ -329,11 +330,9 @@ int misc_init_r (void)
|
||||
#if (CONFIG_COMMANDS & CFG_CMD_NAND)
|
||||
void nand_init(void)
|
||||
{
|
||||
nand_probe(CFG_DFLASH_BASE); /* see if any NAND flash present */
|
||||
if (nand_dev_desc[0].ChipID != NAND_ChipID_UNKNOWN) {
|
||||
puts("NAND: ");
|
||||
print_size(nand_dev_desc[0].totlen, "\n");
|
||||
}
|
||||
unsigned long totlen = nand_probe(CFG_NAND_BASE);
|
||||
|
||||
printf ("%4lu MB\n", totlen >> 20);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -602,3 +601,70 @@ long int initdram(int board_type)
|
||||
|
||||
return (size_sdram);
|
||||
}
|
||||
|
||||
#ifdef CFG_JFFS_CUSTOM_PART
|
||||
|
||||
static struct part_info part;
|
||||
|
||||
#define jffs2_block(i) \
|
||||
((struct jffs2_unknown_node*)(CFG_JFFS2_BASE + (i) * 65536))
|
||||
|
||||
struct part_info* jffs2_part_info(int part_num)
|
||||
{
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
bd_t *bd = gd->bd;
|
||||
char* s;
|
||||
int i;
|
||||
int bootnor = 0; /* assume booting from NAND flash */
|
||||
|
||||
if (part_num != 0)
|
||||
return 0; /* only support one partition */
|
||||
|
||||
if (part.usr_priv == (void*)1)
|
||||
return ∂ /* already have part info */
|
||||
|
||||
memset(&part, 0, sizeof(part));
|
||||
|
||||
if (nand_dev_desc[0].ChipID == NAND_ChipID_UNKNOWN)
|
||||
bootnor = 1;
|
||||
else if (bd->bi_flashsize < 0x800000)
|
||||
bootnor = 0;
|
||||
else for (i = 0; !bootnor && i < 4; ++i) {
|
||||
/* boot from NOR if JFFS2 info in any of
|
||||
* first 4 erase blocks
|
||||
*/
|
||||
|
||||
if (jffs2_block(i)->magic == JFFS2_MAGIC_BITMASK)
|
||||
bootnor = 1;
|
||||
}
|
||||
|
||||
if (bootnor) {
|
||||
/* no NAND flash or boot in NOR, use NOR flash */
|
||||
part.offset = (unsigned char *)CFG_JFFS2_BASE;
|
||||
part.size = CFG_JFFS2_SIZE;
|
||||
}
|
||||
else {
|
||||
char readcmd[60];
|
||||
|
||||
/* boot info in NAND flash, get and use copy in RAM */
|
||||
|
||||
/* override info from environment if present */
|
||||
s = getenv("fsaddr");
|
||||
part.offset = s ? (void *)simple_strtoul(s, NULL, 16)
|
||||
: (void *)CFG_JFFS2_RAMBASE;
|
||||
s = getenv("fssize");
|
||||
part.size = s ? simple_strtoul(s, NULL, 16)
|
||||
: CFG_JFFS2_RAMSIZE;
|
||||
|
||||
/* read from nand flash */
|
||||
sprintf(readcmd, "nand read.jffs2 %x 0 %x",
|
||||
(uint32_t)part.offset, part.size);
|
||||
run_command(readcmd, 0);
|
||||
}
|
||||
|
||||
part.erasesize = 0; /* unused */
|
||||
part.usr_priv=(void*)1; /* ready */
|
||||
|
||||
return ∂
|
||||
}
|
||||
#endif /* ifdef CFG_JFFS_CUSTOM_PART */
|
||||
|
||||
@@ -28,3 +28,4 @@
|
||||
TEXT_BASE = 0xFFF00000
|
||||
|
||||
PLATFORM_CPPFLAGS += -DTEXT_BASE=$(TEXT_BASE)
|
||||
PLATFORM_LIBS += $(shell $(CC) -print-libgcc-file-name)
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
|
||||
#include <common.h>
|
||||
#include <mpc824x.h>
|
||||
#include <pci.h>
|
||||
|
||||
int checkboard (void)
|
||||
{
|
||||
@@ -84,3 +85,11 @@ Done:
|
||||
return CFG_MAX_RAM_SIZE;
|
||||
#endif
|
||||
}
|
||||
|
||||
static struct pci_controller hose;
|
||||
|
||||
void pci_init_board(void)
|
||||
{
|
||||
pci_mpc824x_init(&hose);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# (C) Copyright 2000
|
||||
# (C) Copyright 2000-2003
|
||||
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
#
|
||||
# See file CREDITS for list of people who contributed to this
|
||||
|
||||
@@ -25,7 +25,7 @@ include $(TOPDIR)/config.mk
|
||||
|
||||
LIB = lib$(BOARD).a
|
||||
|
||||
OBJS := trab.o flash.o vfd.o
|
||||
OBJS := trab.o flash.o vfd.o cmd_trab.o memory.o tsc2000.o
|
||||
SOBJS := memsetup.o
|
||||
|
||||
$(LIB): $(OBJS) $(SOBJS)
|
||||
|
||||
71
board/trab/Pt1000_temp_data.h
Normal file
71
board/trab/Pt1000_temp_data.h
Normal file
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Data file for tsc2000 driver.
|
||||
* Copyright (C) 2002, 2003 DENX Software Engineering, Wolfgang Denk, wd@denx.de
|
||||
*/
|
||||
|
||||
#ifndef _PT1000_TEMP_DATA_H
|
||||
#define _PT1000_TEMP_DATA_H
|
||||
|
||||
long Pt1000_temp_table[][2] = {
|
||||
/* For quick range checking the largest element
|
||||
* is placed at index 0.
|
||||
* U, nV T, C*100
|
||||
*/
|
||||
{ 44000000 , 12165 },
|
||||
{ -10000000 , -2644 },
|
||||
{ -9000000 , -2381 },
|
||||
{ -8000000 , -2118 },
|
||||
{ -7000000 , -1855 },
|
||||
{ -6000000 , -1591 },
|
||||
{ -5000000 , -1327 },
|
||||
{ -4000000 , -1063 },
|
||||
{ -3000000 , -798 },
|
||||
{ -2000000 , -532 },
|
||||
{ -1000000 , -266 },
|
||||
{ 0 , 000 },
|
||||
{ 1000000 , 267 },
|
||||
{ 2000000 , 534 },
|
||||
{ 3000000 , 802 },
|
||||
{ 4000000 , 1070 },
|
||||
{ 5000000 , 1338 },
|
||||
{ 6000000 , 1607 },
|
||||
{ 7000000 , 1876 },
|
||||
{ 8000000 , 2146 },
|
||||
{ 9000000 , 2416 },
|
||||
{ 10000000 , 2687 },
|
||||
{ 11000000 , 2958 },
|
||||
{ 12000000 , 3230 },
|
||||
{ 13000000 , 3502 },
|
||||
{ 14000000 , 3774 },
|
||||
{ 15000000 , 4047 },
|
||||
{ 16000000 , 4321 },
|
||||
{ 17000000 , 4595 },
|
||||
{ 18000000 , 4869 },
|
||||
{ 19000000 , 5144 },
|
||||
{ 20000000 , 5419 },
|
||||
{ 21000000 , 5694 },
|
||||
{ 22000000 , 5971 },
|
||||
{ 23000000 , 6247 },
|
||||
{ 24000000 , 6524 },
|
||||
{ 25000000 , 6802 },
|
||||
{ 26000000 , 7080 },
|
||||
{ 27000000 , 7358 },
|
||||
{ 28000000 , 7637 },
|
||||
{ 29000000 , 7916 },
|
||||
{ 30000000 , 8196 },
|
||||
{ 31000000 , 8476 },
|
||||
{ 32000000 , 8757 },
|
||||
{ 33000000 , 9039 },
|
||||
{ 34000000 , 9320 },
|
||||
{ 35000000 , 9602 },
|
||||
{ 36000000 , 9885 },
|
||||
{ 37000000 , 10168 },
|
||||
{ 38000000 , 10452 },
|
||||
{ 39000000 , 10736 },
|
||||
{ 40000000 , 11021 },
|
||||
{ 41000000 , 11306 },
|
||||
{ 42000000 , 11592 },
|
||||
{ 43000000 , 11879 },
|
||||
{ 44000000 , 12165 },
|
||||
};
|
||||
#endif /* _PT1000_TEMP_DATA_H */
|
||||
821
board/trab/cmd_trab.c
Normal file
821
board/trab/cmd_trab.c
Normal file
@@ -0,0 +1,821 @@
|
||||
/*
|
||||
* (C) Copyright 2003
|
||||
* Martin Krause, TQ-Systems GmbH, martin.krause@tqs.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 <s3c2400.h>
|
||||
|
||||
/*
|
||||
* TRAB board specific commands. Especially commands for burn-in and function
|
||||
* test.
|
||||
*/
|
||||
#if (CONFIG_COMMANDS & CFG_CMD_BSP)
|
||||
|
||||
/* limits for valid range of VCC5V in mV */
|
||||
#define VCC5V_MIN 4500
|
||||
#define VCC5V_MAX 5500
|
||||
|
||||
/*
|
||||
* Test strings for EEPROM test. Length of string 2 must not exceed length of
|
||||
* string 1. Otherwise a buffer overrun could occur!
|
||||
*/
|
||||
#define EEPROM_TEST_STRING_1 "0987654321 :tset a si siht"
|
||||
#define EEPROM_TEST_STRING_2 "this is a test: 1234567890"
|
||||
|
||||
/*
|
||||
* min/max limits for valid contact temperature during burn in test (in
|
||||
* degree Centigrade * 100)
|
||||
*/
|
||||
#define MIN_CONTACT_TEMP -1000
|
||||
#define MAX_CONTACT_TEMP +9000
|
||||
|
||||
/* blinking frequency of status LED */
|
||||
#define LED_BLINK_FREQ 5
|
||||
|
||||
/* delay time between burn in cycles in seconds */
|
||||
#ifndef BURN_IN_CYCLE_DELAY /* if not defined in include/configs/trab.h */
|
||||
#define BURN_IN_CYCLE_DELAY 5
|
||||
#endif
|
||||
|
||||
/* physical SRAM parameters */
|
||||
#define SRAM_ADDR 0x02000000 /* GCS1 */
|
||||
#define SRAM_SIZE 0x40000 /* 256 kByte */
|
||||
|
||||
/* CPLD-Register for controlling TRAB hardware functions */
|
||||
#define CPLD_BUTTONS ((volatile unsigned long *)0x04020000)
|
||||
#define CPLD_FILL_LEVEL ((volatile unsigned long *)0x04008000)
|
||||
#define CPLD_ROTARY_SWITCH ((volatile unsigned long *)0x04018000)
|
||||
#define CPLD_RS485_RE ((volatile unsigned long *)0x04028000)
|
||||
|
||||
/* I2C EEPROM device address */
|
||||
#define I2C_EEPROM_DEV_ADDR 0x54
|
||||
|
||||
/* EEPROM address map */
|
||||
#define EE_ADDR_TEST 128
|
||||
#define EE_ADDR_MAX_CYCLES 256
|
||||
#define EE_ADDR_STATUS 258
|
||||
#define EE_ADDR_PASS_CYCLES 259
|
||||
#define EE_ADDR_FIRST_ERROR_CYCLE 261
|
||||
#define EE_ADDR_FIRST_ERROR_NUM 263
|
||||
#define EE_ADDR_FIRST_ERROR_NAME 264
|
||||
#define EE_ADDR_ACT_CYCLE 280
|
||||
|
||||
/* Bit definitions for ADCCON */
|
||||
#define ADC_ENABLE_START 0x1
|
||||
#define ADC_READ_START 0x2
|
||||
#define ADC_STDBM 0x4
|
||||
#define ADC_INP_AIN0 (0x0 << 3)
|
||||
#define ADC_INP_AIN1 (0x1 << 3)
|
||||
#define ADC_INP_AIN2 (0x2 << 3)
|
||||
#define ADC_INP_AIN3 (0x3 << 3)
|
||||
#define ADC_INP_AIN4 (0x4 << 3)
|
||||
#define ADC_INP_AIN5 (0x5 << 3)
|
||||
#define ADC_INP_AIN6 (0x6 << 3)
|
||||
#define ADC_INP_AIN7 (0x7 << 3)
|
||||
#define ADC_PRSCEN 0x4000
|
||||
#define ADC_ECFLG 0x800
|
||||
|
||||
/* misc */
|
||||
|
||||
/* externals */
|
||||
extern int memory_post_tests (unsigned long start, unsigned long size);
|
||||
extern int i2c_write (uchar, uint, int , uchar* , int);
|
||||
extern int i2c_read (uchar, uint, int , uchar* , int);
|
||||
extern void tsc2000_reg_init (void);
|
||||
extern s32 tsc2000_contact_temp (void);
|
||||
extern void spi_init(void);
|
||||
|
||||
/* function declarations */
|
||||
int do_dip (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
|
||||
int do_vcc5v (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
|
||||
int do_burn_in (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
|
||||
int do_contact_temp (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
|
||||
int do_burn_in_status (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
|
||||
|
||||
/* helper functions */
|
||||
static void adc_init (void);
|
||||
static int adc_read (unsigned int channel);
|
||||
static int read_dip (void);
|
||||
static int read_vcc5v (void);
|
||||
static int test_dip (void);
|
||||
static int test_vcc5v (void);
|
||||
static int test_rotary_switch (void);
|
||||
static int test_sram (void);
|
||||
static int test_eeprom (void);
|
||||
static int test_contact_temp (void);
|
||||
static int i2c_write_multiple (uchar chip, uint addr, int alen,
|
||||
uchar *buffer, int len);
|
||||
static int i2c_read_multiple (uchar chip, uint addr, int alen,
|
||||
uchar *buffer, int len);
|
||||
static void led_set (unsigned int);
|
||||
static void led_blink (void);
|
||||
static void led_init (void);
|
||||
static void sdelay (unsigned long seconds); /* delay in seconds */
|
||||
static int dummy (void);
|
||||
static int read_max_cycles(void);
|
||||
static void test_function_table_init (void);
|
||||
static void global_vars_init (void);
|
||||
static int global_vars_write_to_eeprom (void);
|
||||
|
||||
/* globals */
|
||||
u16 max_cycles;
|
||||
u8 status;
|
||||
u16 pass_cycles;
|
||||
u16 first_error_cycle;
|
||||
u8 first_error_num;
|
||||
unsigned char first_error_name[16];
|
||||
u16 act_cycle;
|
||||
|
||||
typedef struct test_function_s {
|
||||
unsigned char *name;
|
||||
int (*pf)(void);
|
||||
} test_function_t;
|
||||
|
||||
/* max number of Burn In Functions */
|
||||
#define BIF_MAX 6
|
||||
|
||||
/* table with burn in functions */
|
||||
test_function_t test_function[BIF_MAX];
|
||||
|
||||
|
||||
int do_burn_in (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
|
||||
{
|
||||
int i;
|
||||
int cycle_status;
|
||||
|
||||
if (argc > 1) {
|
||||
printf ("Usage:\n%s\n", cmdtp->usage);
|
||||
return 1;
|
||||
}
|
||||
|
||||
led_init ();
|
||||
global_vars_init ();
|
||||
test_function_table_init ();
|
||||
|
||||
if (global_vars_write_to_eeprom () != 0) {
|
||||
printf ("%s: error writing global_vars to eeprom\n",
|
||||
__FUNCTION__);
|
||||
return (1);
|
||||
}
|
||||
|
||||
if (read_max_cycles () != 0) {
|
||||
printf ("%s: error reading max_cycles from eeprom\n",
|
||||
__FUNCTION__);
|
||||
return (1);
|
||||
}
|
||||
|
||||
if (max_cycles == 0) {
|
||||
printf ("%s: error, burn in max_cycles = 0\n", __FUNCTION__);
|
||||
return (1);
|
||||
}
|
||||
|
||||
status = 0;
|
||||
for (act_cycle = 1; act_cycle <= max_cycles; act_cycle++) {
|
||||
|
||||
cycle_status = 0;
|
||||
for (i = 0; i < BIF_MAX; i++) {
|
||||
|
||||
/* call test function */
|
||||
if ((*test_function[i].pf)() != 0) {
|
||||
printf ("error in %s test\n",
|
||||
test_function[i].name);
|
||||
|
||||
/* is it the first error? */
|
||||
if (status == 0) {
|
||||
status = 1;
|
||||
first_error_cycle = act_cycle;
|
||||
|
||||
/* do not use error_num 0 */
|
||||
first_error_num = i+1;
|
||||
strncpy (first_error_name,
|
||||
test_function[i].name,
|
||||
sizeof (first_error_name));
|
||||
led_set (0);
|
||||
}
|
||||
cycle_status = 1;
|
||||
}
|
||||
}
|
||||
/* were all tests of actual cycle OK? */
|
||||
if (cycle_status == 0)
|
||||
pass_cycles++;
|
||||
|
||||
/* set status LED if no error is occoured since yet */
|
||||
if (status == 0)
|
||||
led_set (1);
|
||||
|
||||
printf ("%s: cycle %d finished\n", __FUNCTION__, act_cycle);
|
||||
|
||||
/* pause between cycles */
|
||||
sdelay (BURN_IN_CYCLE_DELAY);
|
||||
}
|
||||
|
||||
if (global_vars_write_to_eeprom () != 0) {
|
||||
led_set (0);
|
||||
printf ("%s: error writing global_vars to eeprom\n",
|
||||
__FUNCTION__);
|
||||
status = 1;
|
||||
}
|
||||
|
||||
if (status == 0) {
|
||||
led_blink (); /* endless loop!! */
|
||||
return (0);
|
||||
} else {
|
||||
led_set (0);
|
||||
return (1);
|
||||
}
|
||||
}
|
||||
|
||||
U_BOOT_CMD(
|
||||
burn_in, 1, 1, do_burn_in,
|
||||
"burn_in - start burn-in test application on TRAB\n",
|
||||
"\n"
|
||||
" - start burn-in test application\n"
|
||||
" The burn-in test could took a while to finish!\n"
|
||||
" The content of the onboard EEPROM is modified!\n"
|
||||
);
|
||||
|
||||
|
||||
int do_dip (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
|
||||
{
|
||||
int i, dip;
|
||||
|
||||
if (argc > 1) {
|
||||
printf ("Usage:\n%s\n", cmdtp->usage);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ((dip = read_dip ()) == -1) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
if ((dip & (1 << i)) == 0)
|
||||
printf("0");
|
||||
else
|
||||
printf("1");
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
U_BOOT_CMD(
|
||||
dip, 1, 1, do_dip,
|
||||
"dip - read dip switch on TRAB\n",
|
||||
"\n"
|
||||
" - read state of dip switch (S1) on TRAB board\n"
|
||||
" read sequence: 1-2-3-4; ON=1; OFF=0; e.g.: \"0100\"\n"
|
||||
);
|
||||
|
||||
|
||||
int do_vcc5v (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
|
||||
{
|
||||
int vcc5v;
|
||||
|
||||
if (argc > 1) {
|
||||
printf ("Usage:\n%s\n", cmdtp->usage);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ((vcc5v = read_vcc5v ()) == -1) {
|
||||
return (1);
|
||||
}
|
||||
|
||||
printf ("%d", (vcc5v / 1000));
|
||||
printf (".%d", (vcc5v % 1000) / 100);
|
||||
printf ("%d V\n", (vcc5v % 100) / 10) ;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
U_BOOT_CMD(
|
||||
vcc5v, 1, 1, do_vcc5v,
|
||||
"vcc5v - read VCC5V on TRAB\n",
|
||||
"\n"
|
||||
" - read actual value of voltage VCC5V\n"
|
||||
);
|
||||
|
||||
|
||||
int do_contact_temp (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
|
||||
{
|
||||
int contact_temp;
|
||||
|
||||
if (argc > 1) {
|
||||
printf ("Usage:\n%s\n", cmdtp->usage);
|
||||
return 1;
|
||||
}
|
||||
|
||||
spi_init ();
|
||||
tsc2000_reg_init ();
|
||||
|
||||
contact_temp = tsc2000_contact_temp();
|
||||
printf ("%d degree C * 100\n", contact_temp) ;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
U_BOOT_CMD(
|
||||
c_temp, 1, 1, do_contact_temp,
|
||||
"c_temp - read contact temperature on TRAB\n",
|
||||
"\n"
|
||||
" - reads the onboard temperature (=contact temperature)\n"
|
||||
);
|
||||
|
||||
|
||||
int do_burn_in_status (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
|
||||
{
|
||||
if (argc > 1) {
|
||||
printf ("Usage:\n%s\n", cmdtp->usage);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (i2c_read_multiple (I2C_EEPROM_DEV_ADDR, EE_ADDR_STATUS, 1,
|
||||
(unsigned char*) &status, 1)) {
|
||||
return (1);
|
||||
}
|
||||
if (i2c_read_multiple (I2C_EEPROM_DEV_ADDR, EE_ADDR_PASS_CYCLES, 1,
|
||||
(unsigned char*) &pass_cycles, 2)) {
|
||||
return (1);
|
||||
}
|
||||
if (i2c_read_multiple (I2C_EEPROM_DEV_ADDR, EE_ADDR_FIRST_ERROR_CYCLE,
|
||||
1, (unsigned char*) &first_error_cycle, 2)) {
|
||||
return (1);
|
||||
}
|
||||
if (i2c_read_multiple (I2C_EEPROM_DEV_ADDR, EE_ADDR_FIRST_ERROR_NUM,
|
||||
1, (unsigned char*) &first_error_num, 1)) {
|
||||
return (1);
|
||||
}
|
||||
if (i2c_read_multiple (I2C_EEPROM_DEV_ADDR, EE_ADDR_FIRST_ERROR_NAME,
|
||||
1, first_error_name,
|
||||
sizeof (first_error_name))) {
|
||||
return (1);
|
||||
}
|
||||
|
||||
if (read_max_cycles () != 0) {
|
||||
return (1);
|
||||
}
|
||||
|
||||
printf ("max_cycles = %d\n", max_cycles);
|
||||
printf ("status = %d\n", status);
|
||||
printf ("pass_cycles = %d\n", pass_cycles);
|
||||
printf ("first_error_cycle = %d\n", first_error_cycle);
|
||||
printf ("first_error_num = %d\n", first_error_num);
|
||||
printf ("first_error_name = %.*s\n",(int) sizeof(first_error_name),
|
||||
first_error_name);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
U_BOOT_CMD(
|
||||
bis, 1, 1, do_burn_in_status,
|
||||
"bis - print burn in status on TRAB\n",
|
||||
"\n"
|
||||
" - prints the status variables of the last burn in test\n"
|
||||
" stored in the onboard EEPROM on TRAB board\n"
|
||||
);
|
||||
|
||||
static int read_dip (void)
|
||||
{
|
||||
unsigned int result = 0;
|
||||
int adc_val;
|
||||
int i;
|
||||
|
||||
/***********************************************************
|
||||
DIP switch connection (according to wa4-cpu.sp.301.pdf, page 3):
|
||||
SW1 - AIN4
|
||||
SW2 - AIN5
|
||||
SW3 - AIN6
|
||||
SW4 - AIN7
|
||||
|
||||
"On" DIP switch position short-circuits the voltage from
|
||||
the input channel (i.e. '0' conversion result means "on").
|
||||
*************************************************************/
|
||||
|
||||
for (i = 7; i > 3; i--) {
|
||||
|
||||
if ((adc_val = adc_read (i)) == -1) {
|
||||
printf ("%s: Channel %d could not be read\n",
|
||||
__FUNCTION__, i);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Input voltage (switch open) is 1.8 V.
|
||||
* (Vin_High/VRef)*adc_res = (1,8V/2,5V)*1023) = 736
|
||||
* Set trigger at halve that value.
|
||||
*/
|
||||
if (adc_val < 368)
|
||||
result |= (1 << (i-4));
|
||||
}
|
||||
return (result);
|
||||
}
|
||||
|
||||
|
||||
static int read_vcc5v (void)
|
||||
{
|
||||
s32 result;
|
||||
|
||||
/* VCC5V is connected to channel 2 */
|
||||
|
||||
if ((result = adc_read (2)) == -1) {
|
||||
printf ("%s: VCC5V could not be read\n", __FUNCTION__);
|
||||
return (-1);
|
||||
}
|
||||
/*
|
||||
* Calculate voltage value. Split in two parts because there is no
|
||||
* floating point support. VCC5V is connected over an resistor divider:
|
||||
* VCC5V=ADCval*2,5V/1023*(10K+30K)/10K.
|
||||
*/
|
||||
result = result * 10 * 1000 / 1023; /* result in mV */
|
||||
|
||||
return (result);
|
||||
}
|
||||
|
||||
|
||||
static int test_dip (void)
|
||||
{
|
||||
static int first_run = 1;
|
||||
static int first_dip;
|
||||
|
||||
if (first_run) {
|
||||
if ((first_dip = read_dip ()) == -1) {
|
||||
return (1);
|
||||
}
|
||||
first_run = 0;
|
||||
debug ("%s: first_dip=%d\n", __FUNCTION__, first_dip);
|
||||
}
|
||||
if (first_dip != read_dip ()) {
|
||||
return (1);
|
||||
} else {
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int test_vcc5v (void)
|
||||
{
|
||||
int vcc5v;
|
||||
|
||||
if ((vcc5v = read_vcc5v ()) == -1) {
|
||||
return (1);
|
||||
}
|
||||
|
||||
if ((vcc5v > VCC5V_MAX) || (vcc5v < VCC5V_MIN)) {
|
||||
return (1);
|
||||
} else {
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int test_rotary_switch (void)
|
||||
{
|
||||
static int first_run = 1;
|
||||
static int first_rs;
|
||||
|
||||
if (first_run) {
|
||||
/*
|
||||
* clear bits in CPLD, because they have random values after
|
||||
* power-up or reset.
|
||||
*/
|
||||
*CPLD_ROTARY_SWITCH |= (1 << 16) | (1 << 17);
|
||||
|
||||
first_rs = ((*CPLD_ROTARY_SWITCH >> 16) & 0x7);
|
||||
first_run = 0;
|
||||
debug ("%s: first_rs=%d\n", __FUNCTION__, first_rs);
|
||||
}
|
||||
|
||||
if (first_rs != ((*CPLD_ROTARY_SWITCH >> 16) & 0x7)) {
|
||||
return (1);
|
||||
} else {
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int test_sram (void)
|
||||
{
|
||||
return (memory_post_tests (SRAM_ADDR, SRAM_SIZE));
|
||||
}
|
||||
|
||||
|
||||
static int test_eeprom (void)
|
||||
{
|
||||
unsigned char temp[sizeof (EEPROM_TEST_STRING_1)];
|
||||
int result = 0;
|
||||
|
||||
/* write test string 1, read back and verify */
|
||||
if (i2c_write_multiple (I2C_EEPROM_DEV_ADDR, EE_ADDR_TEST, 1,
|
||||
EEPROM_TEST_STRING_1,
|
||||
sizeof (EEPROM_TEST_STRING_1))) {
|
||||
return (1);
|
||||
}
|
||||
|
||||
if (i2c_read_multiple (I2C_EEPROM_DEV_ADDR, EE_ADDR_TEST, 1,
|
||||
temp, sizeof (EEPROM_TEST_STRING_1))) {
|
||||
return (1);
|
||||
}
|
||||
|
||||
if (strcmp (temp, EEPROM_TEST_STRING_1) != 0) {
|
||||
result = 1;
|
||||
printf ("%s: error; read_str = \"%s\"\n", __FUNCTION__, temp);
|
||||
}
|
||||
|
||||
/* write test string 2, read back and verify */
|
||||
if (result == 0) {
|
||||
if (i2c_write_multiple (I2C_EEPROM_DEV_ADDR, EE_ADDR_TEST, 1,
|
||||
EEPROM_TEST_STRING_2,
|
||||
sizeof (EEPROM_TEST_STRING_2))) {
|
||||
return (1);
|
||||
}
|
||||
|
||||
if (i2c_read_multiple (I2C_EEPROM_DEV_ADDR, EE_ADDR_TEST, 1,
|
||||
temp, sizeof (EEPROM_TEST_STRING_2))) {
|
||||
return (1);
|
||||
}
|
||||
|
||||
if (strcmp (temp, EEPROM_TEST_STRING_2) != 0) {
|
||||
result = 1;
|
||||
printf ("%s: error; read str = \"%s\"\n",
|
||||
__FUNCTION__, temp);
|
||||
}
|
||||
}
|
||||
return (result);
|
||||
}
|
||||
|
||||
|
||||
static int test_contact_temp (void)
|
||||
{
|
||||
int contact_temp;
|
||||
|
||||
spi_init ();
|
||||
contact_temp = tsc2000_contact_temp ();
|
||||
|
||||
if ((contact_temp < MIN_CONTACT_TEMP)
|
||||
|| (contact_temp > MAX_CONTACT_TEMP))
|
||||
return (1);
|
||||
else
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
static int i2c_write_multiple (uchar chip, uint addr, int alen,
|
||||
uchar *buffer, int len)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (alen != 1) {
|
||||
printf ("%s: addr len other than 1 not supported\n",
|
||||
__FUNCTION__);
|
||||
return (1);
|
||||
}
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
if (i2c_write (chip, addr+i, alen, buffer+i, 1)) {
|
||||
printf ("%s: could not write to i2c device %d"
|
||||
", addr %d\n", __FUNCTION__, chip, addr);
|
||||
return (1);
|
||||
}
|
||||
#if 0
|
||||
printf ("chip=%#x, addr+i=%#x+%d=%p, alen=%d, *buffer+i="
|
||||
"%#x+%d=%p=\"%.1s\"\n", chip, addr, i, addr+i,
|
||||
alen, buffer, i, buffer+i, buffer+i);
|
||||
#endif
|
||||
|
||||
udelay (30000);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
static int i2c_read_multiple (uchar chip, uint addr, int alen,
|
||||
uchar *buffer, int len)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (alen != 1) {
|
||||
printf ("%s: addr len other than 1 not supported\n",
|
||||
__FUNCTION__);
|
||||
return (1);
|
||||
}
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
if (i2c_read (chip, addr+i, alen, buffer+i, 1)) {
|
||||
printf ("%s: could not read from i2c device %#x"
|
||||
", addr %d\n", __FUNCTION__, chip, addr);
|
||||
return (1);
|
||||
}
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
static int adc_read (unsigned int channel)
|
||||
{
|
||||
int j = 1000; /* timeout value for wait loop in us */
|
||||
S3C2400_ADC *padc;
|
||||
|
||||
padc = S3C2400_GetBase_ADC();
|
||||
channel &= 0x7;
|
||||
|
||||
adc_init ();
|
||||
|
||||
debug ("%s: adccon %#x\n", __FUNCTION__, padc->ADCCON);
|
||||
|
||||
padc->ADCCON &= ~ADC_STDBM; /* select normal mode */
|
||||
padc->ADCCON &= ~(0x7 << 3); /* clear the channel bits */
|
||||
padc->ADCCON |= ((channel << 3) | ADC_ENABLE_START);
|
||||
|
||||
debug ("%s: reading ch %d, addcon %#x\n", __FUNCTION__,
|
||||
(padc->ADCCON >> 3) & 0x7, padc->ADCCON);
|
||||
|
||||
while (j--) {
|
||||
if ((padc->ADCCON & ADC_ENABLE_START) == 0)
|
||||
break;
|
||||
udelay (1);
|
||||
}
|
||||
|
||||
if (j == 0) {
|
||||
printf("%s: ADC timeout\n", __FUNCTION__);
|
||||
padc->ADCCON |= ADC_STDBM; /* select standby mode */
|
||||
return -1;
|
||||
}
|
||||
|
||||
padc->ADCCON |= ADC_STDBM; /* select standby mode */
|
||||
|
||||
debug ("%s: return %#x, adccon %#x\n", __FUNCTION__,
|
||||
padc->ADCDAT & 0x3FF, padc->ADCCON);
|
||||
|
||||
return (padc->ADCDAT & 0x3FF);
|
||||
}
|
||||
|
||||
|
||||
static void adc_init (void)
|
||||
{
|
||||
S3C2400_ADC *padc;
|
||||
|
||||
padc = S3C2400_GetBase_ADC();
|
||||
|
||||
padc->ADCCON &= ~(0xff << 6); /* clear prescaler bits */
|
||||
padc->ADCCON |= ((65 << 6) | ADC_PRSCEN); /* set prescaler */
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
static void led_set (unsigned int state)
|
||||
{
|
||||
S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
|
||||
|
||||
led_init ();
|
||||
|
||||
switch (state) {
|
||||
case 0: /* turn LED off */
|
||||
gpio->PADAT |= (1 << 12);
|
||||
break;
|
||||
case 1: /* turn LED on */
|
||||
gpio->PADAT &= ~(1 << 12);
|
||||
break;
|
||||
default:
|
||||
}
|
||||
}
|
||||
|
||||
static void led_blink (void)
|
||||
{
|
||||
led_init ();
|
||||
|
||||
/* blink LED. This function does not return! */
|
||||
while (1) {
|
||||
led_set (1);
|
||||
udelay (1000000 / LED_BLINK_FREQ / 2);
|
||||
led_set (0);
|
||||
udelay (1000000 / LED_BLINK_FREQ / 2);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void led_init (void)
|
||||
{
|
||||
S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
|
||||
|
||||
/* configure GPA12 as output and set to High -> LED off */
|
||||
gpio->PACON &= ~(1 << 12);
|
||||
gpio->PADAT |= (1 << 12);
|
||||
}
|
||||
|
||||
|
||||
static void sdelay (unsigned long seconds)
|
||||
{
|
||||
unsigned long i;
|
||||
|
||||
for (i = 0; i < seconds; i++) {
|
||||
udelay (1000000);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int global_vars_write_to_eeprom (void)
|
||||
{
|
||||
if (i2c_write_multiple (I2C_EEPROM_DEV_ADDR, EE_ADDR_STATUS, 1,
|
||||
(unsigned char*) &status, 1)) {
|
||||
return (1);
|
||||
}
|
||||
if (i2c_write_multiple (I2C_EEPROM_DEV_ADDR, EE_ADDR_PASS_CYCLES, 1,
|
||||
(unsigned char*) &pass_cycles, 2)) {
|
||||
return (1);
|
||||
}
|
||||
if (i2c_write_multiple (I2C_EEPROM_DEV_ADDR, EE_ADDR_FIRST_ERROR_CYCLE,
|
||||
1, (unsigned char*) &first_error_cycle, 2)) {
|
||||
return (1);
|
||||
}
|
||||
if (i2c_write_multiple (I2C_EEPROM_DEV_ADDR, EE_ADDR_FIRST_ERROR_NUM,
|
||||
1, (unsigned char*) &first_error_num, 1)) {
|
||||
return (1);
|
||||
}
|
||||
if (i2c_write_multiple (I2C_EEPROM_DEV_ADDR, EE_ADDR_FIRST_ERROR_NAME,
|
||||
1, first_error_name,
|
||||
sizeof(first_error_name))) {
|
||||
return (1);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
static void global_vars_init (void)
|
||||
{
|
||||
status = 1; /* error */
|
||||
pass_cycles = 0;
|
||||
first_error_cycle = 0;
|
||||
first_error_num = 0;
|
||||
first_error_name[0] = '\0';
|
||||
act_cycle = 0;
|
||||
max_cycles = 0;
|
||||
}
|
||||
|
||||
|
||||
static void test_function_table_init (void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < BIF_MAX; i++)
|
||||
test_function[i].pf = dummy;
|
||||
|
||||
/*
|
||||
* the length of "name" must not exceed 16, including the '\0'
|
||||
* termination. See also the EEPROM address map.
|
||||
*/
|
||||
test_function[0].pf = test_dip;
|
||||
test_function[0].name = "dip";
|
||||
|
||||
test_function[1].pf = test_vcc5v;
|
||||
test_function[1].name = "vcc5v";
|
||||
|
||||
test_function[2].pf = test_rotary_switch;
|
||||
test_function[2].name = "rotary_switch";
|
||||
|
||||
test_function[3].pf = test_sram;
|
||||
test_function[3].name = "sram";
|
||||
|
||||
test_function[4].pf = test_eeprom;
|
||||
test_function[4].name = "eeprom";
|
||||
|
||||
test_function[5].pf = test_contact_temp;
|
||||
test_function[5].name = "contact_temp";
|
||||
}
|
||||
|
||||
|
||||
static int read_max_cycles (void)
|
||||
{
|
||||
if (i2c_read_multiple (I2C_EEPROM_DEV_ADDR, EE_ADDR_MAX_CYCLES, 1,
|
||||
(unsigned char *) &max_cycles, 2) != 0) {
|
||||
return (1);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int dummy(void)
|
||||
{
|
||||
return (0);
|
||||
}
|
||||
|
||||
#endif /* CFG_CMD_BSP */
|
||||
484
board/trab/memory.c
Normal file
484
board/trab/memory.c
Normal file
@@ -0,0 +1,484 @@
|
||||
/*
|
||||
* (C) Copyright 2002-2003
|
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
|
||||
/* 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 slow-test 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;
|
||||
|
||||
printf ("Memory (date line) error at %08lx, "
|
||||
"wrote %08x%08x, read %08x%08x !\n",
|
||||
(ulong)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 = (ulong *)((ulong)base + size); /* pointer arith! */
|
||||
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) {
|
||||
printf ("Memory (address line) error at %08lx<->%08lx, "
|
||||
"XOR value %08lx !\n",
|
||||
(ulong)testaddr, (ulong)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) {
|
||||
printf ("Memory error at %08lx, "
|
||||
"wrote %08lx, read %08lx !\n",
|
||||
(ulong)(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))) {
|
||||
printf ("Memory error at %08lx, "
|
||||
"wrote %08x, read %08lx !\n",
|
||||
(ulong)(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) {
|
||||
printf ("Memory error at %08lx, "
|
||||
"wrote %08lx, read %08lx !\n",
|
||||
(ulong)(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) {
|
||||
printf ("Memory error at %08lx, "
|
||||
"wrote %08lx, read %08lx !\n",
|
||||
(ulong)(mem + i), ~i, readback);
|
||||
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
if (i % 1024 == 0)
|
||||
WATCHDOG_RESET ();
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
#if 0
|
||||
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_SLOWTEST) {
|
||||
ret = memory_post_tests (CFG_SDRAM_BASE, memsize);
|
||||
} else { /* POST_NORMAL */
|
||||
|
||||
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 0
|
||||
|
||||
/* #endif */ /* CONFIG_POST & CFG_POST_MEMORY */
|
||||
/* #endif */ /* CONFIG_POST */
|
||||
@@ -105,6 +105,10 @@ int board_init ()
|
||||
gpio->PGUP = 0x0;
|
||||
gpio->OPENCR= 0x0;
|
||||
|
||||
/* suppress flicker of the VFDs */
|
||||
gpio->MISCCR = 0x40;
|
||||
gpio->PFCON |= (2<<12);
|
||||
|
||||
/* arch number of SAMSUNG-Board */
|
||||
/* MACH_TYPE_SMDK2400 */
|
||||
/* XXX this isn't really correct, but keep it for now */
|
||||
|
||||
317
board/trab/tsc2000.c
Normal file
317
board/trab/tsc2000.c
Normal file
@@ -0,0 +1,317 @@
|
||||
/*
|
||||
* Functions to access the TSC2000 controller on TRAB board (used for scanning
|
||||
* thermo sensors)
|
||||
*
|
||||
* Copyright (C) 2003 Martin Krause, TQ-Systems GmbH, martin.krause@tqs.de
|
||||
*
|
||||
* Copyright (C) 2002 DENX Software Engineering, 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 <common.h>
|
||||
#include <s3c2400.h>
|
||||
#include "tsc2000.h"
|
||||
|
||||
void spi_init(void)
|
||||
{
|
||||
S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
|
||||
S3C24X0_SPI * const spi = S3C24X0_GetBase_SPI();
|
||||
int i;
|
||||
|
||||
/* Configure I/O ports. */
|
||||
gpio->PDCON = (gpio->PDCON & 0xF3FFFF) | 0x040000;
|
||||
gpio->PGCON = (gpio->PGCON & 0x0F3FFF) | 0x008000;
|
||||
gpio->PGCON = (gpio->PGCON & 0x0CFFFF) | 0x020000;
|
||||
gpio->PGCON = (gpio->PGCON & 0x03FFFF) | 0x080000;
|
||||
|
||||
CLR_CS_TOUCH();
|
||||
|
||||
spi->ch[0].SPPRE = 0x1F; /* Baud-rate ca. 514kHz */
|
||||
spi->ch[0].SPPIN = 0x01; /* SPI-MOSI holds Level after last bit */
|
||||
spi->ch[0].SPCON = 0x1A; /* Polling, Prescaler, Master, CPOL=0,
|
||||
CPHA=1 */
|
||||
|
||||
/* Dummy byte ensures clock to be low. */
|
||||
for (i = 0; i < 10; i++) {
|
||||
spi->ch[0].SPTDAT = 0xFF;
|
||||
}
|
||||
spi_wait_transmit_done();
|
||||
}
|
||||
|
||||
|
||||
static void spi_wait_transmit_done(void)
|
||||
{
|
||||
S3C24X0_SPI * const spi = S3C24X0_GetBase_SPI();
|
||||
|
||||
while (!(spi->ch[0].SPSTA & 0x01)); /* wait until transfer is done */
|
||||
}
|
||||
|
||||
|
||||
static void tsc2000_write(unsigned short reg, unsigned short data)
|
||||
{
|
||||
S3C24X0_SPI * const spi = S3C24X0_GetBase_SPI();
|
||||
unsigned int command;
|
||||
|
||||
SET_CS_TOUCH();
|
||||
command = reg;
|
||||
spi->ch[0].SPTDAT = (command & 0xFF00) >> 8;
|
||||
spi_wait_transmit_done();
|
||||
spi->ch[0].SPTDAT = (command & 0x00FF);
|
||||
spi_wait_transmit_done();
|
||||
spi->ch[0].SPTDAT = (data & 0xFF00) >> 8;
|
||||
spi_wait_transmit_done();
|
||||
spi->ch[0].SPTDAT = (data & 0x00FF);
|
||||
spi_wait_transmit_done();
|
||||
|
||||
CLR_CS_TOUCH();
|
||||
}
|
||||
|
||||
|
||||
static unsigned short tsc2000_read (unsigned short reg)
|
||||
{
|
||||
unsigned short command, data;
|
||||
S3C24X0_SPI * const spi = S3C24X0_GetBase_SPI();
|
||||
|
||||
SET_CS_TOUCH();
|
||||
command = 0x8000 | reg;
|
||||
|
||||
spi->ch[0].SPTDAT = (command & 0xFF00) >> 8;
|
||||
spi_wait_transmit_done();
|
||||
spi->ch[0].SPTDAT = (command & 0x00FF);
|
||||
spi_wait_transmit_done();
|
||||
|
||||
spi->ch[0].SPTDAT = 0xFF;
|
||||
spi_wait_transmit_done();
|
||||
data = spi->ch[0].SPRDAT;
|
||||
spi->ch[0].SPTDAT = 0xFF;
|
||||
spi_wait_transmit_done();
|
||||
|
||||
CLR_CS_TOUCH();
|
||||
return (spi->ch[0].SPRDAT & 0x0FF) | (data << 8);
|
||||
}
|
||||
|
||||
|
||||
static void tsc2000_set_mux (unsigned int channel)
|
||||
{
|
||||
S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
|
||||
|
||||
CLR_MUX1_ENABLE; CLR_MUX2_ENABLE;
|
||||
CLR_MUX3_ENABLE; CLR_MUX4_ENABLE;
|
||||
switch (channel) {
|
||||
case 0:
|
||||
CLR_MUX0; CLR_MUX1;
|
||||
SET_MUX1_ENABLE;
|
||||
break;
|
||||
case 1:
|
||||
SET_MUX0; CLR_MUX1;
|
||||
SET_MUX1_ENABLE;
|
||||
break;
|
||||
case 2:
|
||||
CLR_MUX0; SET_MUX1;
|
||||
SET_MUX1_ENABLE;
|
||||
break;
|
||||
case 3:
|
||||
SET_MUX0; SET_MUX1;
|
||||
SET_MUX1_ENABLE;
|
||||
break;
|
||||
case 4:
|
||||
CLR_MUX0; CLR_MUX1;
|
||||
SET_MUX2_ENABLE;
|
||||
break;
|
||||
case 5:
|
||||
SET_MUX0; CLR_MUX1;
|
||||
SET_MUX2_ENABLE;
|
||||
break;
|
||||
case 6:
|
||||
CLR_MUX0; SET_MUX1;
|
||||
SET_MUX2_ENABLE;
|
||||
break;
|
||||
case 7:
|
||||
SET_MUX0; SET_MUX1;
|
||||
SET_MUX2_ENABLE;
|
||||
break;
|
||||
case 8:
|
||||
CLR_MUX0; CLR_MUX1;
|
||||
SET_MUX3_ENABLE;
|
||||
break;
|
||||
case 9:
|
||||
SET_MUX0; CLR_MUX1;
|
||||
SET_MUX3_ENABLE;
|
||||
break;
|
||||
case 10:
|
||||
CLR_MUX0; SET_MUX1;
|
||||
SET_MUX3_ENABLE;
|
||||
break;
|
||||
case 11:
|
||||
SET_MUX0; SET_MUX1;
|
||||
SET_MUX3_ENABLE;
|
||||
break;
|
||||
case 12:
|
||||
CLR_MUX0; CLR_MUX1;
|
||||
SET_MUX4_ENABLE;
|
||||
break;
|
||||
case 13:
|
||||
SET_MUX0; CLR_MUX1;
|
||||
SET_MUX4_ENABLE;
|
||||
break;
|
||||
case 14:
|
||||
CLR_MUX0; SET_MUX1;
|
||||
SET_MUX4_ENABLE;
|
||||
break;
|
||||
case 15:
|
||||
SET_MUX0; SET_MUX1;
|
||||
SET_MUX4_ENABLE;
|
||||
break;
|
||||
default:
|
||||
CLR_MUX0; CLR_MUX1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void tsc2000_set_range (unsigned int range)
|
||||
{
|
||||
S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
|
||||
|
||||
switch (range) {
|
||||
case 1:
|
||||
CLR_SEL_TEMP_V_0; SET_SEL_TEMP_V_1;
|
||||
CLR_SEL_TEMP_V_2; CLR_SEL_TEMP_V_3;
|
||||
break;
|
||||
case 2:
|
||||
CLR_SEL_TEMP_V_0; CLR_SEL_TEMP_V_1;
|
||||
CLR_SEL_TEMP_V_2; SET_SEL_TEMP_V_3;
|
||||
break;
|
||||
case 3:
|
||||
SET_SEL_TEMP_V_0; CLR_SEL_TEMP_V_1;
|
||||
SET_SEL_TEMP_V_2; CLR_SEL_TEMP_V_3;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static u16 tsc2000_read_channel (unsigned int channel)
|
||||
{
|
||||
u16 res;
|
||||
|
||||
tsc2000_set_mux(channel);
|
||||
udelay(3 * TSC2000_DELAY_BASE);
|
||||
|
||||
tsc2000_write(TSC2000_REG_ADC, 0x2036);
|
||||
adc_wait_conversion_done ();
|
||||
res = tsc2000_read(TSC2000_REG_AUX1);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
s32 tsc2000_contact_temp (void)
|
||||
{
|
||||
long adc_pt1000, offset;
|
||||
long u_pt1000;
|
||||
long contact_temp;
|
||||
|
||||
|
||||
tsc2000_reg_init ();
|
||||
tsc2000_set_range (3);
|
||||
|
||||
adc_pt1000 = tsc2000_read_channel (14);
|
||||
debug ("read channel 14 (pt1000 adc value): %ld\n", adc_pt1000);
|
||||
|
||||
offset = tsc2000_read_channel (15);
|
||||
debug ("read channel 15 (offset): %ld\n", offset);
|
||||
|
||||
/*
|
||||
* Formula for calculating voltage drop on PT1000 resistor: u_pt1000 =
|
||||
* x_range3 * (adc_raw - offset) / 10. Formula to calculate x_range3:
|
||||
* x_range3 = (2500 * (1000000 + err_vref + err_amp3)) / (4095*6). The
|
||||
* error correction Values err_vref and err_amp3 are assumed as 0 in
|
||||
* u-boot, because this could cause only a very small error (< 1%).
|
||||
*/
|
||||
u_pt1000 = (101750 * (adc_pt1000 - offset)) / 10;
|
||||
debug ("u_pt1000: %ld\n", u_pt1000);
|
||||
|
||||
if (tsc2000_interpolate(u_pt1000, Pt1000_temp_table,
|
||||
&contact_temp) == -1) {
|
||||
printf ("%s: error interpolating PT1000 vlaue\n",
|
||||
__FUNCTION__);
|
||||
return (-1000);
|
||||
}
|
||||
debug ("contact_temp: %ld\n", contact_temp);
|
||||
|
||||
return contact_temp;
|
||||
}
|
||||
|
||||
|
||||
void tsc2000_reg_init (void)
|
||||
{
|
||||
S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
|
||||
|
||||
tsc2000_write(TSC2000_REG_ADC, 0x2036);
|
||||
tsc2000_write(TSC2000_REG_REF, 0x0011);
|
||||
tsc2000_write(TSC2000_REG_DACCTL, 0x0000);
|
||||
|
||||
CON_MUX0;
|
||||
CON_MUX1;
|
||||
|
||||
CON_MUX1_ENABLE;
|
||||
CON_MUX2_ENABLE;
|
||||
CON_MUX3_ENABLE;
|
||||
CON_MUX4_ENABLE;
|
||||
|
||||
CON_SEL_TEMP_V_0;
|
||||
CON_SEL_TEMP_V_1;
|
||||
CON_SEL_TEMP_V_2;
|
||||
CON_SEL_TEMP_V_3;
|
||||
|
||||
tsc2000_set_mux(0);
|
||||
tsc2000_set_range(0);
|
||||
}
|
||||
|
||||
|
||||
static int tsc2000_interpolate(long value, long data[][2], long *result)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* the data is sorted and the first element is upper
|
||||
* limit so we can easily check for out-of-band values
|
||||
*/
|
||||
if (data[0][0] < value || data[1][0] > value)
|
||||
return -1;
|
||||
|
||||
i = 1;
|
||||
while (data[i][0] < value)
|
||||
i++;
|
||||
|
||||
/* To prevent overflow we have to store the intermediate
|
||||
result in 'long long'.
|
||||
*/
|
||||
|
||||
*result = data[i-1][1] +
|
||||
((unsigned long long)(data[i][1] - data[i-1][1])
|
||||
* (unsigned long long)(value - data[i-1][0]))
|
||||
/ (data[i][0] - data[i-1][0]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void adc_wait_conversion_done(void)
|
||||
{
|
||||
while (!(tsc2000_read(TSC2000_REG_ADC) & (1 << 14)));
|
||||
}
|
||||
147
board/trab/tsc2000.h
Normal file
147
board/trab/tsc2000.h
Normal file
@@ -0,0 +1,147 @@
|
||||
/*
|
||||
* Functions to access the TSC2000 controller on TRAB board (used for scanning
|
||||
* thermo sensors)
|
||||
*
|
||||
* Copyright (C) 2003 Martin Krause, TQ-Systems GmbH, martin.krause@tqs.de
|
||||
*
|
||||
* Copyright (C) 2002 DENX Software Engineering, 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
|
||||
*/
|
||||
|
||||
#ifndef _TSC2000_H_
|
||||
#define _TSC2000_H_
|
||||
|
||||
#include "Pt1000_temp_data.h"
|
||||
|
||||
/* temperature channel multiplexer definitions */
|
||||
#define CON_MUX0 (gpio->PCCON = (gpio->PCCON & 0x0FFFFFCFF) | 0x00000100)
|
||||
#define CLR_MUX0 (gpio->PCDAT &= 0x0FFEF)
|
||||
#define SET_MUX0 (gpio->PCDAT |= 0x00010)
|
||||
|
||||
#define CON_MUX1 (gpio->PCCON = (gpio->PCCON & 0x0FFFFF3FF) | 0x00000400)
|
||||
#define CLR_MUX1 (gpio->PCDAT &= 0x0FFDF)
|
||||
#define SET_MUX1 (gpio->PCDAT |= 0x00020)
|
||||
|
||||
#define CON_MUX1_ENABLE (gpio->PCCON = (gpio->PCCON & 0x0FFFFCFFF) | 0x00001000)
|
||||
#define CLR_MUX1_ENABLE (gpio->PCDAT |= 0x00040)
|
||||
#define SET_MUX1_ENABLE (gpio->PCDAT &= 0x0FFBF)
|
||||
|
||||
#define CON_MUX2_ENABLE (gpio->PCCON = (gpio->PCCON & 0x0FFFF3FFF) | 0x00004000)
|
||||
#define CLR_MUX2_ENABLE (gpio->PCDAT |= 0x00080)
|
||||
#define SET_MUX2_ENABLE (gpio->PCDAT &= 0x0FF7F)
|
||||
|
||||
#define CON_MUX3_ENABLE (gpio->PCCON = (gpio->PCCON & 0x0FFFCFFFF) | 0x00010000)
|
||||
#define CLR_MUX3_ENABLE (gpio->PCDAT |= 0x00100)
|
||||
#define SET_MUX3_ENABLE (gpio->PCDAT &= 0x0FEFF)
|
||||
|
||||
#define CON_MUX4_ENABLE (gpio->PCCON = (gpio->PCCON & 0x0FFF3FFFF) | 0x00040000)
|
||||
#define CLR_MUX4_ENABLE (gpio->PCDAT |= 0x00200)
|
||||
#define SET_MUX4_ENABLE (gpio->PCDAT &= 0x0FDFF)
|
||||
|
||||
#define CON_SEL_TEMP_V_0 (gpio->PCCON = (gpio->PCCON & 0x0FFCFFFFF) | 0x00100000)
|
||||
#define CLR_SEL_TEMP_V_0 (gpio->PCDAT &= 0x0FBFF)
|
||||
#define SET_SEL_TEMP_V_0 (gpio->PCDAT |= 0x00400)
|
||||
|
||||
#define CON_SEL_TEMP_V_1 (gpio->PCCON = (gpio->PCCON & 0x0FF3FFFFF) | 0x00400000)
|
||||
#define CLR_SEL_TEMP_V_1 (gpio->PCDAT &= 0x0F7FF)
|
||||
#define SET_SEL_TEMP_V_1 (gpio->PCDAT |= 0x00800)
|
||||
|
||||
#define CON_SEL_TEMP_V_2 (gpio->PCCON = (gpio->PCCON & 0x0FCFFFFFF) | 0x01000000)
|
||||
#define CLR_SEL_TEMP_V_2 (gpio->PCDAT &= 0x0EFFF)
|
||||
#define SET_SEL_TEMP_V_2 (gpio->PCDAT |= 0x01000)
|
||||
|
||||
#define CON_SEL_TEMP_V_3 (gpio->PCCON = (gpio->PCCON & 0x0F3FFFFFF) | 0x04000000)
|
||||
#define CLR_SEL_TEMP_V_3 (gpio->PCDAT &= 0x0DFFF)
|
||||
#define SET_SEL_TEMP_V_3 (gpio->PCDAT |= 0x02000)
|
||||
|
||||
/* TSC2000 register definition */
|
||||
#define TSC2000_REG_X ((0 << 11) | (0 << 5))
|
||||
#define TSC2000_REG_Y ((0 << 11) | (1 << 5))
|
||||
#define TSC2000_REG_Z1 ((0 << 11) | (2 << 5))
|
||||
#define TSC2000_REG_Z2 ((0 << 11) | (3 << 5))
|
||||
#define TSC2000_REG_BAT1 ((0 << 11) | (5 << 5))
|
||||
#define TSC2000_REG_BAT2 ((0 << 11) | (6 << 5))
|
||||
#define TSC2000_REG_AUX1 ((0 << 11) | (7 << 5))
|
||||
#define TSC2000_REG_AUX2 ((0 << 11) | (8 << 5))
|
||||
#define TSC2000_REG_TEMP1 ((0 << 11) | (9 << 5))
|
||||
#define TSC2000_REG_TEMP2 ((0 << 11) | (0xA << 5))
|
||||
#define TSC2000_REG_DAC ((0 << 11) | (0xB << 5))
|
||||
#define TSC2000_REG_ZERO ((0 << 11) | (0x10 << 5))
|
||||
#define TSC2000_REG_ADC ((1 << 11) | (0 << 5))
|
||||
#define TSC2000_REG_DACCTL ((1 << 11) | (2 << 5))
|
||||
#define TSC2000_REG_REF ((1 << 11) | (3 << 5))
|
||||
#define TSC2000_REG_RESET ((1 << 11) | (4 << 5))
|
||||
#define TSC2000_REG_CONFIG ((1 << 11) | (5 << 5))
|
||||
|
||||
/* bit definition of TSC2000 ADC register */
|
||||
#define TC_PSM (1 << 15)
|
||||
#define TC_STS (1 << 14)
|
||||
#define TC_AD3 (1 << 13)
|
||||
#define TC_AD2 (1 << 12)
|
||||
#define TC_AD1 (1 << 11)
|
||||
#define TC_AD0 (1 << 10)
|
||||
#define TC_RS1 (1 << 9)
|
||||
#define TC_RS0 (1 << 8)
|
||||
#define TC_AV1 (1 << 7)
|
||||
#define TC_AV0 (1 << 6)
|
||||
#define TC_CL1 (1 << 5)
|
||||
#define TC_CL0 (1 << 4)
|
||||
#define TC_PV2 (1 << 3)
|
||||
#define TC_PV1 (1 << 2)
|
||||
#define TC_PV0 (1 << 1)
|
||||
|
||||
/* default value for TSC2000 ADC register for use with touch functions */
|
||||
#define DEFAULT_ADC (TC_PV1 | TC_AV0 | TC_AV1 | TC_RS0)
|
||||
|
||||
#define TSC2000_DELAY_BASE 500
|
||||
#define TSC2000_NO_SENSOR -0x10000
|
||||
|
||||
#define ERROR_BATTERY 220 /* must be adjusted, if R68 is changed on
|
||||
* TRAB */
|
||||
|
||||
static void tsc2000_write(unsigned short, unsigned short);
|
||||
static unsigned short tsc2000_read (unsigned short);
|
||||
static u16 tsc2000_read_channel (unsigned int);
|
||||
static void tsc2000_set_mux (unsigned int);
|
||||
static void tsc2000_set_range (unsigned int);
|
||||
void tsc2000_reg_init (void);
|
||||
s32 tsc2000_contact_temp (void);
|
||||
static void spi_wait_transmit_done (void);
|
||||
void spi_init(void);
|
||||
static int tsc2000_interpolate(long value, long data[][2], long *result);
|
||||
static void adc_wait_conversion_done(void);
|
||||
|
||||
|
||||
static inline void SET_CS_TOUCH(void)
|
||||
{
|
||||
S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
|
||||
|
||||
gpio->PDDAT &= 0x5FF;
|
||||
}
|
||||
|
||||
|
||||
static inline void CLR_CS_TOUCH(void)
|
||||
{
|
||||
S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
|
||||
|
||||
gpio->PDDAT |= 0x200;
|
||||
}
|
||||
|
||||
#endif /* _TSC2000_H_ */
|
||||
@@ -81,7 +81,7 @@ int do_bdinfo ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
|
||||
for (i=0; i<6; ++i) {
|
||||
printf ("%c%02X", i ? ':' : ' ', bd->bi_enetaddr[i]);
|
||||
}
|
||||
#ifdef CONFIG_PN62
|
||||
#if (defined CONFIG_PN62) || (defined CONFIG_PPCHAMELEONEVB)
|
||||
printf ("\neth1addr =");
|
||||
for (i=0; i<6; ++i) {
|
||||
printf ("%c%02X", i ? ':' : ' ', bd->bi_enet1addr[i]);
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
#include <image.h>
|
||||
#include <malloc.h>
|
||||
#include <zlib.h>
|
||||
#include <bzlib.h>
|
||||
#include <environment.h>
|
||||
#include <asm/byteorder.h>
|
||||
|
||||
@@ -142,6 +143,7 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
|
||||
ulong addr;
|
||||
ulong data, len, checksum;
|
||||
ulong *len_ptr;
|
||||
uint unc_len = 0x400000;
|
||||
int i, verify;
|
||||
char *name, *s;
|
||||
int (*appl)(cmd_tbl_t *, int, int, char *[]);
|
||||
@@ -307,13 +309,26 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
|
||||
break;
|
||||
case IH_COMP_GZIP:
|
||||
printf (" Uncompressing %s ... ", name);
|
||||
if (gunzip ((void *)ntohl(hdr->ih_load), 0x400000,
|
||||
if (gunzip ((void *)ntohl(hdr->ih_load), unc_len,
|
||||
(uchar *)data, (int *)&len) != 0) {
|
||||
printf ("GUNZIP ERROR - must RESET board to recover\n");
|
||||
SHOW_BOOT_PROGRESS (-6);
|
||||
do_reset (cmdtp, flag, argc, argv);
|
||||
}
|
||||
break;
|
||||
#ifdef CONFIG_BZIP2
|
||||
case IH_COMP_BZIP2:
|
||||
printf (" Uncompressing %s ... ", name);
|
||||
i = BZ2_bzBuffToBuffDecompress ((char*)ntohl(hdr->ih_load),
|
||||
&unc_len, (char *)data, len, 0, 0);
|
||||
if (i != BZ_OK) {
|
||||
printf ("BUNZIP2 ERROR %d - must RESET board to recover\n", i);
|
||||
SHOW_BOOT_PROGRESS (-6);
|
||||
udelay(100000);
|
||||
do_reset (cmdtp, flag, argc, argv);
|
||||
}
|
||||
break;
|
||||
#endif /* CONFIG_BZIP2 */
|
||||
default:
|
||||
if (iflag)
|
||||
enable_interrupts();
|
||||
@@ -1206,6 +1221,13 @@ int gunzip(void *dst, int dstlen, unsigned char *src, int *lenp)
|
||||
return (0);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_BZIP2
|
||||
void bz_internal_error(int errcode)
|
||||
{
|
||||
printf ("BZIP2 internal error %d\n", errcode);
|
||||
}
|
||||
#endif /* CONFIG_BZIP2 */
|
||||
|
||||
static void
|
||||
do_bootm_rtems (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],
|
||||
ulong addr, ulong *len_ptr, int verify)
|
||||
|
||||
@@ -525,7 +525,7 @@ static int DoC_Address(struct DiskOnChip *doc, int numbytes, unsigned long ofs,
|
||||
return DoC_WaitReady(doc);
|
||||
}
|
||||
|
||||
/* Read a buffer from DoC, taking care of Millennium odditys */
|
||||
/* Read a buffer from DoC, taking care of Millennium oddities */
|
||||
static void DoC_ReadBuf(struct DiskOnChip *doc, u_char * buf, int len)
|
||||
{
|
||||
volatile int dummy;
|
||||
@@ -558,7 +558,7 @@ static void DoC_ReadBuf(struct DiskOnChip *doc, u_char * buf, int len)
|
||||
}
|
||||
}
|
||||
|
||||
/* Write a buffer to DoC, taking care of Millennium odditys */
|
||||
/* Write a buffer to DoC, taking care of Millennium oddities */
|
||||
static void DoC_WriteBuf(struct DiskOnChip *doc, const u_char * buf, int len)
|
||||
{
|
||||
unsigned long docptr;
|
||||
@@ -861,8 +861,13 @@ static int find_boot_record(struct NFTLrecord *nftl)
|
||||
memcpy(mh, buf, sizeof(struct NFTLMediaHeader));
|
||||
|
||||
/* Do some sanity checks on it */
|
||||
if (mh->UnitSizeFactor != 0xff) {
|
||||
puts ("Sorry, we don't support UnitSizeFactor "
|
||||
if (mh->UnitSizeFactor == 0) {
|
||||
#ifdef NFTL_DEBUG
|
||||
puts ("UnitSizeFactor 0x00 detected.\n"
|
||||
"This violates the spec but we think we know what it means...\n");
|
||||
#endif
|
||||
} else if (mh->UnitSizeFactor != 0xff) {
|
||||
printf ("Sorry, we don't support UnitSizeFactor "
|
||||
"of != 1 yet.\n");
|
||||
return -1;
|
||||
}
|
||||
@@ -950,6 +955,8 @@ static void DoC2k_init(struct DiskOnChip* this)
|
||||
|
||||
/* Ident all the chips present. */
|
||||
DoC_ScanChips(this);
|
||||
if ((!this->numchips) || (!this->chips))
|
||||
return;
|
||||
|
||||
nftl = &this->nftl;
|
||||
|
||||
@@ -992,7 +999,7 @@ int doc_read_ecc(struct DiskOnChip* this, loff_t from, size_t len,
|
||||
printf("ECC needs a full sector read (adr: %lx size %lx)\n",
|
||||
(long) from, (long) len);
|
||||
|
||||
#ifdef PHYCH_DEBUG
|
||||
#ifdef PSYCHO_DEBUG
|
||||
printf("DoC_Read (adr: %lx size %lx)\n", (long) from, (long) len);
|
||||
#endif
|
||||
|
||||
|
||||
159
common/cmd_fat.c
159
common/cmd_fat.c
@@ -36,76 +36,179 @@
|
||||
|
||||
#include <fat.h>
|
||||
|
||||
extern block_dev_desc_t *ide_get_dev (int dev);
|
||||
|
||||
|
||||
|
||||
block_dev_desc_t *get_dev (char* ifname, int dev)
|
||||
{
|
||||
#if (CONFIG_COMMANDS & CFG_CMD_IDE)
|
||||
if (strncmp(ifname,"ide",3)==0) {
|
||||
extern block_dev_desc_t * ide_get_dev(int dev);
|
||||
return(ide_get_dev(dev));
|
||||
}
|
||||
#endif
|
||||
#if (CONFIG_COMMANDS & CFG_CMD_SCSI)
|
||||
if (strncmp(ifname,"scsi",4)==0) {
|
||||
extern block_dev_desc_t * scsi_get_dev(int dev);
|
||||
return(scsi_get_dev(dev));
|
||||
}
|
||||
#endif
|
||||
#if ((CONFIG_COMMANDS & CFG_CMD_USB) && defined(CONFIG_USB_STORAGE))
|
||||
if (strncmp(ifname,"usb",3)==0) {
|
||||
extern block_dev_desc_t * usb_stor_get_dev(int dev);
|
||||
return(usb_stor_get_dev(dev));
|
||||
}
|
||||
#endif
|
||||
#if defined(CONFIG_MMC)
|
||||
if (strncmp(ifname,"mmc",3)==0) {
|
||||
extern block_dev_desc_t * mmc_get_dev(int dev);
|
||||
return(mmc_get_dev(dev));
|
||||
}
|
||||
#endif
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
int do_fat_fsload (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
|
||||
{
|
||||
long size;
|
||||
unsigned long offset;
|
||||
unsigned long count;
|
||||
block_dev_desc_t *dev_desc=NULL;
|
||||
int dev=0;
|
||||
int part=1;
|
||||
char *ep;
|
||||
|
||||
if (argc < 3) {
|
||||
printf ("usage:fatload <filename> <addr> [bytes]\n");
|
||||
if (argc < 5) {
|
||||
printf ("usage: fatload <interface> <dev[:part]> <addr> <filename> [bytes]\n");
|
||||
return (0);
|
||||
}
|
||||
|
||||
offset = simple_strtoul (argv[2], NULL, 16);
|
||||
if (argc == 4)
|
||||
count = simple_strtoul (argv[3], NULL, 16);
|
||||
dev = (int)simple_strtoul (argv[2], &ep, 16);
|
||||
dev_desc=get_dev(argv[1],dev);
|
||||
if (dev_desc==NULL) {
|
||||
puts ("\n** Invalid boot device **\n");
|
||||
return 1;
|
||||
}
|
||||
if (*ep) {
|
||||
if (*ep != ':') {
|
||||
puts ("\n** Invalid boot device, use `dev[:part]' **\n");
|
||||
return 1;
|
||||
}
|
||||
part = (int)simple_strtoul(++ep, NULL, 16);
|
||||
}
|
||||
if (fat_register_device(dev_desc,part)!=0) {
|
||||
printf ("\n** Unable to use %s %d:%d for fatload **\n",argv[1],dev,part);
|
||||
return 1;
|
||||
}
|
||||
offset = simple_strtoul (argv[3], NULL, 16);
|
||||
if (argc == 6)
|
||||
count = simple_strtoul (argv[5], NULL, 16);
|
||||
else
|
||||
count = 0;
|
||||
size = file_fat_read (argv[4], (unsigned char *) offset, count);
|
||||
|
||||
size = file_fat_read (argv[1], (unsigned char *) offset, count);
|
||||
|
||||
printf ("%ld bytes read\n", size);
|
||||
if(size==-1)
|
||||
printf("\n** Unable to read \"%s\" from %s %d:%d **\n",argv[4],argv[1],dev,part);
|
||||
else
|
||||
printf ("\n%ld bytes read\n", size);
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
U_BOOT_CMD(
|
||||
fatload, 4, 0, do_fat_fsload,
|
||||
fatload, 6, 0, do_fat_fsload,
|
||||
"fatload - load binary file from a dos filesystem\n",
|
||||
"[ off ] [ filename ]\n"
|
||||
" - load binary file from dos filesystem\n"
|
||||
" with offset 'off'\n"
|
||||
"<interface> <dev[:part]> <addr> <filename> [bytes]\n"
|
||||
" - load binary file 'filename' from 'dev' on 'interface'\n"
|
||||
" to address 'addr' from dos filesystem\n"
|
||||
);
|
||||
|
||||
int do_fat_ls (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
|
||||
{
|
||||
char *filename = "/";
|
||||
int ret;
|
||||
int dev=0;
|
||||
int part=1;
|
||||
char *ep;
|
||||
block_dev_desc_t *dev_desc=NULL;
|
||||
|
||||
if (argc == 2)
|
||||
ret = file_fat_ls (argv[1]);
|
||||
if (argc < 3) {
|
||||
printf ("usage: fatls <interface> <dev[:part]> [directory]\n");
|
||||
return (0);
|
||||
}
|
||||
dev = (int)simple_strtoul (argv[2], &ep, 16);
|
||||
dev_desc=get_dev(argv[1],dev);
|
||||
if (dev_desc==NULL) {
|
||||
puts ("\n** Invalid boot device **\n");
|
||||
return 1;
|
||||
}
|
||||
if (*ep) {
|
||||
if (*ep != ':') {
|
||||
puts ("\n** Invalid boot device, use `dev[:part]' **\n");
|
||||
return 1;
|
||||
}
|
||||
part = (int)simple_strtoul(++ep, NULL, 16);
|
||||
}
|
||||
if (fat_register_device(dev_desc,part)!=0) {
|
||||
printf ("\n** Unable to use %s %d:%d for fatls **\n",argv[1],dev,part);
|
||||
return 1;
|
||||
}
|
||||
if (argc == 4)
|
||||
ret = file_fat_ls (argv[3]);
|
||||
else
|
||||
ret = file_fat_ls (filename);
|
||||
|
||||
if(ret!=0)
|
||||
printf("No Fat FS detected\n");
|
||||
return (ret);
|
||||
}
|
||||
|
||||
U_BOOT_CMD(
|
||||
fatls, 2, 1, do_fat_ls,
|
||||
fatls, 4, 1, do_fat_ls,
|
||||
"fatls - list files in a directory (default /)\n",
|
||||
"[ directory ]\n"
|
||||
" - list files in a directory\n"
|
||||
"<interface> <dev[:part]> [directory]\n"
|
||||
" - list files from 'dev' on 'interface' in a 'directory'\n"
|
||||
);
|
||||
|
||||
int do_fat_fsinfo (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
|
||||
{
|
||||
int ret;
|
||||
int dev=0;
|
||||
int part=1;
|
||||
char *ep;
|
||||
block_dev_desc_t *dev_desc=NULL;
|
||||
|
||||
ret = 0;
|
||||
|
||||
printf ("FAT info: %d\n", file_fat_detectfs ());
|
||||
|
||||
return (ret);
|
||||
if (argc < 2) {
|
||||
printf ("usage: fatinfo <interface> <dev[:part]>\n");
|
||||
return (0);
|
||||
}
|
||||
dev = (int)simple_strtoul (argv[2], &ep, 16);
|
||||
dev_desc=get_dev(argv[1],dev);
|
||||
if (dev_desc==NULL) {
|
||||
puts ("\n** Invalid boot device **\n");
|
||||
return 1;
|
||||
}
|
||||
if (*ep) {
|
||||
if (*ep != ':') {
|
||||
puts ("\n** Invalid boot device, use `dev[:part]' **\n");
|
||||
return 1;
|
||||
}
|
||||
part = (int)simple_strtoul(++ep, NULL, 16);
|
||||
}
|
||||
if (fat_register_device(dev_desc,part)!=0) {
|
||||
printf ("\n** Unable to use %s %d:%d for fatinfo **\n",argv[1],dev,part);
|
||||
return 1;
|
||||
}
|
||||
return (file_fat_detectfs ());
|
||||
}
|
||||
|
||||
U_BOOT_CMD(
|
||||
fatinfo, 1, 1, do_fat_fsinfo,
|
||||
fatinfo, 3, 1, do_fat_fsinfo,
|
||||
"fatinfo - print information about filesystem\n",
|
||||
"\n"
|
||||
" - print information about filesystem\n"
|
||||
"<interface> <dev[:part]>\n"
|
||||
" - print information about filesystem from 'dev' on 'interface'\n"
|
||||
);
|
||||
|
||||
#ifdef NOT_IMPLEMENTED_YET
|
||||
|
||||
@@ -174,7 +174,7 @@ do_jffs2_chpart(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
|
||||
}
|
||||
|
||||
if (jffs2_part_info(tmp_part)){
|
||||
printf("Partiton changed to %d\n",tmp_part);
|
||||
printf("Partition changed to %d\n",tmp_part);
|
||||
part_num=tmp_part;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -520,7 +520,7 @@ static int NanD_WaitReady(struct nand_chip *nand, int ale_wait)
|
||||
else
|
||||
udelay(10);
|
||||
#else /* has functional r/b signal */
|
||||
NAND_WAIT_READY(nand);
|
||||
NAND_WAIT_READY(nand);
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
@@ -639,7 +639,9 @@ static int NanD_IdentChip(struct nand_chip *nand, int floor, int chip)
|
||||
NAND_DISABLE_CE(nand); /* set pin high */
|
||||
/* No response - return failure */
|
||||
if (mfr == 0xff || mfr == 0) {
|
||||
#ifdef NAND_DEBUG
|
||||
printf("NanD_Command (ReadID) got %d %d\n", mfr, id);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -732,7 +734,9 @@ static void NanD_ScanChips(struct nand_chip *nand)
|
||||
|
||||
/* If there are none at all that we recognise, bail */
|
||||
if (!nand->numchips) {
|
||||
puts ("No flash chips recognised.\n");
|
||||
#ifdef NAND_DEBUG
|
||||
puts ("No NAND flash chips recognised.\n");
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1406,7 +1410,7 @@ static inline int nandcheck(unsigned long potential, unsigned long physadr)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void nand_probe(unsigned long physadr)
|
||||
unsigned long nand_probe(unsigned long physadr)
|
||||
{
|
||||
struct nand_chip *nand = NULL;
|
||||
int i = 0, ChipID = 1;
|
||||
@@ -1432,10 +1436,12 @@ void nand_probe(unsigned long physadr)
|
||||
|
||||
for (i=0; i<CFG_MAX_NAND_DEVICE; i++) {
|
||||
if (nand_dev_desc[i].ChipID == NAND_ChipID_UNKNOWN) {
|
||||
nand = nand_dev_desc + i;
|
||||
nand = &nand_dev_desc[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!nand)
|
||||
return (0);
|
||||
|
||||
memset((char *)nand, 0, sizeof(struct nand_chip));
|
||||
|
||||
@@ -1447,7 +1453,7 @@ void nand_probe(unsigned long physadr)
|
||||
/* no chips found, clean up and quit */
|
||||
memset((char *)nand, 0, sizeof(struct nand_chip));
|
||||
nand->ChipID = NAND_ChipID_UNKNOWN;
|
||||
return;
|
||||
return (0);
|
||||
}
|
||||
|
||||
nand->ChipID = ChipID;
|
||||
@@ -1457,8 +1463,10 @@ void nand_probe(unsigned long physadr)
|
||||
nand->data_buf = malloc (nand->oobblock + nand->oobsize);
|
||||
if (!nand->data_buf) {
|
||||
puts ("Cannot allocate memory for data structures.\n");
|
||||
return;
|
||||
return (0);
|
||||
}
|
||||
|
||||
return (nand->totlen);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_MTD_NAND_ECC
|
||||
|
||||
@@ -116,6 +116,13 @@ static void netboot_update_env(void)
|
||||
setenv("dnsip", tmp);
|
||||
}
|
||||
|
||||
#if (CONFIG_BOOTP_MASK & CONFIG_BOOTP_DNS2)
|
||||
if (NetOurDNS2IP) {
|
||||
ip_to_string (NetOurDNS2IP, tmp);
|
||||
setenv("dnsip2", tmp);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (NetOurNISDomain[0])
|
||||
setenv("domain", NetOurNISDomain);
|
||||
|
||||
|
||||
@@ -54,7 +54,7 @@ int do_vfd (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (argv[1][0] == '#') { /* select bitmap by number */
|
||||
if (argv[1][0] == '/') { /* select bitmap by number */
|
||||
bitmap = simple_strtoul(argv[1]+1, NULL, 10);
|
||||
return (trab_vfd(bitmap));
|
||||
}
|
||||
@@ -68,8 +68,10 @@ int do_vfd (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
|
||||
U_BOOT_CMD(
|
||||
vfd, 2, 0, do_vfd,
|
||||
"vfd - load a bitmap to the VFDs on TRAB\n",
|
||||
"N\n"
|
||||
"/N\n"
|
||||
" - load bitmap N to the VFDs (N is _decimal_ !!!)\n"
|
||||
"vfd ADDR\n"
|
||||
" - load bitmap at address ADDR\n"
|
||||
);
|
||||
#endif /* CFG_CMD_VFD */
|
||||
|
||||
|
||||
@@ -27,5 +27,9 @@ void jumptable_init (void)
|
||||
#if defined(CONFIG_I386) || defined(CONFIG_PPC)
|
||||
gd->jt[XF_install_hdlr] = (void *) irq_install_handler;
|
||||
gd->jt[XF_free_hdlr] = (void *) irq_free_handler;
|
||||
#endif
|
||||
#endif /* I386 || PPC */
|
||||
#if (CONFIG_COMMANDS & CFG_CMD_I2C)
|
||||
gd->jt[XF_i2c_write] = (void *) i2c_write;
|
||||
gd->jt[XF_i2c_read] = (void *) i2c_read;
|
||||
#endif /* CFG_CMD_I2C */
|
||||
}
|
||||
|
||||
@@ -2,8 +2,12 @@
|
||||
* (C) Copyright 2001
|
||||
* Denis Peter, MPL AG Switzerland
|
||||
*
|
||||
* For BBB support (C) Copyright 2003
|
||||
* Gary Jennejohn, DENX Software Engineering <gj@denx.de>
|
||||
*
|
||||
* Most of this source has been derived from the Linux USB
|
||||
* project.
|
||||
* project. BBB support based on /sys/dev/usb/umass.c from
|
||||
* FreeBSD.
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
@@ -30,6 +34,13 @@
|
||||
* is only tested with a TEAC USB Floppy. Other Massstorages with CBI or CB
|
||||
* transport protocoll may work as well.
|
||||
*/
|
||||
/*
|
||||
* New Note:
|
||||
* Support for USB Mass Storage Devices (BBB) has been added. It has
|
||||
* only been tested with USB memory sticks.
|
||||
* Nota bene: if you are using the BBB support with a little-endian
|
||||
* CPU then you MUST define LITTLEENDIAN in the configuration file!
|
||||
*/
|
||||
|
||||
|
||||
#include <common.h>
|
||||
@@ -71,6 +82,41 @@ static ccb usb_ccb;
|
||||
|
||||
#define US_CBI_ADSC 0
|
||||
|
||||
/*
|
||||
* BULK only
|
||||
*/
|
||||
#define US_BBB_RESET 0xff
|
||||
#define US_BBB_GET_MAX_LUN 0xfe
|
||||
|
||||
/* Command Block Wrapper */
|
||||
typedef struct {
|
||||
__u32 dCBWSignature;
|
||||
# define CBWSIGNATURE 0x43425355
|
||||
__u32 dCBWTag;
|
||||
__u32 dCBWDataTransferLength;
|
||||
__u8 bCBWFlags;
|
||||
# define CBWFLAGS_OUT 0x00
|
||||
# define CBWFLAGS_IN 0x80
|
||||
__u8 bCBWLUN;
|
||||
__u8 bCDBLength;
|
||||
# define CBWCDBLENGTH 16
|
||||
__u8 CBWCDB[CBWCDBLENGTH];
|
||||
} umass_bbb_cbw_t;
|
||||
#define UMASS_BBB_CBW_SIZE 31
|
||||
static __u32 CBWTag = 0;
|
||||
|
||||
/* Command Status Wrapper */
|
||||
typedef struct {
|
||||
__u32 dCSWSignature;
|
||||
# define CSWSIGNATURE 0x53425355
|
||||
__u32 dCSWTag;
|
||||
__u32 dCSWDataResidue;
|
||||
__u8 bCSWStatus;
|
||||
# define CSWSTATUS_GOOD 0x0
|
||||
# define CSWSTATUS_FAILED 0x1
|
||||
# define CSWSTATUS_PHASE 0x2
|
||||
} umass_bbb_csw_t;
|
||||
#define UMASS_BBB_CSW_SIZE 13
|
||||
|
||||
#define USB_MAX_STOR_DEV 5
|
||||
static int usb_max_devs; /* number of highest available usb device */
|
||||
@@ -138,6 +184,9 @@ int usb_stor_scan(int mode)
|
||||
unsigned char i;
|
||||
struct usb_device *dev;
|
||||
|
||||
/* GJ */
|
||||
memset(usb_stor_buf, 0, sizeof(usb_stor_buf));
|
||||
|
||||
if(mode==1) {
|
||||
printf("scanning bus for storage devices...\n");
|
||||
}
|
||||
@@ -293,6 +342,51 @@ static int us_one_transfer(struct us_data *us, int pipe, char *buf, int length)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int usb_stor_BBB_reset(struct us_data *us)
|
||||
{
|
||||
int result;
|
||||
unsigned int pipe;
|
||||
|
||||
/*
|
||||
* Reset recovery (5.3.4 in Universal Serial Bus Mass Storage Class)
|
||||
*
|
||||
* For Reset Recovery the host shall issue in the following order:
|
||||
* a) a Bulk-Only Mass Storage Reset
|
||||
* b) a Clear Feature HALT to the Bulk-In endpoint
|
||||
* c) a Clear Feature HALT to the Bulk-Out endpoint
|
||||
*
|
||||
* This is done in 3 steps.
|
||||
*
|
||||
* If the reset doesn't succeed, the device should be port reset.
|
||||
*
|
||||
* This comment stolen from FreeBSD's /sys/dev/usb/umass.c.
|
||||
*/
|
||||
USB_STOR_PRINTF("BBB_reset\n");
|
||||
result = usb_control_msg(us->pusb_dev, usb_sndctrlpipe(us->pusb_dev,0),
|
||||
US_BBB_RESET, USB_TYPE_CLASS | USB_RECIP_INTERFACE,
|
||||
0, us->ifnum, 0, 0, USB_CNTL_TIMEOUT*5);
|
||||
if((result < 0) && (us->pusb_dev->status & USB_ST_STALLED))
|
||||
{
|
||||
USB_STOR_PRINTF("RESET:stall\n");
|
||||
return -1;
|
||||
}
|
||||
/* long wait for reset */
|
||||
wait_ms(150);
|
||||
USB_STOR_PRINTF("BBB_reset result %d: status %X reset\n",result,us->pusb_dev->status);
|
||||
pipe = usb_rcvbulkpipe(us->pusb_dev, us->ep_in);
|
||||
result = usb_clear_halt(us->pusb_dev, pipe);
|
||||
/* long wait for reset */
|
||||
wait_ms(150);
|
||||
USB_STOR_PRINTF("BBB_reset result %d: status %X clearing IN endpoint\n",result,us->pusb_dev->status);
|
||||
/* long wait for reset */
|
||||
pipe = usb_sndbulkpipe(us->pusb_dev, us->ep_out);
|
||||
result = usb_clear_halt(us->pusb_dev, pipe);
|
||||
wait_ms(150);
|
||||
USB_STOR_PRINTF("BBB_reset result %d: status %X clearing OUT endpoint\n",result,us->pusb_dev->status);
|
||||
USB_STOR_PRINTF("BBB_reset done\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* FIXME: this reset function doesn't really reset the port, and it
|
||||
* should. Actually it should probably do what it's doing here, and
|
||||
* reset the port physically
|
||||
@@ -320,6 +414,52 @@ static int usb_stor_CB_reset(struct us_data *us)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set up the command for a BBB device. Note that the actual SCSI
|
||||
* command is copied into cbw.CBWCDB.
|
||||
*/
|
||||
int usb_stor_BBB_comdat(ccb *srb, struct us_data *us)
|
||||
{
|
||||
int result;
|
||||
int actlen;
|
||||
int dir_in;
|
||||
unsigned int pipe;
|
||||
umass_bbb_cbw_t cbw;
|
||||
|
||||
dir_in = US_DIRECTION(srb->cmd[0]);
|
||||
|
||||
#ifdef BBB_COMDAT_TRACE
|
||||
printf("dir %d lun %d cmdlen %d cmd %p datalen %d pdata %p\n", dir_in, srb->lun, srb->cmdlen, srb->cmd, srb->datalen, srb->pdata);
|
||||
if (srb->cmdlen) {
|
||||
for(result = 0;result < srb->cmdlen;result++)
|
||||
printf("cmd[%d] %#x ", result, srb->cmd[result]);
|
||||
printf("\n");
|
||||
}
|
||||
#endif
|
||||
/* sanity checks */
|
||||
if (!(srb->cmdlen <= CBWCDBLENGTH)) {
|
||||
USB_STOR_PRINTF("usb_stor_BBB_comdat:cmdlen too large\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* always OUT to the ep */
|
||||
pipe = usb_sndbulkpipe(us->pusb_dev, us->ep_out);
|
||||
|
||||
cbw.dCBWSignature = swap_32(CBWSIGNATURE);
|
||||
cbw.dCBWTag = swap_32(CBWTag++);
|
||||
cbw.dCBWDataTransferLength = swap_32(srb->datalen);
|
||||
cbw.bCBWFlags = (dir_in? CBWFLAGS_IN : CBWFLAGS_OUT);
|
||||
cbw.bCBWLUN = srb->lun;
|
||||
cbw.bCDBLength = srb->cmdlen;
|
||||
/* copy the command data into the CBW command data buffer */
|
||||
/* DST SRC LEN!!! */
|
||||
memcpy(cbw.CBWCDB, srb->cmd, srb->cmdlen);
|
||||
result = usb_bulk_msg(us->pusb_dev, pipe, &cbw, UMASS_BBB_CBW_SIZE, &actlen, USB_CNTL_TIMEOUT*5);
|
||||
if (result < 0)
|
||||
USB_STOR_PRINTF("usb_stor_BBB_comdat:usb_bulk_msg error\n");
|
||||
return result;
|
||||
}
|
||||
|
||||
/* FIXME: we also need a CBI_command which sets up the completion
|
||||
* interrupt, and waits for it
|
||||
*/
|
||||
@@ -422,6 +562,134 @@ int usb_stor_CBI_get_status(ccb *srb, struct us_data *us)
|
||||
#define USB_TRANSPORT_UNKNOWN_RETRY 5
|
||||
#define USB_TRANSPORT_NOT_READY_RETRY 10
|
||||
|
||||
/* clear a stall on an endpoint - special for BBB devices */
|
||||
int usb_stor_BBB_clear_endpt_stall(struct us_data *us, __u8 endpt)
|
||||
{
|
||||
int result;
|
||||
|
||||
/* ENDPOINT_HALT = 0, so set value to 0 */
|
||||
result = usb_control_msg(us->pusb_dev, usb_sndctrlpipe(us->pusb_dev,0),
|
||||
USB_REQ_CLEAR_FEATURE, USB_RECIP_ENDPOINT,
|
||||
0, endpt, 0, 0, USB_CNTL_TIMEOUT*5);
|
||||
return result;
|
||||
}
|
||||
|
||||
int usb_stor_BBB_transport(ccb *srb, struct us_data *us)
|
||||
{
|
||||
int result, retry;
|
||||
int dir_in;
|
||||
int actlen, data_actlen;
|
||||
unsigned int pipe, pipein, pipeout;
|
||||
umass_bbb_csw_t csw;
|
||||
#ifdef BBB_XPORT_TRACE
|
||||
unsigned char *ptr;
|
||||
int index;
|
||||
#endif
|
||||
|
||||
dir_in = US_DIRECTION(srb->cmd[0]);
|
||||
|
||||
/* COMMAND phase */
|
||||
USB_STOR_PRINTF("COMMAND phase\n");
|
||||
result = usb_stor_BBB_comdat(srb, us);
|
||||
if (result < 0) {
|
||||
USB_STOR_PRINTF("failed to send CBW status %ld\n",
|
||||
us->pusb_dev->status);
|
||||
usb_stor_BBB_reset(us);
|
||||
return USB_STOR_TRANSPORT_FAILED;
|
||||
}
|
||||
wait_ms(5);
|
||||
pipein = usb_rcvbulkpipe(us->pusb_dev, us->ep_in);
|
||||
pipeout = usb_sndbulkpipe(us->pusb_dev, us->ep_out);
|
||||
/* DATA phase + error handling */
|
||||
USB_STOR_PRINTF("DATA phase\n");
|
||||
data_actlen = 0;
|
||||
/* no data, go immediately to the STATUS phase */
|
||||
if (srb->datalen == 0)
|
||||
goto st;
|
||||
if (dir_in)
|
||||
pipe = pipein;
|
||||
else
|
||||
pipe = pipeout;
|
||||
result = usb_bulk_msg(us->pusb_dev, pipe, srb->pdata, srb->datalen, &data_actlen, USB_CNTL_TIMEOUT*5);
|
||||
/* special handling of STALL in DATA phase */
|
||||
if((result < 0) && (us->pusb_dev->status & USB_ST_STALLED)) {
|
||||
USB_STOR_PRINTF("DATA:stall\n");
|
||||
/* clear the STALL on the endpoint */
|
||||
result = usb_stor_BBB_clear_endpt_stall(us, dir_in? us->ep_in : us->ep_out);
|
||||
if (result >= 0)
|
||||
/* continue on to STATUS phase */
|
||||
goto st;
|
||||
}
|
||||
if (result < 0) {
|
||||
USB_STOR_PRINTF("usb_bulk_msg error status %ld\n",
|
||||
us->pusb_dev->status);
|
||||
usb_stor_BBB_reset(us);
|
||||
return USB_STOR_TRANSPORT_FAILED;
|
||||
}
|
||||
#ifdef BBB_XPORT_TRACE
|
||||
for (index = 0; index < data_actlen; index++)
|
||||
printf("pdata[%d] %#x ", index, srb->pdata[index]);
|
||||
printf("\n");
|
||||
#endif
|
||||
/* STATUS phase + error handling */
|
||||
st:
|
||||
retry = 0;
|
||||
again:
|
||||
USB_STOR_PRINTF("STATUS phase\n");
|
||||
result = usb_bulk_msg(us->pusb_dev, pipein, &csw, UMASS_BBB_CSW_SIZE, &actlen, USB_CNTL_TIMEOUT*5);
|
||||
/* special handling of STALL in STATUS phase */
|
||||
if((result < 0) && (retry < 1) && (us->pusb_dev->status & USB_ST_STALLED)) {
|
||||
USB_STOR_PRINTF("STATUS:stall\n");
|
||||
/* clear the STALL on the endpoint */
|
||||
result = usb_stor_BBB_clear_endpt_stall(us, us->ep_in);
|
||||
if (result >= 0 && (retry++ < 1))
|
||||
/* do a retry */
|
||||
goto again;
|
||||
}
|
||||
if (result < 0) {
|
||||
USB_STOR_PRINTF("usb_bulk_msg error status %ld\n",
|
||||
us->pusb_dev->status);
|
||||
usb_stor_BBB_reset(us);
|
||||
return USB_STOR_TRANSPORT_FAILED;
|
||||
}
|
||||
#ifdef BBB_XPORT_TRACE
|
||||
ptr = (unsigned char *)&csw;
|
||||
for (index = 0; index < UMASS_BBB_CSW_SIZE; index++)
|
||||
printf("ptr[%d] %#x ", index, ptr[index]);
|
||||
printf("\n");
|
||||
#endif
|
||||
/* misuse pipe to get the residue */
|
||||
pipe = swap_32(csw.dCSWDataResidue);
|
||||
if (pipe == 0 && srb->datalen != 0 && srb->datalen - data_actlen != 0)
|
||||
pipe = srb->datalen - data_actlen;
|
||||
if (CSWSIGNATURE != swap_32(csw.dCSWSignature)) {
|
||||
USB_STOR_PRINTF("!CSWSIGNATURE\n");
|
||||
usb_stor_BBB_reset(us);
|
||||
return USB_STOR_TRANSPORT_FAILED;
|
||||
} else if ((CBWTag - 1) != swap_32(csw.dCSWTag)) {
|
||||
USB_STOR_PRINTF("!Tag\n");
|
||||
usb_stor_BBB_reset(us);
|
||||
return USB_STOR_TRANSPORT_FAILED;
|
||||
} else if (csw.bCSWStatus > CSWSTATUS_PHASE) {
|
||||
USB_STOR_PRINTF(">PHASE\n");
|
||||
usb_stor_BBB_reset(us);
|
||||
return USB_STOR_TRANSPORT_FAILED;
|
||||
} else if (csw.bCSWStatus == CSWSTATUS_PHASE) {
|
||||
USB_STOR_PRINTF("=PHASE\n");
|
||||
usb_stor_BBB_reset(us);
|
||||
return USB_STOR_TRANSPORT_FAILED;
|
||||
} else if (data_actlen > srb->datalen) {
|
||||
USB_STOR_PRINTF("transferred %dB instead of %dB\n",
|
||||
data_actlen, srb->datalen);
|
||||
return USB_STOR_TRANSPORT_FAILED;
|
||||
} else if (csw.bCSWStatus == CSWSTATUS_FAILED) {
|
||||
USB_STOR_PRINTF("FAILED\n");
|
||||
return USB_STOR_TRANSPORT_FAILED;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int usb_stor_CB_transport(ccb *srb, struct us_data *us)
|
||||
{
|
||||
int result,status;
|
||||
@@ -495,29 +763,28 @@ do_retry:
|
||||
return USB_STOR_TRANSPORT_GOOD;
|
||||
/* Check the auto request result */
|
||||
switch(srb->sense_buf[2]) {
|
||||
case 0x01: /* Recovered Error */
|
||||
return USB_STOR_TRANSPORT_GOOD;
|
||||
break;
|
||||
case 0x02: /* Not Ready */
|
||||
if(notready++ > USB_TRANSPORT_NOT_READY_RETRY) {
|
||||
printf("cmd 0x%02X returned 0x%02X 0x%02X 0x%02X 0x%02X (NOT READY)\n",
|
||||
srb->cmd[0],srb->sense_buf[0],srb->sense_buf[2],srb->sense_buf[12],srb->sense_buf[13]);
|
||||
return USB_STOR_TRANSPORT_FAILED;
|
||||
}
|
||||
else {
|
||||
wait_ms(100);
|
||||
goto do_retry;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if(retry++ > USB_TRANSPORT_UNKNOWN_RETRY) {
|
||||
printf("cmd 0x%02X returned 0x%02X 0x%02X 0x%02X 0x%02X\n",
|
||||
srb->cmd[0],srb->sense_buf[0],srb->sense_buf[2],srb->sense_buf[12],srb->sense_buf[13]);
|
||||
return USB_STOR_TRANSPORT_FAILED;
|
||||
}
|
||||
else
|
||||
goto do_retry;
|
||||
break;
|
||||
case 0x01: /* Recovered Error */
|
||||
return USB_STOR_TRANSPORT_GOOD;
|
||||
break;
|
||||
case 0x02: /* Not Ready */
|
||||
if(notready++ > USB_TRANSPORT_NOT_READY_RETRY) {
|
||||
printf("cmd 0x%02X returned 0x%02X 0x%02X 0x%02X 0x%02X (NOT READY)\n",
|
||||
srb->cmd[0],srb->sense_buf[0],srb->sense_buf[2],srb->sense_buf[12],srb->sense_buf[13]);
|
||||
return USB_STOR_TRANSPORT_FAILED;
|
||||
} else {
|
||||
wait_ms(100);
|
||||
goto do_retry;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if(retry++ > USB_TRANSPORT_UNKNOWN_RETRY) {
|
||||
printf("cmd 0x%02X returned 0x%02X 0x%02X 0x%02X 0x%02X\n",
|
||||
srb->cmd[0],srb->sense_buf[0],srb->sense_buf[2],srb->sense_buf[12],srb->sense_buf[13]);
|
||||
return USB_STOR_TRANSPORT_FAILED;
|
||||
} else {
|
||||
goto do_retry;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return USB_STOR_TRANSPORT_FAILED;
|
||||
}
|
||||
@@ -538,7 +805,8 @@ static int usb_inquiry(ccb *srb,struct us_data *ss)
|
||||
USB_STOR_PRINTF("inquiry returns %d\n",i);
|
||||
if(i==0)
|
||||
break;
|
||||
}while(retry--);
|
||||
} while(retry--);
|
||||
|
||||
if(!retry) {
|
||||
printf("error in inquiry\n");
|
||||
return -1;
|
||||
@@ -567,17 +835,18 @@ static int usb_request_sense(ccb *srb,struct us_data *ss)
|
||||
static int usb_test_unit_ready(ccb *srb,struct us_data *ss)
|
||||
{
|
||||
int retries=10;
|
||||
|
||||
do {
|
||||
memset(&srb->cmd[0],0,12);
|
||||
srb->cmd[0]=SCSI_TST_U_RDY;
|
||||
srb->cmd[1]=srb->lun<<5;
|
||||
srb->datalen=0;
|
||||
srb->cmdlen=12;
|
||||
if(ss->transport(srb,ss)==USB_STOR_TRANSPORT_GOOD)
|
||||
{
|
||||
if(ss->transport(srb,ss)==USB_STOR_TRANSPORT_GOOD) {
|
||||
return 0;
|
||||
}
|
||||
} while(retries--);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -594,7 +863,8 @@ static int usb_read_capacity(ccb *srb,struct us_data *ss)
|
||||
if(ss->transport(srb,ss)==USB_STOR_TRANSPORT_GOOD) {
|
||||
return 0;
|
||||
}
|
||||
}while(retry--);
|
||||
} while(retry--);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -654,8 +924,7 @@ unsigned long usb_stor_read(int device, unsigned long blknr, unsigned long blkcn
|
||||
srb->pdata=(unsigned char *)buf_addr;
|
||||
if(blks>USB_MAX_READ_BLK) {
|
||||
smallblks=USB_MAX_READ_BLK;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
smallblks=(unsigned short) blks;
|
||||
}
|
||||
retry_it:
|
||||
@@ -751,6 +1020,11 @@ int usb_storage_probe(struct usb_device *dev, unsigned int ifnum,struct us_data
|
||||
ss->transport = usb_stor_CB_transport;
|
||||
ss->transport_reset = usb_stor_CB_reset;
|
||||
break;
|
||||
case US_PR_BULK:
|
||||
USB_STOR_PRINTF("Bulk/Bulk/Bulk\n");
|
||||
ss->transport = usb_stor_BBB_transport;
|
||||
ss->transport_reset = usb_stor_BBB_reset;
|
||||
break;
|
||||
default:
|
||||
printf("USB Starage Transport unknown / not yet implemented\n");
|
||||
return 0;
|
||||
@@ -793,23 +1067,22 @@ int usb_storage_probe(struct usb_device *dev, unsigned int ifnum,struct us_data
|
||||
return 0;
|
||||
}
|
||||
/* set class specific stuff */
|
||||
/* We only handle certain protocols. Currently, this is
|
||||
* the only one.
|
||||
/* We only handle certain protocols. Currently, these are
|
||||
* the only ones.
|
||||
*/
|
||||
if (ss->subclass != US_SC_UFI) {
|
||||
if (ss->subclass != US_SC_UFI && ss->subclass != US_SC_SCSI) {
|
||||
printf("Sorry, protocol %d not yet supported.\n",ss->subclass);
|
||||
return 0;
|
||||
}
|
||||
if(ss->ep_int) /* we had found an interrupt endpoint, prepare irq pipe */
|
||||
{
|
||||
if(ss->ep_int) { /* we had found an interrupt endpoint, prepare irq pipe */
|
||||
/* set up the IRQ pipe and handler */
|
||||
|
||||
ss->irqinterval = (ss->irqinterval > 0) ? ss->irqinterval : 255;
|
||||
ss->irqpipe = usb_rcvintpipe(ss->pusb_dev, ss->ep_int);
|
||||
ss->irqmaxp = usb_maxpacket(dev, ss->irqpipe);
|
||||
dev->irq_handle=usb_stor_irq;
|
||||
dev->privptr=(void *)ss;
|
||||
}
|
||||
dev->privptr=(void *)ss;
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -865,6 +1138,19 @@ int usb_stor_get_info(struct usb_device *dev,struct us_data *ss,block_dev_desc_t
|
||||
if(cap[0]>(0x200000 * 10)) /* greater than 10 GByte */
|
||||
cap[0]>>=16;
|
||||
#endif
|
||||
#ifdef LITTLEENDIAN
|
||||
cap[0] = ((unsigned long)(
|
||||
(((unsigned long)(cap[0]) & (unsigned long)0x000000ffUL) << 24) |
|
||||
(((unsigned long)(cap[0]) & (unsigned long)0x0000ff00UL) << 8) |
|
||||
(((unsigned long)(cap[0]) & (unsigned long)0x00ff0000UL) >> 8) |
|
||||
(((unsigned long)(cap[0]) & (unsigned long)0xff000000UL) >> 24) ));
|
||||
cap[1] = ((unsigned long)(
|
||||
(((unsigned long)(cap[1]) & (unsigned long)0x000000ffUL) << 24) |
|
||||
(((unsigned long)(cap[1]) & (unsigned long)0x0000ff00UL) << 8) |
|
||||
(((unsigned long)(cap[1]) & (unsigned long)0x00ff0000UL) >> 8) |
|
||||
(((unsigned long)(cap[1]) & (unsigned long)0xff000000UL) >> 24) ));
|
||||
#endif
|
||||
/* this assumes bigendian! */
|
||||
cap[0]+=1;
|
||||
capacity=&cap[0];
|
||||
blksz=&cap[1];
|
||||
@@ -881,5 +1167,5 @@ int usb_stor_get_info(struct usb_device *dev,struct us_data *ss,block_dev_desc_t
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif /* CONFIG_USB_STORAGE */
|
||||
#endif /* CFG_CMD_USB */
|
||||
|
||||
@@ -26,7 +26,7 @@ include $(TOPDIR)/config.mk
|
||||
LIB = lib$(CPU).a
|
||||
|
||||
START = start.o
|
||||
OBJS = serial.o interrupts.o cpu.o speed.o
|
||||
OBJS = serial.o interrupts.o cpu.o speed.o usb_ohci.o
|
||||
|
||||
all: .depend $(START) $(LIB)
|
||||
|
||||
|
||||
1560
cpu/arm920t/usb_ohci.c
Normal file
1560
cpu/arm920t/usb_ohci.c
Normal file
File diff suppressed because it is too large
Load Diff
420
cpu/arm920t/usb_ohci.h
Normal file
420
cpu/arm920t/usb_ohci.h
Normal file
@@ -0,0 +1,420 @@
|
||||
/*
|
||||
* URB OHCI HCD (Host Controller Driver) for USB.
|
||||
*
|
||||
* (C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at>
|
||||
* (C) Copyright 2000-2001 David Brownell <dbrownell@users.sourceforge.net>
|
||||
*
|
||||
* usb-ohci.h
|
||||
*/
|
||||
|
||||
|
||||
static int cc_to_error[16] = {
|
||||
|
||||
/* mapping of the OHCI CC status to error codes */
|
||||
/* No Error */ 0,
|
||||
/* CRC Error */ USB_ST_CRC_ERR,
|
||||
/* Bit Stuff */ USB_ST_BIT_ERR,
|
||||
/* Data Togg */ USB_ST_CRC_ERR,
|
||||
/* Stall */ USB_ST_STALLED,
|
||||
/* DevNotResp */ -1,
|
||||
/* PIDCheck */ USB_ST_BIT_ERR,
|
||||
/* UnExpPID */ USB_ST_BIT_ERR,
|
||||
/* DataOver */ USB_ST_BUF_ERR,
|
||||
/* DataUnder */ USB_ST_BUF_ERR,
|
||||
/* reservd */ -1,
|
||||
/* reservd */ -1,
|
||||
/* BufferOver */ USB_ST_BUF_ERR,
|
||||
/* BuffUnder */ USB_ST_BUF_ERR,
|
||||
/* Not Access */ -1,
|
||||
/* Not Access */ -1
|
||||
};
|
||||
|
||||
/* ED States */
|
||||
|
||||
#define ED_NEW 0x00
|
||||
#define ED_UNLINK 0x01
|
||||
#define ED_OPER 0x02
|
||||
#define ED_DEL 0x04
|
||||
#define ED_URB_DEL 0x08
|
||||
|
||||
/* usb_ohci_ed */
|
||||
struct ed {
|
||||
__u32 hwINFO;
|
||||
__u32 hwTailP;
|
||||
__u32 hwHeadP;
|
||||
__u32 hwNextED;
|
||||
|
||||
struct ed *ed_prev;
|
||||
__u8 int_period;
|
||||
__u8 int_branch;
|
||||
__u8 int_load;
|
||||
__u8 int_interval;
|
||||
__u8 state;
|
||||
__u8 type;
|
||||
__u16 last_iso;
|
||||
struct ed *ed_rm_list;
|
||||
|
||||
struct usb_device *usb_dev;
|
||||
__u32 unused[3];
|
||||
} __attribute((aligned(16)));
|
||||
typedef struct ed ed_t;
|
||||
|
||||
|
||||
/* TD info field */
|
||||
#define TD_CC 0xf0000000
|
||||
#define TD_CC_GET(td_p) ((td_p >>28) & 0x0f)
|
||||
#define TD_CC_SET(td_p, cc) (td_p) = ((td_p) & 0x0fffffff) | (((cc) & 0x0f) << 28)
|
||||
#define TD_EC 0x0C000000
|
||||
#define TD_T 0x03000000
|
||||
#define TD_T_DATA0 0x02000000
|
||||
#define TD_T_DATA1 0x03000000
|
||||
#define TD_T_TOGGLE 0x00000000
|
||||
#define TD_R 0x00040000
|
||||
#define TD_DI 0x00E00000
|
||||
#define TD_DI_SET(X) (((X) & 0x07)<< 21)
|
||||
#define TD_DP 0x00180000
|
||||
#define TD_DP_SETUP 0x00000000
|
||||
#define TD_DP_IN 0x00100000
|
||||
#define TD_DP_OUT 0x00080000
|
||||
|
||||
#define TD_ISO 0x00010000
|
||||
#define TD_DEL 0x00020000
|
||||
|
||||
/* CC Codes */
|
||||
#define TD_CC_NOERROR 0x00
|
||||
#define TD_CC_CRC 0x01
|
||||
#define TD_CC_BITSTUFFING 0x02
|
||||
#define TD_CC_DATATOGGLEM 0x03
|
||||
#define TD_CC_STALL 0x04
|
||||
#define TD_DEVNOTRESP 0x05
|
||||
#define TD_PIDCHECKFAIL 0x06
|
||||
#define TD_UNEXPECTEDPID 0x07
|
||||
#define TD_DATAOVERRUN 0x08
|
||||
#define TD_DATAUNDERRUN 0x09
|
||||
#define TD_BUFFEROVERRUN 0x0C
|
||||
#define TD_BUFFERUNDERRUN 0x0D
|
||||
#define TD_NOTACCESSED 0x0F
|
||||
|
||||
|
||||
#define MAXPSW 1
|
||||
|
||||
struct td {
|
||||
__u32 hwINFO;
|
||||
__u32 hwCBP; /* Current Buffer Pointer */
|
||||
__u32 hwNextTD; /* Next TD Pointer */
|
||||
__u32 hwBE; /* Memory Buffer End Pointer */
|
||||
|
||||
__u16 hwPSW[MAXPSW];
|
||||
__u8 unused;
|
||||
__u8 index;
|
||||
struct ed *ed;
|
||||
struct td *next_dl_td;
|
||||
struct usb_device *usb_dev;
|
||||
int transfer_len;
|
||||
__u32 data;
|
||||
|
||||
__u32 unused2[2];
|
||||
} __attribute((aligned(32)));
|
||||
typedef struct td td_t;
|
||||
|
||||
#define OHCI_ED_SKIP (1 << 14)
|
||||
|
||||
/*
|
||||
* The HCCA (Host Controller Communications Area) is a 256 byte
|
||||
* structure defined in the OHCI spec. that the host controller is
|
||||
* told the base address of. It must be 256-byte aligned.
|
||||
*/
|
||||
|
||||
#define NUM_INTS 32 /* part of the OHCI standard */
|
||||
struct ohci_hcca {
|
||||
__u32 int_table[NUM_INTS]; /* Interrupt ED table */
|
||||
__u16 frame_no; /* current frame number */
|
||||
__u16 pad1; /* set to 0 on each frame_no change */
|
||||
__u32 done_head; /* info returned for an interrupt */
|
||||
u8 reserved_for_hc[116];
|
||||
} __attribute((aligned(256)));
|
||||
|
||||
|
||||
/*
|
||||
* Maximum number of root hub ports.
|
||||
*/
|
||||
#define MAX_ROOT_PORTS 15 /* maximum OHCI root hub ports */
|
||||
|
||||
/*
|
||||
* This is the structure of the OHCI controller's memory mapped I/O
|
||||
* region. This is Memory Mapped I/O. You must use the readl() and
|
||||
* writel() macros defined in asm/io.h to access these!!
|
||||
*/
|
||||
struct ohci_regs {
|
||||
/* control and status registers */
|
||||
__u32 revision;
|
||||
__u32 control;
|
||||
__u32 cmdstatus;
|
||||
__u32 intrstatus;
|
||||
__u32 intrenable;
|
||||
__u32 intrdisable;
|
||||
/* memory pointers */
|
||||
__u32 hcca;
|
||||
__u32 ed_periodcurrent;
|
||||
__u32 ed_controlhead;
|
||||
__u32 ed_controlcurrent;
|
||||
__u32 ed_bulkhead;
|
||||
__u32 ed_bulkcurrent;
|
||||
__u32 donehead;
|
||||
/* frame counters */
|
||||
__u32 fminterval;
|
||||
__u32 fmremaining;
|
||||
__u32 fmnumber;
|
||||
__u32 periodicstart;
|
||||
__u32 lsthresh;
|
||||
/* Root hub ports */
|
||||
struct ohci_roothub_regs {
|
||||
__u32 a;
|
||||
__u32 b;
|
||||
__u32 status;
|
||||
__u32 portstatus[MAX_ROOT_PORTS];
|
||||
} roothub;
|
||||
} __attribute((aligned(32)));
|
||||
|
||||
|
||||
/* OHCI CONTROL AND STATUS REGISTER MASKS */
|
||||
|
||||
/*
|
||||
* HcControl (control) register masks
|
||||
*/
|
||||
#define OHCI_CTRL_CBSR (3 << 0) /* control/bulk service ratio */
|
||||
#define OHCI_CTRL_PLE (1 << 2) /* periodic list enable */
|
||||
#define OHCI_CTRL_IE (1 << 3) /* isochronous enable */
|
||||
#define OHCI_CTRL_CLE (1 << 4) /* control list enable */
|
||||
#define OHCI_CTRL_BLE (1 << 5) /* bulk list enable */
|
||||
#define OHCI_CTRL_HCFS (3 << 6) /* host controller functional state */
|
||||
#define OHCI_CTRL_IR (1 << 8) /* interrupt routing */
|
||||
#define OHCI_CTRL_RWC (1 << 9) /* remote wakeup connected */
|
||||
#define OHCI_CTRL_RWE (1 << 10) /* remote wakeup enable */
|
||||
|
||||
/* pre-shifted values for HCFS */
|
||||
# define OHCI_USB_RESET (0 << 6)
|
||||
# define OHCI_USB_RESUME (1 << 6)
|
||||
# define OHCI_USB_OPER (2 << 6)
|
||||
# define OHCI_USB_SUSPEND (3 << 6)
|
||||
|
||||
/*
|
||||
* HcCommandStatus (cmdstatus) register masks
|
||||
*/
|
||||
#define OHCI_HCR (1 << 0) /* host controller reset */
|
||||
#define OHCI_CLF (1 << 1) /* control list filled */
|
||||
#define OHCI_BLF (1 << 2) /* bulk list filled */
|
||||
#define OHCI_OCR (1 << 3) /* ownership change request */
|
||||
#define OHCI_SOC (3 << 16) /* scheduling overrun count */
|
||||
|
||||
/*
|
||||
* masks used with interrupt registers:
|
||||
* HcInterruptStatus (intrstatus)
|
||||
* HcInterruptEnable (intrenable)
|
||||
* HcInterruptDisable (intrdisable)
|
||||
*/
|
||||
#define OHCI_INTR_SO (1 << 0) /* scheduling overrun */
|
||||
#define OHCI_INTR_WDH (1 << 1) /* writeback of done_head */
|
||||
#define OHCI_INTR_SF (1 << 2) /* start frame */
|
||||
#define OHCI_INTR_RD (1 << 3) /* resume detect */
|
||||
#define OHCI_INTR_UE (1 << 4) /* unrecoverable error */
|
||||
#define OHCI_INTR_FNO (1 << 5) /* frame number overflow */
|
||||
#define OHCI_INTR_RHSC (1 << 6) /* root hub status change */
|
||||
#define OHCI_INTR_OC (1 << 30) /* ownership change */
|
||||
#define OHCI_INTR_MIE (1 << 31) /* master interrupt enable */
|
||||
|
||||
|
||||
|
||||
/* Virtual Root HUB */
|
||||
struct virt_root_hub {
|
||||
int devnum; /* Address of Root Hub endpoint */
|
||||
void *dev; /* was urb */
|
||||
void *int_addr;
|
||||
int send;
|
||||
int interval;
|
||||
};
|
||||
|
||||
/* USB HUB CONSTANTS (not OHCI-specific; see hub.h) */
|
||||
|
||||
/* destination of request */
|
||||
#define RH_INTERFACE 0x01
|
||||
#define RH_ENDPOINT 0x02
|
||||
#define RH_OTHER 0x03
|
||||
|
||||
#define RH_CLASS 0x20
|
||||
#define RH_VENDOR 0x40
|
||||
|
||||
/* Requests: bRequest << 8 | bmRequestType */
|
||||
#define RH_GET_STATUS 0x0080
|
||||
#define RH_CLEAR_FEATURE 0x0100
|
||||
#define RH_SET_FEATURE 0x0300
|
||||
#define RH_SET_ADDRESS 0x0500
|
||||
#define RH_GET_DESCRIPTOR 0x0680
|
||||
#define RH_SET_DESCRIPTOR 0x0700
|
||||
#define RH_GET_CONFIGURATION 0x0880
|
||||
#define RH_SET_CONFIGURATION 0x0900
|
||||
#define RH_GET_STATE 0x0280
|
||||
#define RH_GET_INTERFACE 0x0A80
|
||||
#define RH_SET_INTERFACE 0x0B00
|
||||
#define RH_SYNC_FRAME 0x0C80
|
||||
/* Our Vendor Specific Request */
|
||||
#define RH_SET_EP 0x2000
|
||||
|
||||
|
||||
/* Hub port features */
|
||||
#define RH_PORT_CONNECTION 0x00
|
||||
#define RH_PORT_ENABLE 0x01
|
||||
#define RH_PORT_SUSPEND 0x02
|
||||
#define RH_PORT_OVER_CURRENT 0x03
|
||||
#define RH_PORT_RESET 0x04
|
||||
#define RH_PORT_POWER 0x08
|
||||
#define RH_PORT_LOW_SPEED 0x09
|
||||
|
||||
#define RH_C_PORT_CONNECTION 0x10
|
||||
#define RH_C_PORT_ENABLE 0x11
|
||||
#define RH_C_PORT_SUSPEND 0x12
|
||||
#define RH_C_PORT_OVER_CURRENT 0x13
|
||||
#define RH_C_PORT_RESET 0x14
|
||||
|
||||
/* Hub features */
|
||||
#define RH_C_HUB_LOCAL_POWER 0x00
|
||||
#define RH_C_HUB_OVER_CURRENT 0x01
|
||||
|
||||
#define RH_DEVICE_REMOTE_WAKEUP 0x00
|
||||
#define RH_ENDPOINT_STALL 0x01
|
||||
|
||||
#define RH_ACK 0x01
|
||||
#define RH_REQ_ERR -1
|
||||
#define RH_NACK 0x00
|
||||
|
||||
|
||||
/* OHCI ROOT HUB REGISTER MASKS */
|
||||
|
||||
/* roothub.portstatus [i] bits */
|
||||
#define RH_PS_CCS 0x00000001 /* current connect status */
|
||||
#define RH_PS_PES 0x00000002 /* port enable status*/
|
||||
#define RH_PS_PSS 0x00000004 /* port suspend status */
|
||||
#define RH_PS_POCI 0x00000008 /* port over current indicator */
|
||||
#define RH_PS_PRS 0x00000010 /* port reset status */
|
||||
#define RH_PS_PPS 0x00000100 /* port power status */
|
||||
#define RH_PS_LSDA 0x00000200 /* low speed device attached */
|
||||
#define RH_PS_CSC 0x00010000 /* connect status change */
|
||||
#define RH_PS_PESC 0x00020000 /* port enable status change */
|
||||
#define RH_PS_PSSC 0x00040000 /* port suspend status change */
|
||||
#define RH_PS_OCIC 0x00080000 /* over current indicator change */
|
||||
#define RH_PS_PRSC 0x00100000 /* port reset status change */
|
||||
|
||||
/* roothub.status bits */
|
||||
#define RH_HS_LPS 0x00000001 /* local power status */
|
||||
#define RH_HS_OCI 0x00000002 /* over current indicator */
|
||||
#define RH_HS_DRWE 0x00008000 /* device remote wakeup enable */
|
||||
#define RH_HS_LPSC 0x00010000 /* local power status change */
|
||||
#define RH_HS_OCIC 0x00020000 /* over current indicator change */
|
||||
#define RH_HS_CRWE 0x80000000 /* clear remote wakeup enable */
|
||||
|
||||
/* roothub.b masks */
|
||||
#define RH_B_DR 0x0000ffff /* device removable flags */
|
||||
#define RH_B_PPCM 0xffff0000 /* port power control mask */
|
||||
|
||||
/* roothub.a masks */
|
||||
#define RH_A_NDP (0xff << 0) /* number of downstream ports */
|
||||
#define RH_A_PSM (1 << 8) /* power switching mode */
|
||||
#define RH_A_NPS (1 << 9) /* no power switching */
|
||||
#define RH_A_DT (1 << 10) /* device type (mbz) */
|
||||
#define RH_A_OCPM (1 << 11) /* over current protection mode */
|
||||
#define RH_A_NOCP (1 << 12) /* no over current protection */
|
||||
#define RH_A_POTPGT (0xff << 24) /* power on to power good time */
|
||||
|
||||
/* urb */
|
||||
#define N_URB_TD 48
|
||||
typedef struct
|
||||
{
|
||||
ed_t *ed;
|
||||
__u16 length; /* number of tds associated with this request */
|
||||
__u16 td_cnt; /* number of tds already serviced */
|
||||
int state;
|
||||
unsigned long pipe;
|
||||
int actual_length;
|
||||
td_t *td[N_URB_TD]; /* list pointer to all corresponding TDs associated with this request */
|
||||
} urb_priv_t;
|
||||
#define URB_DEL 1
|
||||
|
||||
/*
|
||||
* This is the full ohci controller description
|
||||
*
|
||||
* Note how the "proper" USB information is just
|
||||
* a subset of what the full implementation needs. (Linus)
|
||||
*/
|
||||
|
||||
|
||||
typedef struct ohci {
|
||||
struct ohci_hcca *hcca; /* hcca */
|
||||
/*dma_addr_t hcca_dma;*/
|
||||
|
||||
int irq;
|
||||
int disabled; /* e.g. got a UE, we're hung */
|
||||
int sleeping;
|
||||
unsigned long flags; /* for HC bugs */
|
||||
|
||||
struct ohci_regs *regs; /* OHCI controller's memory */
|
||||
|
||||
ed_t *ed_rm_list[2]; /* lists of all endpoints to be removed */
|
||||
ed_t *ed_bulktail; /* last endpoint of bulk list */
|
||||
ed_t *ed_controltail; /* last endpoint of control list */
|
||||
int intrstatus;
|
||||
__u32 hc_control; /* copy of the hc control reg */
|
||||
struct usb_device *dev[32];
|
||||
struct virt_root_hub rh;
|
||||
|
||||
const char *slot_name;
|
||||
} ohci_t;
|
||||
|
||||
#define NUM_EDS 8 /* num of preallocated endpoint descriptors */
|
||||
|
||||
struct ohci_device {
|
||||
ed_t ed[NUM_EDS];
|
||||
int ed_cnt;
|
||||
};
|
||||
|
||||
/* hcd */
|
||||
/* endpoint */
|
||||
static int ep_link(ohci_t * ohci, ed_t * ed);
|
||||
static int ep_unlink(ohci_t * ohci, ed_t * ed);
|
||||
static ed_t * ep_add_ed(struct usb_device * usb_dev, unsigned long pipe);
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
/* we need more TDs than EDs */
|
||||
#define NUM_TD 64
|
||||
|
||||
/* +1 so we can align the storage */
|
||||
td_t gtd[NUM_TD+1];
|
||||
/* pointers to aligned storage */
|
||||
td_t *ptd;
|
||||
|
||||
/* TDs ... */
|
||||
static inline struct td *
|
||||
td_alloc (struct usb_device *usb_dev)
|
||||
{
|
||||
int i;
|
||||
struct td *td;
|
||||
|
||||
td = NULL;
|
||||
for (i = 0; i < NUM_TD; i++)
|
||||
{
|
||||
if (ptd[i].usb_dev == NULL)
|
||||
{
|
||||
td = &ptd[i];
|
||||
td->usb_dev = usb_dev;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return td;
|
||||
}
|
||||
|
||||
static inline void
|
||||
ed_free (struct ed *ed)
|
||||
{
|
||||
ed->usb_dev = NULL;
|
||||
}
|
||||
43
cpu/arm926ejs/Makefile
Normal file
43
cpu/arm926ejs/Makefile
Normal file
@@ -0,0 +1,43 @@
|
||||
#
|
||||
# (C) Copyright 2000-2003
|
||||
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
#
|
||||
# See file CREDITS for list of people who contributed to this
|
||||
# project.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License as
|
||||
# published by the Free Software Foundation; either version 2 of
|
||||
# the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
# MA 02111-1307 USA
|
||||
#
|
||||
|
||||
include $(TOPDIR)/config.mk
|
||||
|
||||
LIB = lib$(CPU).a
|
||||
|
||||
START = start.o
|
||||
OBJS = interrupts.o cpu.o
|
||||
|
||||
all: .depend $(START) $(LIB)
|
||||
|
||||
$(LIB): $(OBJS)
|
||||
$(AR) crv $@ $(OBJS)
|
||||
|
||||
#########################################################################
|
||||
|
||||
.depend: Makefile $(START:.o=.S) $(OBJS:.o=.c)
|
||||
$(CC) -M $(CFLAGS) $(START:.o=.S) $(OBJS:.o=.c) > $@
|
||||
|
||||
sinclude .depend
|
||||
|
||||
#########################################################################
|
||||
27
cpu/arm926ejs/config.mk
Normal file
27
cpu/arm926ejs/config.mk
Normal file
@@ -0,0 +1,27 @@
|
||||
#
|
||||
# (C) Copyright 2002
|
||||
# Gary Jennejohn, DENX Software Engineering, <gj@denx.de>
|
||||
#
|
||||
# See file CREDITS for list of people who contributed to this
|
||||
# project.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License as
|
||||
# published by the Free Software Foundation; either version 2 of
|
||||
# the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
# MA 02111-1307 USA
|
||||
#
|
||||
|
||||
PLATFORM_RELFLAGS += -fno-strict-aliasing -fno-common -ffixed-r8 \
|
||||
-mshort-load-bytes -msoft-float
|
||||
|
||||
PLATFORM_CPPFLAGS += -mapcs-32 -march=armv4
|
||||
159
cpu/arm926ejs/cpu.c
Normal file
159
cpu/arm926ejs/cpu.c
Normal file
@@ -0,0 +1,159 @@
|
||||
/*
|
||||
* (C) Copyright 2002
|
||||
* Sysgo Real-Time Solutions, GmbH <www.elinos.com>
|
||||
* Marius Groeger <mgroeger@sysgo.de>
|
||||
*
|
||||
* (C) Copyright 2002
|
||||
* Gary Jennejohn, DENX Software Engineering, <gj@denx.de>
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/*
|
||||
* CPU specific code
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <command.h>
|
||||
#include <arm926ejs.h>
|
||||
|
||||
/* read co-processor 15, register #1 (control register) */
|
||||
static unsigned long read_p15_c1 (void)
|
||||
{
|
||||
unsigned long value;
|
||||
|
||||
__asm__ __volatile__(
|
||||
"mrc p15, 0, %0, c1, c0, 0 @ read control reg\n"
|
||||
: "=r" (value)
|
||||
:
|
||||
: "memory");
|
||||
|
||||
#ifdef MMU_DEBUG
|
||||
printf ("p15/c1 is = %08lx\n", value);
|
||||
#endif
|
||||
return value;
|
||||
}
|
||||
|
||||
/* write to co-processor 15, register #1 (control register) */
|
||||
static void write_p15_c1 (unsigned long value)
|
||||
{
|
||||
#ifdef MMU_DEBUG
|
||||
printf ("write %08lx to p15/c1\n", value);
|
||||
#endif
|
||||
__asm__ __volatile__(
|
||||
"mcr p15, 0, %0, c1, c0, 0 @ write it back\n"
|
||||
:
|
||||
: "r" (value)
|
||||
: "memory");
|
||||
|
||||
read_p15_c1 ();
|
||||
}
|
||||
|
||||
static void cp_delay (void)
|
||||
{
|
||||
volatile int i;
|
||||
|
||||
/* Many OMAP regs need at least 2 nops */
|
||||
for (i = 0; i < 100; i++);
|
||||
}
|
||||
|
||||
/* See also ARM Ref. Man. */
|
||||
#define C1_MMU (1<<0) /* mmu off/on */
|
||||
#define C1_ALIGN (1<<1) /* alignment faults off/on */
|
||||
#define C1_DC (1<<2) /* dcache off/on */
|
||||
#define C1_WB (1<<3) /* merging write buffer on/off */
|
||||
#define C1_BIG_ENDIAN (1<<7) /* big endian off/on */
|
||||
#define C1_SYS_PROT (1<<8) /* system protection */
|
||||
#define C1_ROM_PROT (1<<9) /* ROM protection */
|
||||
#define C1_IC (1<<12) /* icache off/on */
|
||||
#define C1_HIGH_VECTORS (1<<13) /* location of vectors: low/high addresses */
|
||||
#define RESERVED_1 (0xf << 3) /* must be 111b for R/W */
|
||||
|
||||
int cpu_init (void)
|
||||
{
|
||||
/*
|
||||
* setup up stack if necessary
|
||||
*/
|
||||
#ifdef CONFIG_USE_IRQ
|
||||
IRQ_STACK_START = _armboot_end +
|
||||
CONFIG_STACKSIZE + CONFIG_STACKSIZE_IRQ - 4;
|
||||
FIQ_STACK_START = IRQ_STACK_START + CONFIG_STACKSIZE_FIQ;
|
||||
_armboot_real_end = FIQ_STACK_START + 4;
|
||||
#else
|
||||
_armboot_real_end = _armboot_end + CONFIG_STACKSIZE;
|
||||
#endif /* CONFIG_USE_IRQ */
|
||||
return (0);
|
||||
}
|
||||
|
||||
int cleanup_before_linux (void)
|
||||
{
|
||||
/*
|
||||
* this function is called just before we call linux
|
||||
* it prepares the processor for linux
|
||||
*
|
||||
* we turn off caches etc ...
|
||||
*/
|
||||
|
||||
unsigned long i;
|
||||
|
||||
disable_interrupts ();
|
||||
|
||||
/* turn off I/D-cache */
|
||||
asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i));
|
||||
i &= ~(C1_DC | C1_IC);
|
||||
asm ("mcr p15, 0, %0, c1, c0, 0": :"r" (i));
|
||||
|
||||
/* flush I/D-cache */
|
||||
i = 0;
|
||||
asm ("mcr p15, 0, %0, c7, c7, 0": :"r" (i));
|
||||
return (0);
|
||||
}
|
||||
|
||||
int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
|
||||
{
|
||||
extern void reset_cpu (ulong addr);
|
||||
|
||||
disable_interrupts ();
|
||||
reset_cpu (0);
|
||||
/*NOTREACHED*/
|
||||
return (0);
|
||||
}
|
||||
|
||||
void icache_enable (void)
|
||||
{
|
||||
ulong reg;
|
||||
|
||||
reg = read_p15_c1 (); /* get control reg. */
|
||||
cp_delay ();
|
||||
write_p15_c1 (reg | C1_IC);
|
||||
}
|
||||
|
||||
void icache_disable (void)
|
||||
{
|
||||
ulong reg;
|
||||
|
||||
reg = read_p15_c1 ();
|
||||
cp_delay ();
|
||||
write_p15_c1 (reg & ~C1_IC);
|
||||
}
|
||||
|
||||
int icache_status (void)
|
||||
{
|
||||
return (read_p15_c1 () & C1_IC) != 0;
|
||||
}
|
||||
293
cpu/arm926ejs/interrupts.c
Normal file
293
cpu/arm926ejs/interrupts.c
Normal file
@@ -0,0 +1,293 @@
|
||||
/*
|
||||
* (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 <arm925t.h>
|
||||
#include <configs/omap1510.h>
|
||||
|
||||
#include <asm/proc-armv/ptrace.h>
|
||||
|
||||
extern void reset_cpu(ulong addr);
|
||||
#define TIMER_LOAD_VAL 0xffffffff
|
||||
|
||||
/* macro to read the 32 bit timer */
|
||||
#define READ_TIMER (*(volatile ulong *)(CFG_TIMERBASE+8))
|
||||
|
||||
#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;
|
||||
|
||||
/* nothing really to do with interrupts, just starts up a counter. */
|
||||
int interrupt_init (void)
|
||||
{
|
||||
int32_t val;
|
||||
|
||||
*((int32_t *) (CFG_TIMERBASE + LOAD_TIM)) = TIMER_LOAD_VAL;
|
||||
val = MPUTIM_ST | MPUTIM_AR | MPUTIM_CLOCK_ENABLE |
|
||||
(CFG_PVT << MPUTIM_PTV_BIT);
|
||||
*((int32_t *) (CFG_TIMERBASE + CNTL_TIMER)) = val;
|
||||
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;
|
||||
}
|
||||
|
||||
/* very rough timer... */
|
||||
void udelay (unsigned long usec)
|
||||
{
|
||||
#ifdef CONFIG_INNOVATOROMAP1610
|
||||
#define LOOPS_PER_MSEC 100 /* tuned on omap1610 */
|
||||
volatile int i, time_remaining = LOOPS_PER_MSEC * usec;
|
||||
|
||||
for (i = time_remaining; i > 0; i--) {
|
||||
}
|
||||
#else
|
||||
|
||||
ulong tmo;
|
||||
tmo = usec / 1000;
|
||||
tmo *= CFG_HZ;
|
||||
tmo /= 1000;
|
||||
tmo += get_timer (0);
|
||||
while (get_timer_masked () < tmo)
|
||||
/*NOP*/;
|
||||
#endif
|
||||
}
|
||||
|
||||
void reset_timer_masked (void)
|
||||
{
|
||||
/* reset time */
|
||||
lastdec = READ_TIMER;
|
||||
timestamp = 0;
|
||||
}
|
||||
|
||||
ulong get_timer_masked (void)
|
||||
{
|
||||
ulong now = READ_TIMER; /* current tick value */
|
||||
|
||||
if (lastdec >= now) { /* did I roll (rem decrementer) */
|
||||
/* normal mode */
|
||||
/* record amount of time since last check */
|
||||
timestamp += lastdec - now;
|
||||
} else {
|
||||
/* we have an overflow ... */
|
||||
timestamp += lastdec + TIMER_LOAD_VAL - now;
|
||||
}
|
||||
lastdec = now;
|
||||
|
||||
return timestamp;
|
||||
}
|
||||
|
||||
void udelay_masked (unsigned long usec)
|
||||
{
|
||||
#ifdef CONFIG_INNOVATOROMAP1610
|
||||
#define LOOPS_PER_MSEC 100 /* tuned on omap1610 */
|
||||
volatile int i, time_remaining = LOOPS_PER_MSEC*usec;
|
||||
for (i=time_remaining; i>0; i--) { }
|
||||
#else
|
||||
|
||||
ulong tmo;
|
||||
|
||||
tmo = usec / 1000;
|
||||
tmo *= CFG_HZ;
|
||||
tmo /= 1000;
|
||||
|
||||
reset_timer_masked ();
|
||||
|
||||
while (get_timer_masked () < tmo)
|
||||
/*NOP*/;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* This function is derived from PowerPC code (read timebase as long long).
|
||||
* On ARM it just returns the timer value.
|
||||
*/
|
||||
unsigned long long get_ticks(void)
|
||||
{
|
||||
return get_timer(0);
|
||||
}
|
||||
|
||||
/*
|
||||
* This function is derived from PowerPC code (timebase clock frequency).
|
||||
* On ARM it returns the number of timer ticks per second.
|
||||
*/
|
||||
ulong get_tbclk (void)
|
||||
{
|
||||
ulong tbclk;
|
||||
tbclk = CFG_HZ;
|
||||
return tbclk;
|
||||
}
|
||||
426
cpu/arm926ejs/start.S
Normal file
426
cpu/arm926ejs/start.S
Normal file
@@ -0,0 +1,426 @@
|
||||
/*
|
||||
* armboot - Startup Code for ARM926EJS CPU-core
|
||||
*
|
||||
* Copyright (c) 2003 Texas Instruments
|
||||
*
|
||||
* ----- Adapted for OMAP1610 from ARM925t code ------
|
||||
*
|
||||
* Copyright (c) 2001 Marius Gröger <mag@sysgo.de>
|
||||
* Copyright (c) 2002 Alex Züpke <azu@sysgo.de>
|
||||
* Copyright (c) 2002 Gary Jennejohn <gj@denx.de>
|
||||
* Copyright (c) 2003 Richard Woodruff <r-woodruff2@ti.com>
|
||||
* Copyright (c) 2003 Kshitij <kshitij@ti.com>
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include <config.h>
|
||||
#include <version.h>
|
||||
|
||||
#if defined(CONFIG_OMAP1610)
|
||||
#include <./configs/omap1510.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
*************************************************************************
|
||||
*
|
||||
* Jump vector table as in table 3.1 in [1]
|
||||
*
|
||||
*************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
.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!
|
||||
* setup Memory and board specific bits prior to relocation.
|
||||
* relocate armboot to ram
|
||||
* setup stack
|
||||
*
|
||||
*************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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
|
||||
|
||||
#ifdef CONFIG_USE_IRQ
|
||||
/* IRQ stack memory (calculated at run-time) */
|
||||
.globl IRQ_STACK_START
|
||||
IRQ_STACK_START:
|
||||
.word 0x0badc0de
|
||||
|
||||
/* IRQ stack memory (calculated at run-time) */
|
||||
.globl FIQ_STACK_START
|
||||
FIQ_STACK_START:
|
||||
.word 0x0badc0de
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* the actual reset code
|
||||
*/
|
||||
|
||||
reset:
|
||||
/*
|
||||
* set the cpu to SVC32 mode
|
||||
*/
|
||||
mrs r0,cpsr
|
||||
bic r0,r0,#0x1f
|
||||
orr r0,r0,#0xd3
|
||||
msr cpsr,r0
|
||||
|
||||
|
||||
/*
|
||||
* turn off the watchdog, unlock/diable sequence
|
||||
*/
|
||||
mov r1, #0xF5
|
||||
ldr r0, =WDTIM_MODE
|
||||
strh r1, [r0]
|
||||
mov r1, #0xA0
|
||||
strh r1, [r0]
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* mask all IRQs by setting all bits in the INTMR - default
|
||||
*/
|
||||
|
||||
mov r1, #0xffffffff
|
||||
ldr r0, =REG_IHL1_MIR
|
||||
str r1, [r0]
|
||||
ldr r0, =REG_IHL2_MIR
|
||||
str r1, [r0]
|
||||
bl cpu_init_crit
|
||||
|
||||
relocate:
|
||||
/*
|
||||
* relocate armboot 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, _TEXT_BASE /* r1 <- destination address */
|
||||
add r2, r0, r2 /* r2 <- source end address */
|
||||
|
||||
/*
|
||||
* r0 = source address
|
||||
* r1 = target address
|
||||
* r2 = source end address
|
||||
*/
|
||||
copy_loop:
|
||||
ldmia r0!, {r3-r10}
|
||||
stmia r1!, {r3-r10}
|
||||
cmp r0, r2
|
||||
ble copy_loop
|
||||
|
||||
/* set up the stack */
|
||||
ldr r0, _armboot_end
|
||||
add r0, r0, #CONFIG_STACKSIZE
|
||||
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
|
||||
*
|
||||
*************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
cpu_init_crit:
|
||||
/*
|
||||
* flush v4 I/D caches
|
||||
*/
|
||||
mov r0, #0
|
||||
mcr p15, 0, r0, c7, c7, 0 /* flush v3/v4 cache */
|
||||
mcr p15, 0, r0, c8, c7, 0 /* flush v4 TLB */
|
||||
|
||||
/*
|
||||
* disable MMU stuff and caches
|
||||
*/
|
||||
mrc p15, 0, r0, c1, c0, 0
|
||||
bic r0, r0, #0x00002300 /* clear bits 13, 9:8 (--V- --RS) */
|
||||
bic r0, r0, #0x00000087 /* clear bits 7, 2:0 (B--- -CAM) */
|
||||
orr r0, r0, #0x00000002 /* set bit 2 (A) Align */
|
||||
orr r0, r0, #0x00001000 /* set bit 12 (I) I-Cache */
|
||||
mcr p15, 0, r0, c1, c0, 0
|
||||
|
||||
/*
|
||||
* Go setup Memory and board specific bits prior to relocation.
|
||||
*/
|
||||
mov ip, lr /* perserve link reg across call */
|
||||
bl platformsetup /* go setup pll,mux,memory */
|
||||
mov lr, ip /* restore link */
|
||||
mov pc, lr /* back to my caller */
|
||||
/*
|
||||
*************************************************************************
|
||||
*
|
||||
* Interrupt handling
|
||||
*
|
||||
*************************************************************************
|
||||
*/
|
||||
|
||||
@
|
||||
@ IRQ stack frame.
|
||||
@
|
||||
#define S_FRAME_SIZE 72
|
||||
|
||||
#define S_OLD_R0 68
|
||||
#define S_PSR 64
|
||||
#define S_PC 60
|
||||
#define S_LR 56
|
||||
#define S_SP 52
|
||||
|
||||
#define S_IP 48
|
||||
#define S_FP 44
|
||||
#define S_R10 40
|
||||
#define S_R9 36
|
||||
#define S_R8 32
|
||||
#define S_R7 28
|
||||
#define S_R6 24
|
||||
#define S_R5 20
|
||||
#define S_R4 16
|
||||
#define S_R3 12
|
||||
#define S_R2 8
|
||||
#define S_R1 4
|
||||
#define S_R0 0
|
||||
|
||||
#define MODE_SVC 0x13
|
||||
#define I_BIT 0x80
|
||||
|
||||
/*
|
||||
* use bad_save_user_regs for abort/prefetch/undef/swi ...
|
||||
* use irq_save_user_regs / irq_restore_user_regs for IRQ/FIQ handling
|
||||
*/
|
||||
|
||||
.macro bad_save_user_regs
|
||||
@ carve out a frame on current user stack
|
||||
sub sp, sp, #S_FRAME_SIZE
|
||||
stmia sp, {r0 - r12} @ Save user registers (now in svc mode) r0-r12
|
||||
ldr r2, _armboot_end @ find top of stack
|
||||
add r2, r2, #CONFIG_STACKSIZE @ find base of normal stack
|
||||
sub r2, r2, #8 @ set base 2 words into abort stack
|
||||
@ get values for "aborted" pc and cpsr (into parm regs)
|
||||
ldmia r2, {r2 - r3}
|
||||
add r0, sp, #S_FRAME_SIZE @ grab pointer to old stack
|
||||
add r5, sp, #S_SP
|
||||
mov r1, lr
|
||||
stmia r5, {r0 - r3} @ save sp_SVC, lr_SVC, pc, cpsr
|
||||
mov r0, sp @ save current stack into r0 (param register)
|
||||
.endm
|
||||
|
||||
.macro irq_save_user_regs
|
||||
sub sp, sp, #S_FRAME_SIZE
|
||||
stmia sp, {r0 - r12} @ Calling r0-r12
|
||||
@ !!!! R8 NEEDS to be saved !!!! a reserved stack spot would be good.
|
||||
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
|
||||
@ get bottom of stack (into sp by by user stack pointer).
|
||||
ldr r13, _armboot_end
|
||||
@ head to reserved words at the top of the stack
|
||||
add r13, r13, #CONFIG_STACKSIZE
|
||||
sub r13, r13, #8 @ reserved a couple spots in abort stack
|
||||
|
||||
str lr, [r13] @ save caller lr in position 0 of saved stack
|
||||
mrs lr, spsr @ get the spsr
|
||||
str lr, [r13, #4] @ save spsr in position 1 of saved stack
|
||||
mov r13, #MODE_SVC @ prepare SVC-Mode
|
||||
@ msr spsr_c, r13
|
||||
msr spsr, r13 @ switch modes, make sure moves will execute
|
||||
mov lr, pc @ capture return pc
|
||||
movs pc, lr @ jump to next instruction & switch modes.
|
||||
.endm
|
||||
|
||||
.macro get_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
|
||||
/* someone ought to write a more effiction fiq_save_user_regs */
|
||||
irq_save_user_regs
|
||||
bl do_fiq
|
||||
irq_restore_user_regs
|
||||
|
||||
#else
|
||||
|
||||
.align 5
|
||||
irq:
|
||||
get_bad_stack
|
||||
bad_save_user_regs
|
||||
bl do_irq
|
||||
|
||||
.align 5
|
||||
fiq:
|
||||
get_bad_stack
|
||||
bad_save_user_regs
|
||||
bl do_fiq
|
||||
|
||||
#endif
|
||||
|
||||
.align 5
|
||||
.globl reset_cpu
|
||||
reset_cpu:
|
||||
ldr r1, rstctl1 /* get clkm1 reset ctl */
|
||||
mov r3, #0x0
|
||||
strh r3, [r1] /* clear it */
|
||||
mov r3, #0x8
|
||||
strh r3, [r1] /* force dsp+arm reset */
|
||||
_loop_forever:
|
||||
b _loop_forever
|
||||
|
||||
|
||||
rstctl1:
|
||||
.word 0xfffece10
|
||||
@@ -54,31 +54,17 @@ int checkcpu (void)
|
||||
int
|
||||
do_reset (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
|
||||
{
|
||||
ulong msr, addr;
|
||||
|
||||
*(vu_long *)MPC5XXX_CDM_SRESET &= ~(1 << 16); /* Checkstop Reset enable */
|
||||
|
||||
ulong msr;
|
||||
/* Interrupts and MMU off */
|
||||
__asm__ __volatile__ ("mfmsr %0":"=r" (msr):);
|
||||
|
||||
msr &= ~(MSR_ME | MSR_EE | MSR_IR | MSR_DR);
|
||||
__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.
|
||||
*/
|
||||
addr = CFG_MONITOR_BASE - sizeof (ulong);
|
||||
#endif
|
||||
((void (*)(void)) addr) ();
|
||||
/* Charge the watchdog timer */
|
||||
*(vu_long *)(MPC5XXX_GPT0_COUNTER) = 0xf;
|
||||
*(vu_long *)(MPC5XXX_GPT0_ENABLE) = 0x9004; /* wden|ce|timer_ms */
|
||||
|
||||
return 1;
|
||||
|
||||
}
|
||||
|
||||
@@ -24,14 +24,6 @@
|
||||
#include <common.h>
|
||||
#include <mpc5xxx.h>
|
||||
|
||||
#if defined(CONFIG_MGT5100)
|
||||
#define START_REG(start) ((start) >> 15)
|
||||
#define STOP_REG(start, size) (((start) + (size) - 1) >> 15)
|
||||
#elif defined(CONFIG_MPC5200)
|
||||
#define START_REG(start) ((start) >> 16)
|
||||
#define STOP_REG(start, size) (((start) + (size) - 1) >> 16)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Breath some life into the CPU...
|
||||
*
|
||||
@@ -159,6 +151,14 @@ void cpu_init_f (void)
|
||||
#if defined(CONFIG_MPC5200)
|
||||
/* enable timebase */
|
||||
*(vu_long *)(MPC5XXX_XLBARB + 0x40) |= (1 << 13);
|
||||
|
||||
/* Motorola reports IPB should better run at 133 MHz. */
|
||||
*(vu_long *)MPC5XXX_ADDECR |= 1;
|
||||
/* pci_clk_sel = 0x02, ipb_clk_sel = 0x00; */
|
||||
addecr = *(vu_long *)MPC5XXX_CDM_CFG;
|
||||
addecr &= ~0x103;
|
||||
addecr |= 0x02;
|
||||
*(vu_long *)MPC5XXX_CDM_CFG = addecr;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -208,6 +208,7 @@ static void mpc5xxx_fec_set_hwaddr(mpc5xxx_fec_priv *fec, char *mac)
|
||||
/********************************************************************/
|
||||
static int mpc5xxx_fec_init(struct eth_device *dev, bd_t * bis)
|
||||
{
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
mpc5xxx_fec_priv *fec = (mpc5xxx_fec_priv *)dev->priv;
|
||||
struct mpc5xxx_sdma *sdma = (struct mpc5xxx_sdma *)MPC5XXX_SDMA;
|
||||
const uint8 phyAddr = 0; /* Only one PHY */
|
||||
@@ -269,10 +270,10 @@ static int mpc5xxx_fec_init(struct eth_device *dev, bd_t * bis)
|
||||
fec->eth->x_cntrl = 0x00000004; /* full-duplex, heartbeat disabled */
|
||||
|
||||
/*
|
||||
* Set MII_SPEED = (1/(mii_speed * 2)) * System Clock(25Mhz)
|
||||
* Set MII_SPEED = (1/(mii_speed * 2)) * System Clock
|
||||
* and do not drop the Preamble.
|
||||
*/
|
||||
fec->eth->mii_speed = (0x5 << 1); /* No MII for 7-wire mode */
|
||||
fec->eth->mii_speed = (((gd->ipb_clk >> 20) / 5) << 1); /* No MII for 7-wire mode */
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -809,9 +810,13 @@ int mpc5xxx_fec_initialize(bd_t * bis)
|
||||
{
|
||||
mpc5xxx_fec_priv *fec;
|
||||
struct eth_device *dev;
|
||||
char *tmp, *end;
|
||||
char env_enetaddr[6];
|
||||
int i;
|
||||
|
||||
fec = (mpc5xxx_fec_priv *)malloc(sizeof(*fec));
|
||||
dev = (struct eth_device *)malloc(sizeof(*dev));
|
||||
memset(dev, 0, sizeof *dev);
|
||||
|
||||
fec->eth = (ethernet_regs *)MPC5XXX_FEC;
|
||||
fec->tbdBase = (FEC_TBD *)FEC_BD_BASE;
|
||||
@@ -830,6 +835,21 @@ int mpc5xxx_fec_initialize(bd_t * bis)
|
||||
sprintf(dev->name, "FEC ETHERNET");
|
||||
eth_register(dev);
|
||||
|
||||
/*
|
||||
* Try to set the mac address now. The fec mac address is
|
||||
* a garbage after reset. When not using fec for booting
|
||||
* the Linux fec driver will try to work with this garbage.
|
||||
*/
|
||||
tmp = getenv("ethaddr");
|
||||
if (tmp) {
|
||||
for (i=0; i<6; i++) {
|
||||
env_enetaddr[i] = tmp ? simple_strtoul(tmp, &end, 16) : 0;
|
||||
if (tmp)
|
||||
tmp = (*end) ? end+1 : end;
|
||||
}
|
||||
mpc5xxx_fec_set_hwaddr(fec, env_enetaddr);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -25,14 +25,14 @@ include $(TOPDIR)/config.mk
|
||||
|
||||
LIB = lib$(CPU).a
|
||||
|
||||
START = start.S drivers/i2c/i2c2.o
|
||||
START = start.S
|
||||
OBJS = traps.o cpu.o cpu_init.o interrupts.o speed.o \
|
||||
drivers/epic/epic1.o drivers/i2c/i2c1.o pci.o bedbug_603e.o
|
||||
drivers/epic/epic1.o drivers/i2c/i2c.o pci.o bedbug_603e.o
|
||||
|
||||
all: .depend $(START) $(LIB)
|
||||
|
||||
$(LIB): $(OBJS)
|
||||
$(AR) crv $@ $(OBJS) drivers/i2c/i2c2.o
|
||||
$(AR) crv $@ $(OBJS)
|
||||
|
||||
bedbug_603e.c:
|
||||
ln -s ../mpc8260/bedbug_603e.c bedbug_603e.c
|
||||
|
||||
@@ -1,84 +0,0 @@
|
||||
##########################################################################
|
||||
#
|
||||
# Copyright Motorola, Inc. 1997
|
||||
# ALL RIGHTS RESERVED
|
||||
#
|
||||
# You are hereby granted a copyright license to use, modify, and
|
||||
# distribute the SOFTWARE so long as this entire notice is retained
|
||||
# without alteration in any modified and/or redistributed versions,
|
||||
# and that such modified versions are clearly identified as such.
|
||||
# No licenses are granted by implication, estoppel or otherwise under
|
||||
# any patents or trademarks of Motorola, Inc.
|
||||
#
|
||||
# The SOFTWARE is provided on an "AS IS" basis and without warranty.
|
||||
# To the maximum extent permitted by applicable law, MOTOROLA DISCLAIMS
|
||||
# ALL WARRANTIES WHETHER EXPRESS OR IMPLIED, INCLUDING IMPLIED
|
||||
# WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR
|
||||
# PURPOSE AND ANY WARRANTY AGAINST INFRINGEMENT WITH
|
||||
# REGARD TO THE SOFTWARE (INCLUDING ANY MODIFIED VERSIONS
|
||||
# THEREOF) AND ANY ACCOMPANYING WRITTEN MATERIALS.
|
||||
#
|
||||
# To the maximum extent permitted by applicable law, IN NO EVENT SHALL
|
||||
# MOTOROLA BE LIABLE FOR ANY DAMAGES WHATSOEVER
|
||||
# (INCLUDING WITHOUT LIMITATION, DAMAGES FOR LOSS OF
|
||||
# BUSINESS PROFITS, BUSINESS INTERRUPTION, LOSS OF BUSINESS
|
||||
# INFORMATION, OR OTHER PECUNIARY LOSS) ARISING OF THE USE OR
|
||||
# INABILITY TO USE THE SOFTWARE.
|
||||
#
|
||||
############################################################################
|
||||
TARGET = libi2c.a
|
||||
|
||||
#DEBUG = -g
|
||||
DEBUG = -DI2CDBG
|
||||
LST = -Hanno -S
|
||||
OPTIM =
|
||||
CC = /risc/tools/pkgs/metaware/bin/hcppc
|
||||
CFLAGS = -Hnocopyr -c -Hsds -Hon=Char_default_unsigned -Hon=Char_is_rep -I../inc -I/risc/tools/pkgs/metaware/inc
|
||||
CCobj = $(CC) $(CFLAGS) $(DEBUG) $(OPTIM)
|
||||
PREP = $(CC) $(CFLAGS) -P
|
||||
|
||||
# Assembler used to build the .s files (for the board version)
|
||||
|
||||
ASOPT = -big_si -c
|
||||
ASDEBUG = -l -fm
|
||||
AS = /risc/tools/pkgs/metaware/bin/asppc
|
||||
|
||||
# Linker to bring .o files together into an executable.
|
||||
|
||||
LKOPT = -Bbase=0 -q -Qn -r
|
||||
LKCMD =
|
||||
LINK = /risc/tools/pkgs/metaware/bin/ldppc $(LKCMD) $(LKOPT)
|
||||
|
||||
# DOS Utilities
|
||||
|
||||
DEL = rm
|
||||
COPY = cp
|
||||
LIST = ls
|
||||
|
||||
OBJECTS = i2c1.o i2c2.o
|
||||
|
||||
all: $(TARGET)
|
||||
|
||||
objects: $(OBJECTS)
|
||||
|
||||
$(TARGET): $(OBJECTS)
|
||||
$(LINK) $(OBJECTS) -o $@
|
||||
|
||||
clean:
|
||||
$(DEL) -f *.o *.i *.map *.lst $(TARGET) $(OBJECTS)
|
||||
|
||||
.s.o:
|
||||
$(DEL) -f $*.i
|
||||
$(PREP) -Hasmcpp $<
|
||||
$(AS) $(ASOPT) $*.i
|
||||
# $(AS) $(ASOPT) $(ASDEBUG) $*.i > $*.lst
|
||||
|
||||
.c.o:
|
||||
$(CCobj) $<
|
||||
|
||||
.c.s:
|
||||
$(CCobj) $(LST) $<
|
||||
|
||||
i2c1.o: i2c_export.h i2c.h i2c1.c
|
||||
|
||||
i2c2.o: i2c.h i2c2.s
|
||||
@@ -1,91 +0,0 @@
|
||||
##########################################################################
|
||||
#
|
||||
# makefile_pc for use with PC mksnt tools dink32/drivers/i2c
|
||||
#
|
||||
# Copyright Motorola, Inc. 1997
|
||||
# ALL RIGHTS RESERVED
|
||||
#
|
||||
# You are hereby granted a copyright license to use, modify, and
|
||||
# distribute the SOFTWARE so long as this entire notice is retained
|
||||
# without alteration in any modified and/or redistributed versions,
|
||||
# and that such modified versions are clearly identified as such.
|
||||
# No licenses are granted by implication, estoppel or otherwise under
|
||||
# any patents or trademarks of Motorola, Inc.
|
||||
#
|
||||
# The SOFTWARE is provided on an "AS IS" basis and without warranty.
|
||||
# To the maximum extent permitted by applicable law, MOTOROLA DISCLAIMS
|
||||
# ALL WARRANTIES WHETHER EXPRESS OR IMPLIED, INCLUDING IMPLIED
|
||||
# WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR
|
||||
# PURPOSE AND ANY WARRANTY AGAINST INFRINGEMENT WITH
|
||||
# REGARD TO THE SOFTWARE (INCLUDING ANY MODIFIED VERSIONS
|
||||
# THEREOF) AND ANY ACCOMPANYING WRITTEN MATERIALS.
|
||||
#
|
||||
# To the maximum extent permitted by applicable law, IN NO EVENT SHALL
|
||||
# MOTOROLA BE LIABLE FOR ANY DAMAGES WHATSOEVER
|
||||
# (INCLUDING WITHOUT LIMITATION, DAMAGES FOR LOSS OF
|
||||
# BUSINESS PROFITS, BUSINESS INTERRUPTION, LOSS OF BUSINESS
|
||||
# INFORMATION, OR OTHER PECUNIARY LOSS) ARISING OF THE USE OR
|
||||
# INABILITY TO USE THE SOFTWARE.
|
||||
#
|
||||
############################################################################
|
||||
TARGET = libi2c.a
|
||||
|
||||
#DEBUG = -g
|
||||
DEBUG = -DI2CDBG
|
||||
LST = -Hanno -S
|
||||
OPTIM =
|
||||
CC = m:/old_tools/tools/hcppc/bin/hcppc
|
||||
CFLAGS = -Hnocopyr -c -Hsds -Hon=Char_default_unsigned -Hon=Char_is_rep -I../inc -I/risc/tools/pkgs/metaware/inc
|
||||
CCobj = $(CC) $(CFLAGS) $(DEBUG) $(OPTIM)
|
||||
PREP = $(CC) $(CFLAGS) -P
|
||||
|
||||
# Assembler used to build the .s files (for the board version)
|
||||
|
||||
ASOPT = -big_si -c
|
||||
ASDEBUG = -l -fm
|
||||
AS = m:/old_tools/tools/hcppc/bin/asppc
|
||||
|
||||
# Linker to bring .o files together into an executable.
|
||||
|
||||
LKOPT = -Bbase=0 -q -Qn -r
|
||||
LKCMD =
|
||||
LINK = m:/old_tools/tools/hcppc/bin/ldppc $(LKCMD) $(LKOPT)
|
||||
|
||||
# DOS Utilities
|
||||
|
||||
DEL = rm
|
||||
COPY = cp
|
||||
LIST = ls
|
||||
|
||||
OBJECTS = i2c1.o i2c2.o
|
||||
|
||||
all: $(TARGET)
|
||||
|
||||
objects: $(OBJECTS)
|
||||
|
||||
$(TARGET): $(OBJECTS)
|
||||
$(LINK) $(OBJECTS) -o $@
|
||||
|
||||
clean:
|
||||
$(DEL) -f *.o *.i *.map *.lst $(TARGET) $(OBJECTS)
|
||||
|
||||
.s.o:
|
||||
$(DEL) -f $*.i
|
||||
$(PREP) -Hasmcpp $<
|
||||
$(AS) $(ASOPT) $*.i
|
||||
# $(AS) $(ASOPT) $(ASDEBUG) $*.i > $*.lst
|
||||
|
||||
.c.o:
|
||||
$(CCobj) $<
|
||||
|
||||
.c.s:
|
||||
$(CCobj) $(LST) $<
|
||||
|
||||
i2c1.o: i2c_export.h i2c.h i2c1.c
|
||||
$(CCobj) $<
|
||||
|
||||
|
||||
i2c2.o: i2c.h i2c2.s
|
||||
$(DEL) -f $*.i
|
||||
$(PREP) -Hasmcpp $<
|
||||
$(AS) $(ASOPT) $*.i
|
||||
@@ -1,104 +0,0 @@
|
||||
CONTENT:
|
||||
|
||||
i2c.h
|
||||
i2c1.c
|
||||
i2c2.s
|
||||
|
||||
WHAT ARE THESE FILES:
|
||||
|
||||
These files contain MPC8240 (Kahlua) I2C
|
||||
driver routines. The driver routines are not
|
||||
written for any specific operating system.
|
||||
They serves the purpose of code sample, and
|
||||
jump-start for using the MPC8240 I2C unit.
|
||||
|
||||
For the reason of correctness of C language
|
||||
syntax, these files are compiled by Metaware
|
||||
C compiler and assembler.
|
||||
|
||||
ENDIAN NOTATION:
|
||||
|
||||
The algorithm is designed for big-endian mode,
|
||||
software is responsible for byte swapping.
|
||||
|
||||
USAGE:
|
||||
|
||||
1. The host system that is running on MPC8240
|
||||
shall link the files listed here. The memory
|
||||
location of driver routines shall take into
|
||||
account of that driver routines need to run
|
||||
in supervisor mode and they process I2C
|
||||
interrupt.
|
||||
|
||||
2. The host system is responsible for configuring
|
||||
the MPC8240 including Embedded Utilities Memory
|
||||
Block. All I2C driver functions require the
|
||||
content of Embedded Utilities Memory Block
|
||||
Base Address Register, EUMBBAR, as the first
|
||||
parameter.
|
||||
|
||||
3. Before I2C unit of MPC8240 can be used,
|
||||
initialize I2C unit by calling I2C_Init
|
||||
with the corresponding parameters.
|
||||
|
||||
Note that the I2CFDR register shall be written
|
||||
once during the initialization. If it is written
|
||||
in the midst of transers, or after I2C STOPs or
|
||||
REPEAT STATRs, depending on the data written,
|
||||
a long reset time may be encountered.
|
||||
|
||||
4. After I2C unit has been successfully initialized,
|
||||
use the Application level API to send data or
|
||||
receive data upon the desired mode, Master or
|
||||
Slave.
|
||||
|
||||
5. If the host system is also using the EPIC unit
|
||||
on MPC8240, the system can register the
|
||||
I2C_ISR with the EPIC including other
|
||||
desired resources.
|
||||
|
||||
If the host system does not using the EPIC unit
|
||||
on MPC8240, I2C_Timer_Event function can
|
||||
be called for each desired time interval.
|
||||
|
||||
In both cases, the host system is free to provide
|
||||
its own timer event handler and interrupt service
|
||||
routine.
|
||||
|
||||
6. The I2C driver routines contains a set
|
||||
of utilities, Set and Get, for host system
|
||||
to query and modify the desired I2C registers.
|
||||
|
||||
7. It is the host system's responsibility of
|
||||
queueing the I2C I/O request. The host
|
||||
system shall check the I2C_ISR return code
|
||||
for I2C I/O status. If I2C_ISR returns
|
||||
I2CBUFFEMPTY or I2CBUFFFULL, it means
|
||||
I2C unit has completed a I/O request
|
||||
stated by the Application API.
|
||||
|
||||
8. If the host system has more than one master
|
||||
mode I2C unit I/O requests but doesn't want
|
||||
to be intervented by being addressed as slave,
|
||||
the host system can use the master mode
|
||||
Application API with stop_flag set to 0 in
|
||||
conjunction with is_cnt flag set to 1.
|
||||
The first API call sets both stop_flag and
|
||||
is_cnt to 0, indicating a START condition
|
||||
shall be generated but when the end of
|
||||
transaction is reached, do not generate a
|
||||
STOP condition. Once the host system is
|
||||
informed that the transaction has been
|
||||
completed, the next Application API call
|
||||
shall set is_cnt flag to 1, indicating a
|
||||
repeated START condition shall be generated.
|
||||
The last Application API call shall set
|
||||
stop_flag
|
||||
to 1.
|
||||
|
||||
9. The I2C_Timer_Event function containes
|
||||
a user defined function pointer. It
|
||||
serves the purpose of providing the
|
||||
host system a way to use its own event
|
||||
handler instead of the I2C_ISR provided
|
||||
here.
|
||||
284
cpu/mpc824x/drivers/i2c/i2c.c
Normal file
284
cpu/mpc824x/drivers/i2c/i2c.c
Normal file
@@ -0,0 +1,284 @@
|
||||
/*
|
||||
* (C) Copyright 2003
|
||||
* Gleb Natapov <gnatapov@mrv.com>
|
||||
* Some bits are taken from linux driver writen by adrian@humboldt.co.uk
|
||||
*
|
||||
* Hardware I2C driver for MPC107 PCI bridge.
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public 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>
|
||||
|
||||
#undef I2CDBG
|
||||
|
||||
#ifdef CONFIG_HARD_I2C
|
||||
#include <i2c.h>
|
||||
|
||||
#define TIMEOUT (CFG_HZ/4)
|
||||
|
||||
#define I2C_Addr ((unsigned *)(CFG_EUMB_ADDR + 0x3000))
|
||||
|
||||
#define I2CADR &I2C_Addr[0]
|
||||
#define I2CFDR &I2C_Addr[1]
|
||||
#define I2CCCR &I2C_Addr[2]
|
||||
#define I2CCSR &I2C_Addr[3]
|
||||
#define I2CCDR &I2C_Addr[4]
|
||||
|
||||
#define MPC107_CCR_MEN 0x80
|
||||
#define MPC107_CCR_MIEN 0x40
|
||||
#define MPC107_CCR_MSTA 0x20
|
||||
#define MPC107_CCR_MTX 0x10
|
||||
#define MPC107_CCR_TXAK 0x08
|
||||
#define MPC107_CCR_RSTA 0x04
|
||||
|
||||
#define MPC107_CSR_MCF 0x80
|
||||
#define MPC107_CSR_MAAS 0x40
|
||||
#define MPC107_CSR_MBB 0x20
|
||||
#define MPC107_CSR_MAL 0x10
|
||||
#define MPC107_CSR_SRW 0x04
|
||||
#define MPC107_CSR_MIF 0x02
|
||||
#define MPC107_CSR_RXAK 0x01
|
||||
|
||||
#define I2C_READ 1
|
||||
#define I2C_WRITE 0
|
||||
|
||||
/* taken from linux include/asm-ppc/io.h */
|
||||
inline unsigned in_le32 (volatile unsigned *addr)
|
||||
{
|
||||
unsigned ret;
|
||||
|
||||
__asm__ __volatile__ ("lwbrx %0,0,%1;\n"
|
||||
"twi 0,%0,0;\n"
|
||||
"isync":"=r" (ret): "r" (addr), "m" (*addr));
|
||||
return ret;
|
||||
}
|
||||
|
||||
inline void out_le32 (volatile unsigned *addr, int val)
|
||||
{
|
||||
__asm__ __volatile__ ("stwbrx %1,0,%2; eieio":"=m" (*addr):"r" (val),
|
||||
"r" (addr));
|
||||
}
|
||||
|
||||
#define writel(val, addr) out_le32(addr, val)
|
||||
#define readl(addr) in_le32(addr)
|
||||
|
||||
void i2c_init (int speed, int slaveadd)
|
||||
{
|
||||
/* stop I2C controller */
|
||||
writel (0x0, I2CCCR);
|
||||
/* set clock */
|
||||
writel (0x1020, I2CFDR);
|
||||
/* write slave address */
|
||||
writel (slaveadd, I2CADR);
|
||||
/* clear status register */
|
||||
writel (0x0, I2CCSR);
|
||||
/* start I2C controller */
|
||||
writel (MPC107_CCR_MEN, I2CCCR);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static __inline__ int i2c_wait4bus (void)
|
||||
{
|
||||
ulong timeval = get_timer (0);
|
||||
|
||||
while (readl (I2CCSR) & MPC107_CSR_MBB)
|
||||
if (get_timer (timeval) > TIMEOUT)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static __inline__ int i2c_wait (int write)
|
||||
{
|
||||
u32 csr;
|
||||
ulong timeval = get_timer (0);
|
||||
|
||||
do {
|
||||
csr = readl (I2CCSR);
|
||||
|
||||
if (!(csr & MPC107_CSR_MIF))
|
||||
continue;
|
||||
|
||||
writel (0x0, I2CCSR);
|
||||
|
||||
if (csr & MPC107_CSR_MAL) {
|
||||
#ifdef I2CDBG
|
||||
printf ("i2c_wait: MAL\n");
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!(csr & MPC107_CSR_MCF)) {
|
||||
#ifdef I2CDBG
|
||||
printf ("i2c_wait: unfinished\n");
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (write == I2C_WRITE && (csr & MPC107_CSR_RXAK)) {
|
||||
#ifdef I2CDBG
|
||||
printf ("i2c_wait: No RXACK\n");
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
} while (get_timer (timeval) < TIMEOUT);
|
||||
|
||||
#ifdef I2CDBG
|
||||
printf ("i2c_wait: timed out\n");
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
|
||||
static __inline__ int i2c_write_addr (u8 dev, u8 dir, int rsta)
|
||||
{
|
||||
writel (MPC107_CCR_MEN | MPC107_CCR_MSTA | MPC107_CCR_MTX |
|
||||
(rsta ? MPC107_CCR_RSTA : 0), I2CCCR);
|
||||
|
||||
writel ((dev << 1) | dir, I2CCDR);
|
||||
|
||||
if (i2c_wait (I2C_WRITE) < 0)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static __inline__ int __i2c_write (u8 * data, int length)
|
||||
{
|
||||
int i;
|
||||
|
||||
writel (MPC107_CCR_MEN | MPC107_CCR_MSTA | MPC107_CCR_MTX, I2CCCR);
|
||||
|
||||
for (i = 0; i < length; i++) {
|
||||
writel (data[i], I2CCDR);
|
||||
|
||||
if (i2c_wait (I2C_WRITE) < 0)
|
||||
break;
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
static __inline__ int __i2c_read (u8 * data, int length)
|
||||
{
|
||||
int i;
|
||||
|
||||
writel (MPC107_CCR_MEN | MPC107_CCR_MSTA |
|
||||
((length == 1) ? MPC107_CCR_TXAK : 0), I2CCCR);
|
||||
|
||||
/* dummy read */
|
||||
readl (I2CCDR);
|
||||
|
||||
for (i = 0; i < length; i++) {
|
||||
if (i2c_wait (I2C_READ) < 0)
|
||||
break;
|
||||
|
||||
/* Generate ack on last next to last byte */
|
||||
if (i == length - 2)
|
||||
writel (MPC107_CCR_MEN | MPC107_CCR_MSTA |
|
||||
MPC107_CCR_TXAK, I2CCCR);
|
||||
|
||||
/* Generate stop on last byte */
|
||||
if (i == length - 1)
|
||||
writel (MPC107_CCR_MEN | MPC107_CCR_TXAK, I2CCCR);
|
||||
|
||||
data[i] = readl (I2CCDR);
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
int i2c_read (u8 dev, uint addr, int alen, u8 * data, int length)
|
||||
{
|
||||
int i = 0;
|
||||
u8 *a = (u8 *) & addr;
|
||||
|
||||
if (i2c_wait4bus () < 0)
|
||||
goto exit;
|
||||
|
||||
if (i2c_write_addr (dev, I2C_WRITE, 0) == 0)
|
||||
goto exit;
|
||||
|
||||
if (__i2c_write (&a[4 - alen], alen) != alen)
|
||||
goto exit;
|
||||
|
||||
if (i2c_write_addr (dev, I2C_READ, 1) == 0)
|
||||
goto exit;
|
||||
|
||||
i = __i2c_read (data, length);
|
||||
|
||||
exit:
|
||||
writel (MPC107_CCR_MEN, I2CCCR);
|
||||
|
||||
return !(i == length);
|
||||
}
|
||||
|
||||
int i2c_write (u8 dev, uint addr, int alen, u8 * data, int length)
|
||||
{
|
||||
int i = 0;
|
||||
u8 *a = (u8 *) & addr;
|
||||
|
||||
if (i2c_wait4bus () < 0)
|
||||
goto exit;
|
||||
|
||||
if (i2c_write_addr (dev, I2C_WRITE, 0) == 0)
|
||||
goto exit;
|
||||
|
||||
if (__i2c_write (&a[4 - alen], alen) != alen)
|
||||
goto exit;
|
||||
|
||||
i = __i2c_write (data, length);
|
||||
|
||||
exit:
|
||||
writel (MPC107_CCR_MEN, I2CCCR);
|
||||
|
||||
return !(i == length);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
uchar i2c_reg_read (uchar i2c_addr, uchar reg)
|
||||
{
|
||||
char buf[1];
|
||||
|
||||
i2c_read (i2c_addr, reg, 1, buf, 1);
|
||||
|
||||
return (buf[0]);
|
||||
}
|
||||
|
||||
void i2c_reg_write (uchar i2c_addr, uchar reg, uchar val)
|
||||
{
|
||||
i2c_write (i2c_addr, reg, 1, &val, 1);
|
||||
}
|
||||
|
||||
#endif /* CONFIG_HARD_I2C */
|
||||
@@ -1,309 +0,0 @@
|
||||
#ifndef I2C_H
|
||||
#define I2C_H
|
||||
|
||||
/****************************************************
|
||||
*
|
||||
* Copyright Motrola 1999
|
||||
*
|
||||
****************************************************/
|
||||
#define get_eumbbar() CFG_EUMB_ADDR
|
||||
|
||||
#define I2CADR 0x00003000
|
||||
#define I2CFDR 0x00003004
|
||||
#define I2CCR 0x00003008
|
||||
#define I2CSR 0x0000300C
|
||||
#define I2CDR 0x00003010
|
||||
|
||||
typedef enum _i2cstatus
|
||||
{
|
||||
I2CSUCCESS = 0x3000,
|
||||
I2CADDRESS,
|
||||
I2CERROR,
|
||||
I2CBUFFFULL,
|
||||
I2CBUFFEMPTY,
|
||||
I2CXMITERROR,
|
||||
I2CRCVERROR,
|
||||
I2CBUSBUSY,
|
||||
I2CALOSS,
|
||||
I2CNOEVENT,
|
||||
} I2CStatus;
|
||||
|
||||
typedef enum i2c_control
|
||||
{
|
||||
MEN = 0x00000080,
|
||||
MIEN = 0x00000040,
|
||||
MSTA = 0x00000020,
|
||||
MTX = 0x00000010,
|
||||
TXAK = 0x00000008,
|
||||
RSTA = 0x00000004,
|
||||
} I2C_CONTROL;
|
||||
|
||||
typedef enum i2c_status
|
||||
{
|
||||
MCF = 0x00000080,
|
||||
MAAS = 0x00000040,
|
||||
MBB = 0x00000020,
|
||||
MAL = 0x00000010,
|
||||
SRW = 0x00000004,
|
||||
MIF = 0x00000002,
|
||||
RXAK = 0x00000001,
|
||||
} I2C_STATUS;
|
||||
|
||||
typedef struct _i2c_ctrl
|
||||
{
|
||||
unsigned int reserved0 : 24;
|
||||
unsigned int men : 1;
|
||||
unsigned int mien : 1;
|
||||
unsigned int msta : 1;
|
||||
unsigned int mtx : 1;
|
||||
unsigned int txak : 1;
|
||||
unsigned int rsta : 1;
|
||||
unsigned int reserved1 : 2;
|
||||
} I2C_CTRL;
|
||||
|
||||
typedef struct _i2c_stat
|
||||
{
|
||||
unsigned int rsrv0 : 24;
|
||||
unsigned int mcf : 1;
|
||||
unsigned int maas : 1;
|
||||
unsigned int mbb : 1;
|
||||
unsigned int mal : 1;
|
||||
unsigned int rsrv1 : 1;
|
||||
unsigned int srw : 1;
|
||||
unsigned int mif : 1;
|
||||
unsigned int rxak : 1;
|
||||
} I2C_STAT;
|
||||
|
||||
typedef enum _i2c_mode
|
||||
{
|
||||
RCV = 0,
|
||||
XMIT = 1,
|
||||
} I2C_MODE;
|
||||
|
||||
/******************** App. API ********************
|
||||
* The application API is for user level application
|
||||
* to use the funcitonality provided by I2C driver
|
||||
*
|
||||
* Note: Its App.s responsibility to swap the data
|
||||
* byte. In our API, we just transfer whatever
|
||||
* we are given
|
||||
**************************************************/
|
||||
/**
|
||||
* Note:
|
||||
*
|
||||
* In all following functions,
|
||||
* the caller shall pass the configured embedded utility memory
|
||||
* block base, EUMBBAR.
|
||||
**/
|
||||
|
||||
/* 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.
|
||||
*
|
||||
* return I2CSUCCESS if no error.
|
||||
*/
|
||||
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
|
||||
*/
|
||||
|
||||
/* 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.
|
||||
*
|
||||
* return I2CSUCCESS if no error.
|
||||
*/
|
||||
static I2CStatus I2C_get( unsigned int eumbbar,
|
||||
unsigned char sender_addr, /* 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 0 /* the I2C_write and I2C_read functions are not active */
|
||||
/* 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.
|
||||
*
|
||||
* return I2CSUCCESS if no error.
|
||||
*
|
||||
* Note: due to the 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., 1.
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
/* 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.
|
||||
*
|
||||
* return I2CSUCCESS if no error.
|
||||
*/
|
||||
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
|
||||
*/
|
||||
#endif /* of if0 for turning off I2C_read & I2C_write */
|
||||
|
||||
/* 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 ) );
|
||||
|
||||
/********************* Kernel API ************************
|
||||
* Kernel APIs are functions I2C driver provides to the
|
||||
* O.S.
|
||||
*********************************************************/
|
||||
|
||||
/******************* device I/O function ***************/
|
||||
|
||||
/* Generate a START signal in the desired mode.
|
||||
* I2C is the master.
|
||||
*
|
||||
* return I2CSUCCESS if no error.
|
||||
* I2CERROR if i2c unit is not enabled.
|
||||
* I2CBUSBUSY if bus cannot be granted
|
||||
*/
|
||||
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, check MBB
|
||||
*/
|
||||
|
||||
/* Generate a STOP signal to terminate the transaction. */
|
||||
static I2CStatus I2C_Stop( unsigned int eumbbar );
|
||||
|
||||
/* Do a one-byte master transmit.
|
||||
*
|
||||
* return I2CBUFFEMPTY if this is the last byte.
|
||||
* Otherwise return I2CSUCCESS
|
||||
*/
|
||||
static I2CStatus I2C_Master_Xmit( unsigned int eumbbar );
|
||||
|
||||
/* Do a one-byte master receive.
|
||||
*
|
||||
* return I2CBUFFFULL if this is the last byte.
|
||||
* Otherwise return I2CSUCCESS
|
||||
*/
|
||||
static I2CStatus I2C_Master_Rcv( unsigned int eumbbar );
|
||||
|
||||
/* Do a one-byte slave transmit.
|
||||
*
|
||||
* return I2CBUFFEMPTY if this is the last byte.
|
||||
* Otherwise return I2CSUCCESS
|
||||
*
|
||||
*/
|
||||
static I2CStatus I2C_Slave_Xmit( unsigned int eumbbar );
|
||||
|
||||
/* Do a one-byte slave receive.
|
||||
*
|
||||
* return I2CBUFFFULL if this is the last byte.
|
||||
* Otherwise return I2CSUCCESS
|
||||
*/
|
||||
static I2CStatus I2C_Slave_Rcv( unsigned int eumbbar );
|
||||
|
||||
/* Process slave address phase.
|
||||
*
|
||||
* return I2CADDRESS if this is slave receiver's address phase
|
||||
* Otherwise return the result of slave xmit one byte.
|
||||
*/
|
||||
static I2CStatus I2C_Slave_Addr( unsigned int eumbbar );
|
||||
|
||||
/******************* Device Control Fucntion ****************/
|
||||
/* Initialize I2C unit with desired frequency divider,
|
||||
* driver's slave address w/o interrupt enabled.
|
||||
*
|
||||
* This function must be called before I2C unit can
|
||||
* be used.
|
||||
*/
|
||||
static I2CStatus I2C_Init( unsigned int eumbbar,
|
||||
unsigned char fdr, /* frequency divider */
|
||||
unsigned char addr, /* driver's address used for receiving */
|
||||
unsigned int en_int); /* 1 - enable I2C interrupt
|
||||
* 0 - disable I2C interrup
|
||||
*/
|
||||
|
||||
/* I2C interrupt service routine.
|
||||
*
|
||||
* return I2CADDRESS if it is receiver's (either master or slave) address phase.
|
||||
* return the result of xmit or receive one byte
|
||||
*/
|
||||
static I2CStatus I2C_ISR(unsigned int eumbbar );
|
||||
|
||||
/* Set I2C Status, i.e., write to I2CSR */
|
||||
static void I2C_Set_Stat( unsigned int eumbbar, I2C_STAT stat );
|
||||
|
||||
/* Query I2C Status, i.e., read I2CSR */
|
||||
static I2C_STAT I2C_Get_Stat( unsigned int eumbbar );
|
||||
|
||||
/* Change I2C Control bits, i.e., write to I2CCR */
|
||||
static void I2C_Set_Ctrl( unsigned int eumbbar, I2C_CTRL ); /* new control value */
|
||||
|
||||
/* Query I2C Control bits, i.e., read I2CCR */
|
||||
static I2C_CTRL I2C_Get_Ctrl( unsigned int eumbbar );
|
||||
|
||||
/* 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);
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,52 +0,0 @@
|
||||
/**************************************
|
||||
*
|
||||
* copyright @ Motorola, 1999
|
||||
*
|
||||
**************************************/
|
||||
|
||||
#include <config.h>
|
||||
#ifdef CONFIG_HARD_I2C
|
||||
#include <ppc_asm.tmpl>
|
||||
#include <asm/mmu.h>
|
||||
/**********************************************************
|
||||
* function: load_runtime_reg
|
||||
*
|
||||
* input: r3 - value of eumbbar
|
||||
* r4 - register offset in embedded utility space
|
||||
*
|
||||
* output: r3 - register content
|
||||
**********************************************************/
|
||||
.text
|
||||
.align 2
|
||||
.global load_runtime_reg
|
||||
load_runtime_reg:
|
||||
|
||||
/* xor r5,r5,r5
|
||||
* or r5,r5,r3
|
||||
*
|
||||
* lwbrx r3,r4,r5
|
||||
*/
|
||||
lwbrx r3,r4,r3
|
||||
sync
|
||||
|
||||
bclr 20, 0
|
||||
|
||||
/****************************************************************
|
||||
* function: store_runtime_reg
|
||||
*
|
||||
* input: r3 - value of eumbbar
|
||||
* r4 - register offset in embedded utility space
|
||||
* r5 - new value to be stored
|
||||
*
|
||||
****************************************************************/
|
||||
.text
|
||||
.align 2
|
||||
.global store_runtime_reg
|
||||
store_runtime_reg:
|
||||
|
||||
stwbrx r5, r4, r3
|
||||
sync
|
||||
|
||||
bclr 20,0
|
||||
|
||||
#endif /* CONFIG_HARD_I2C */
|
||||
@@ -1,103 +0,0 @@
|
||||
#ifndef I2C_EXPORT_H
|
||||
#define I2C_EXPORT_H
|
||||
|
||||
/****************************************************
|
||||
*
|
||||
* Copyright Motrola 1999
|
||||
*
|
||||
****************************************************/
|
||||
|
||||
/* These are the defined return values for the I2C_do_transaction function.
|
||||
* Any non-zero value indicates failure. Failure modes can be added for
|
||||
* more detailed error reporting.
|
||||
*/
|
||||
typedef enum _i2c_status
|
||||
{
|
||||
I2C_SUCCESS = 0,
|
||||
I2C_ERROR,
|
||||
} I2C_Status;
|
||||
|
||||
/* These are the defined tasks for I2C_do_transaction.
|
||||
* Modes for SLAVE_RCV and SLAVE_XMIT will be added.
|
||||
*/
|
||||
typedef enum _i2c_transaction_mode
|
||||
{
|
||||
I2C_MASTER_RCV = 0,
|
||||
I2C_MASTER_XMIT = 1,
|
||||
} I2C_TRANSACTION_MODE;
|
||||
|
||||
typedef enum _i2c_interrupt_mode
|
||||
{
|
||||
I2C_INT_DISABLE = 0,
|
||||
I2C_INT_ENABLE = 1,
|
||||
} I2C_INTERRUPT_MODE;
|
||||
|
||||
typedef enum _i2c_stop
|
||||
{
|
||||
I2C_NO_STOP = 0,
|
||||
I2C_STOP = 1,
|
||||
} I2C_STOP_MODE;
|
||||
|
||||
typedef enum _i2c_restart
|
||||
{
|
||||
I2C_NO_RESTART = 0,
|
||||
I2C_RESTART = 1,
|
||||
} I2C_RESTART_MODE;
|
||||
|
||||
/******************** App. API ********************
|
||||
* The application API is for user level application
|
||||
* to use the functionality provided by I2C driver.
|
||||
* This is a "generic" I2C interface, it should contain
|
||||
* nothing specific to the Kahlua implementation.
|
||||
* Only the generic functions are exported by the library.
|
||||
*
|
||||
* Note: Its App.s responsibility to swap the data
|
||||
* byte. In our API, we just transfer whatever
|
||||
* we are given
|
||||
**************************************************/
|
||||
|
||||
|
||||
/* 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.
|
||||
*/
|
||||
extern I2C_Status I2C_Initialize(
|
||||
unsigned char addr, /* driver's I2C slave address */
|
||||
I2C_INTERRUPT_MODE en_int, /* 1 - enable I2C interrupt
|
||||
* 0 - disable I2C interrupt
|
||||
*/
|
||||
int (*app_print_function)(char *,...)); /* pointer to optional "printf"
|
||||
* provided by application
|
||||
*/
|
||||
|
||||
/* 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
|
||||
* 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
|
||||
*/
|
||||
extern 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);
|
||||
#endif
|
||||
@@ -526,11 +526,26 @@ relocate_code:
|
||||
stwu r0,-4(r7)
|
||||
bdnz 3b
|
||||
|
||||
4:
|
||||
#if !defined(CONFIG_BMW)
|
||||
/* Unlock the data cache and invalidate locked area */
|
||||
xor r0, r0, r0
|
||||
mtspr 1011, r0
|
||||
lis r4, CFG_INIT_RAM_ADDR@h
|
||||
ori r4, r4, CFG_INIT_RAM_ADDR@l
|
||||
li r0, 128
|
||||
mtctr r0
|
||||
41:
|
||||
dcbi r0, r4
|
||||
addi r4, r4, 32
|
||||
bdnz 41b
|
||||
#endif
|
||||
|
||||
/*
|
||||
* 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
|
||||
cmpwi r6,0
|
||||
add r5,r3,r5
|
||||
beq 7f /* Always flush prefetch queue in any case */
|
||||
subi r0,r6,1
|
||||
|
||||
@@ -98,6 +98,7 @@ static int check_CPU (long clock, uint pvr, uint immr)
|
||||
case 0x00310065: mid = "SR"; suf = "C1"; m = 1; break;
|
||||
case 0x05010000: suf = "D3"; m = 1; break;
|
||||
case 0x05020000: suf = "D4"; m = 1; break;
|
||||
case 0x08000003: suf = ""; m = 1; break;
|
||||
/* this value is not documented anywhere */
|
||||
case 0x40000000: pre = 'P'; suf = "D"; m = 1; break;
|
||||
#endif
|
||||
|
||||
@@ -132,7 +132,8 @@ void cpu_init_f (volatile immap_t * immr)
|
||||
* I owe him a free beer. - wd]
|
||||
*/
|
||||
|
||||
#if defined(CONFIG_GTH) || \
|
||||
#if defined(CONFIG_ADDERII) || \
|
||||
defined(CONFIG_GTH) || \
|
||||
defined(CONFIG_HERMES) || \
|
||||
defined(CONFIG_ICU862) || \
|
||||
defined(CONFIG_IP860) || \
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user