Compare commits

...

14 Commits

Author SHA1 Message Date
wdenk
9a0e21a3a8 Had to move the RTC area for ATC board to upper addresses
(0xf5000000, to be specific). The reason is that the RTC first gets
accessed before MMU is initialized and, consequently, it needs to be
placed at physical addresses which are later mapped to the same
virtual addresses (like 0xf5000000 physical is mapped to 0xf5000000
virtual).
2003-06-22 10:30:54 +00:00
wdenk
592c5cabe7 Patch by Murray Jensen, 20 Jun 2003:
- hymod update
- cleanup (especially for gcc-3.x compilers)
2003-06-21 00:17:24 +00:00
wdenk
72755c7137 Patch by Tom Guilliams, 20 Jun 2003:
added CONFIG_750FX support for IBM 750FX processors
2003-06-20 23:10:58 +00:00
wdenk
0332990b85 * Patch by Devin Crumb, 02 Apr 2003:
Fix clock divider rounding problem in drivers/serial.c

* Patch by Ken Chou, 19 June 2003:
  Added support for A3000 SBC board (Artis Microsystems Inc.)
2003-06-20 22:36:30 +00:00
wdenk
0b97ab144f * Patch by Richard Woodruff, 19 June 03:
- Fixed smc91c111 driver to sync with the u-boot environment (driver/smc91c111.c).
- Added eth_init error return check in NetLoop (net/net.c).
2003-06-19 23:58:30 +00:00
wdenk
6dd652fa4d Patches by Murray Jensen, 17 Jun 2003:
- Hymod board database mods: add "who" field and new xilinx chip types
- provide new "init_cmd_timeout()" function so code external to
  "common/main.c" can use the "reset_cmd_timeout()" function before
  entering the main loop
- add DTT support for adm1021 (new file dtt/adm1021.c; config
  slightly different. see include/configs/hymod.h for an example
  (requires CONFIG_DTT_ADM1021, CONFIG_DTT_SENSORS, and
  CFG_DTT_ADM1021 defined)
- add new "eeprom_probe()" function which has similar args and
  behaves in a similar way to "eeprom_read()" etc.
- add 8260 FCC ethernet loopback code (new "eth_loopback_test()"
  function which is enabled by defining CONFIG_ETHER_LOOPBACK_TEST)
- gdbtools copyright update
- ensure that set_msr() executes the "sync" and "isync" instructions
  after the "mtmsr" instruction in cpu/mpc8260/interrupts.c
- 8260 I/O ports fix: Open Drain should be set last when configuring
- add SIU IRQ defines for 8260
- allow LDSCRIPT override and OBJCFLAGS initialization: change to
  config.mk to allow board configurations to override the GNU
  linker script, selected via the LDSCRIPT, make variable, and to
  give an initial value to the OBJCFLAGS make variable
- 8260 i2c enhancement:
  o correctly extends the timeout depending on the size of all
    queued messages for both transmit and receive
  o will not continue with receive if transmit times out
  o ensures that the error callback is done for all queued tx
    and rx messages
  o correctly detects both tx and rx timeouts, only delivers one to
    the callback, and does not overwrite an earlier error
  o logic in i2c_probe now correct
- add "vprintf()" function so that "panic()" function can be
  technically correct
- many Hymod board changes
2003-06-19 23:40:20 +00:00
wdenk
52f52c1494 Patches by Robert Schwebel, 14 Jun 2003:
- add support for Logotronic DL datalogger board
- cleanup serial line after kermit binary download
- add debugX macro (debug level support)
- update mach-types.h to latest arm.linux.org.uk master list.
2003-06-19 23:04:19 +00:00
wdenk
48b42616e9 * Patches by David Mller, 12 Jun 2003:
- rewrite of the S3C24X0 register definitions stuff
  - "driver" for the built-in S3C24X0 RTC

* Patches by Yuli Barcohen, 12 Jun 2003:
  - Add MII support and Ethernet PHY initialization for MPC8260ADS board
  - Fix incorrect SIUMCR initialisation caused by wrong Hard Reset
    configuration word supplied by FPGA on some MPC8260ADS boards

* Patch by Pantelis Antoniou, 10 Jun 2003:
  Unify status LED interface
2003-06-19 23:01:32 +00:00
wdenk
15ef8a5d17 Add support for DS12887 RTC; add RTC support for ATC board 2003-06-18 20:22:24 +00:00
wdenk
2abbe07547 * Patch by Nicolas Lacressonniere, 11 Jun 2003:
Modifications for Atmel AT91RM9200DK ARM920T based development kit
  - Add Atmel DataFlash support for reading and writing.
  - Add possibility to boot a Linux from DataFlash with BOOTM command.
  - Add Flash detection on Atmel AT91RM9200DK
    (between Atmel AT49BV1614 and AT49BV1614A flashes)
  - Replace old Ethernet PHY layer functions
  - Change link address

* Patch by Frank Smith, 9 Jun 2003:
  use CRIT_EXCEPTION for machine check on 4xx

* Patch by Detlev Zundel, 13 Jun 2003:
  added implementation of the "carinfo" command in cmd_immap.c
2003-06-16 23:50:08 +00:00
wdenk
71f9511803 * Fix CONFIG_NET_MULTI support in include/net.h
* Patches by Kyle Harris, 13 Mar 2003:
  - Add FAT partition support
  - Add command support for FAT
  - Add command support for MMC
  ----
  - Add Intel PXA support for video
  - Add Intel PXA support for MMC
  ----
  - Enable MMC and FAT for lubbock board
  - Other misc changes for lubbock board
2003-06-15 22:40:42 +00:00
wdenk
487778b781 Patch by Robert Schwebel, April 02, 2003:
fix for SMSC91111 driver
2003-06-06 11:20:01 +00:00
stroese
8b601449e8 - Update new fpga file. 2003-06-06 09:44:40 +00:00
stroese
e58dc13283 - Fix compile bug (PPC4xx). 2003-06-06 09:43:42 +00:00
173 changed files with 17706 additions and 3951 deletions

106
CHANGELOG
View File

@@ -2,6 +2,110 @@
Changes since U-Boot 0.3.1:
======================================================================
* Patch by Murray Jensen, 20 Jun 2003:
- hymod update
- cleanup (especially for gcc-3.x compilers)
* Patch by Tom Guilliams, 20 Jun 2003:
added CONFIG_750FX support for IBM 750FX processors
* Patch by Devin Crumb, 02 Apr 2003:
Fix clock divider rounding problem in drivers/serial.c
* Patch by Richard Woodruff, 19 June 03:
- Fixed smc91c111 driver to sync with the u-boot environment
(driver/smc91c111.c).
- Added eth_init error return check in NetLoop (net/net.c).
* Patch by Ken Chou, 19 June 2003:
Added support for A3000 SBC board (Artis Microsystems Inc.)
* Patches by Murray Jensen, 17 Jun 2003:
- Hymod board database mods: add "who" field and new xilinx chip types
- provide new "init_cmd_timeout()" function so code external to
"common/main.c" can use the "reset_cmd_timeout()" function before
entering the main loop
- add DTT support for adm1021 (new file dtt/adm1021.c; config
slightly different. see include/configs/hymod.h for an example
(requires CONFIG_DTT_ADM1021, CONFIG_DTT_SENSORS, and
CFG_DTT_ADM1021 defined)
- add new "eeprom_probe()" function which has similar args and
behaves in a similar way to "eeprom_read()" etc.
- add 8260 FCC ethernet loopback code (new "eth_loopback_test()"
function which is enabled by defining CONFIG_ETHER_LOOPBACK_TEST)
- gdbtools copyright update
- ensure that set_msr() executes the "sync" and "isync" instructions
after the "mtmsr" instruction in cpu/mpc8260/interrupts.c
- 8260 I/O ports fix: Open Drain should be set last when configuring
- add SIU IRQ defines for 8260
- allow LDSCRIPT override and OBJCFLAGS initialization: change to
config.mk to allow board configurations to override the GNU
linker script, selected via the LDSCRIPT, make variable, and to
give an initial value to the OBJCFLAGS make variable
- 8260 i2c enhancement:
o correctly extends the timeout depending on the size of all
queued messages for both transmit and receive
o will not continue with receive if transmit times out
o ensures that the error callback is done for all queued tx
and rx messages
o correctly detects both tx and rx timeouts, only delivers one to
the callback, and does not overwrite an earlier error
o logic in i2c_probe now correct
- add "vprintf()" function so that "panic()" function can be
technically correct
- many Hymod board changes
* Patches by Robert Schwebel, 14 Jun 2003:
- add support for Logotronic DL datalogger board
- cleanup serial line after kermit binary download
- add debugX macro (debug level support)
- update mach-types.h to latest arm.linux.org.uk master list.
* Patches by David Müller, 12 Jun 2003:
- rewrite of the S3C24X0 register definitions stuff
- "driver" for the built-in S3C24X0 RTC
* Patches by Yuli Barcohen, 12 Jun 2003:
- Add MII support and Ethernet PHY initialization for MPC8260ADS board
- Fix incorrect SIUMCR initialisation caused by wrong Hard Reset
configuration word supplied by FPGA on some MPC8260ADS boards
* Patch by Pantelis Antoniou, 10 Jun 2003:
Unify status LED interface
* Add support for DS12887 RTC; add RTC support for ATC board
* Patch by Nicolas Lacressonniere, 11 Jun 2003:
Modifications for Atmel AT91RM9200DK ARM920T based development kit
- Add Atmel DataFlash support for reading and writing.
- Add possibility to boot a Linux from DataFlash with BOOTM command.
- Add Flash detection on Atmel AT91RM9200DK
(between Atmel AT49BV1614 and AT49BV1614A flashes)
- Replace old Ethernet PHY layer functions
- Change link address
* Patch by Frank Smith, 9 Jun 2003:
use CRIT_EXCEPTION for machine check on 4xx
* Patch by Detlev Zundel, 13 Jun 2003:
added implementation of the "carinfo" command in cmd_immap.c
* Fix CONFIG_NET_MULTI support in include/net.h
* Patches by Kyle Harris, 13 Mar 2003:
- Add FAT partition support
- Add command support for FAT
- Add command support for MMC
----
- Add Intel PXA support for video
- Add Intel PXA support for MMC
----
- Enable MMC and FAT for lubbock board
- Other misc changes for lubbock board
* Patch by Robert Schwebel, April 02, 2003:
fix for SMSC91111 driver
* Patch by Vladimir Gurevich, 04 Jun 2003:
make ppc405 ethernet driver compatible with CONFIG_NET_MULTI option
@@ -388,7 +492,7 @@ Changes for U-Boot 0.3.0:
* TRAB fixes / extensions:
- Restore VFD brightness as saved in environment
- add support for FGujitsu flashes
- add support for Fujitsu flashes
- make sure both buzzers are turned off (drive low level)
* Patches by Robert Schwebel, 06 Mar 2003:

View File

@@ -66,6 +66,10 @@ N: Jonathan De Bruyne
E: jonathan.debruyne@siemens.atea.be
D: Port to Siemens IAD210 board
N: Ken Chou
E: kchou@ieee.org
D: Support for A3000 SBC board
N: Conn Clark
E: clark@esteem.com
D: ESTEEM192E support

View File

@@ -58,9 +58,9 @@ LIST_4xx=" \
#########################################################################
LIST_824x=" \
BMW CPC45 CU824 MOUSSE \
MUSENKI OXC PN62 Sandpoint8240 \
Sandpoint8245 utx8245 \
A3000 BMW CPC45 CU824 \
MOUSSE MUSENKI OXC PN62 \
Sandpoint8240 Sandpoint8245 utx8245 \
"
#########################################################################

View File

@@ -106,7 +106,7 @@ endif
LIBS = board/$(BOARDDIR)/lib$(BOARD).a
LIBS += cpu/$(CPU)/lib$(CPU).a
LIBS += lib_$(ARCH)/lib$(ARCH).a
LIBS += fs/jffs2/libjffs2.a fs/fdos/libfdos.a
LIBS += fs/jffs2/libjffs2.a fs/fdos/libfdos.a fs/fat/libfat.a
LIBS += net/libnet.a
LIBS += disk/libdisk.a
LIBS += rtc/librtc.a
@@ -377,7 +377,7 @@ TQM860L_80MHz_config \
TQM862L_config \
TQM862L_66MHz_config \
TQM862L_80MHz_config \
TQM862L_100MHz_config: unconfig
TQM862M_100MHz_config: unconfig
@ >include/config.h
@[ -z "$(findstring _66MHz,$@)" ] || \
{ echo "#define CONFIG_66MHz" >>include/config.h ; \
@@ -490,6 +490,9 @@ WALNUT405_config:unconfig
#########################################################################
xtract_82xx = $(subst _ROMBOOT,,$(subst _L2,,$(subst _266MHz,,$(subst _300MHz,,$(subst _config,,$1)))))
A3000_config: unconfig
@./mkconfig $(@:_config=) ppc mpc824x a3000
BMW_config: unconfig
@./mkconfig $(@:_config=) ppc mpc824x bmw
@@ -737,6 +740,9 @@ innokom_config : unconfig
lubbock_config : unconfig
@./mkconfig $(@:_config=) arm pxa lubbock
logodl_config : unconfig
@./mkconfig $(@:_config=) arm pxa logodl
wepep250_config : unconfig
@./mkconfig $(@:_config=) arm pxa wepep250

37
README
View File

@@ -151,6 +151,7 @@ Directory Hierarchy:
- board/RPXClassic
Files specific to RPXClassic boards
- board/RPXlite Files specific to RPXlite boards
- board/at91rm9200dk Files specific to AT91RM9200DK boards
- board/c2mon Files specific to c2mon boards
- board/cmi Files specific to cmi boards
- board/cogent Files specific to Cogent boards
@@ -300,6 +301,7 @@ The following options need to be configured:
or CONFIG_405GP
or CONFIG_440
or CONFIG_MPC74xx
or CONFIG_750FX
ARM based CPUs:
---------------
@@ -352,7 +354,7 @@ The following options need to be configured:
CONFIG_HHP_CRADLE, CONFIG_DNP1110, CONFIG_EP7312,
CONFIG_IMPA7, CONFIG_LART, CONFIG_LUBBOCK,
CONFIG_SHANNON, CONFIG_SMDK2400, CONFIG_SMDK2410,
CONFIG_TRAB
CONFIG_TRAB, CONFIG_AT91RM9200DK
- CPU Module Type: (if CONFIG_COGENT is defined)
@@ -565,6 +567,7 @@ The following options need to be configured:
CFG_CMD_ELF bootelf, bootvx
CFG_CMD_ENV saveenv
CFG_CMD_FDC * Floppy Disk Support
CFG_CMD_FAT FAT partition support
CFG_CMD_FDOS * Dos diskette Support
CFG_CMD_FLASH flinfo, erase, protect
CFG_CMD_FPGA FPGA device initialization support
@@ -578,6 +581,7 @@ The following options need to be configured:
CFG_CMD_LOADS loads
CFG_CMD_MEMORY md, mm, nm, mw, cp, cmp, crc, base,
loop, mtest
CFG_CMD_MMC MMC memory mapped support
CFG_CMD_MII MII utility commands
CFG_CMD_NET bootp, tftpboot, rarpboot
CFG_CMD_PCI * pciinfo
@@ -730,6 +734,14 @@ The following options need to be configured:
Supported are USB Keyboards and USB Floppy drives
(TEAC FD-05PUB).
- MMC Support:
The MMC controller on the Intel PXA is supported. To
enable this define CONFIG_MMC. The MMC can be
accessed from the boot prompt by mapping the device
to physical memory similar to flash. Command line is
enabled with CFG_CMD_MMC. The MMC driver also works with
the FAT fs. This is enabled with CFG_CMD_FAT.
- Keyboard Support:
CONFIG_ISA_KEYBOARD
@@ -1238,6 +1250,13 @@ The following options need to be configured:
the environment like the autoscript function or the
boot command first.
- DataFlash Support
CONFIG_HAS_DATAFLASH
Defining this option enables DataFlash features and
allows to read/write in Dataflash via the standard
commands cp, md...
- Show boot progress
CONFIG_SHOW_BOOT_PROGRESS
@@ -1791,6 +1810,7 @@ configurations; the following names are supported:
GENIETV_config TQM823L_config PIP405_config
GEN860T_config EBONY_config FPS860L_config
ELPT860_config cmi_mpc5xx_config NETVIA_config
at91rm9200dk_config
Note: for some board special configuration names may exist; check if
additional information is available from the board vendor; for
@@ -2632,6 +2652,14 @@ Unix, I recommend to use C-Kermit for general purpose use (and
especially for kermit binary protocol download ("loadb" command), and
use "cu" for S-Record download ("loads" command).
Nevertheless, if you absolutely want to use it try adding this
configuration to your "File transfer protocols" section:
Name Program Name U/D FullScr IO-Red. Multi
X kermit /usr/bin/kermit -i -l %l -s Y U Y N N
Y kermit /usr/bin/kermit -i -l %l -r N D Y N N
NetBSD Notes:
=============
@@ -2983,6 +3011,13 @@ it:
We accept patches as plain text, MIME attachments or as uuencoded
gzipped text.
* If one logical set of modifications affects or creates several
files, all these changes shall be submitted in a SINGLE patch file.
* Changesets that contain different, unrelated modifications shall be
submitted as SEPARATE patches, one patch per changeset.
Notes:
* Before sending the patch, run the MAKEALL script on your patched

40
board/a3000/Makefile Normal file
View File

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

18
board/a3000/README Normal file
View File

@@ -0,0 +1,18 @@
U-Boot for Artis SBC-A3000
---------------------------
Artis SBC-A3000 has one flash socket that the user uses Intel 28F128J3A (16MB)
or 28F064J3A (8MB) chips.
In board's notation, bank 0 is the one at the address of 0xFF000000.
bank 1 is the one at the address of 0xFF800000
On power-up the processor jumps to the address of 0xFFF00100, the last
megabyte of the bank 0 of flash.
Thus, U-Boot is configured to reside in flash starting at the address of
0xFFF00000. The environment space is located in flash separately from
U-Boot, at the address of 0xFFFE0000.
There is a National ns83815 10/100M ethernet controller on-board.

144
board/a3000/a3000.c Normal file
View File

@@ -0,0 +1,144 @@
/*
* (C) Copyright 2001
* Rob Taylor, Flying Pig Systems. robt@flyingpig.com.
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#include <common.h>
#include <mpc824x.h>
#include <pci.h>
int checkboard (void)
{
ulong busfreq = get_bus_freq(0);
char buf[32];
printf("Board: A3000 Local Bus at %s MHz\n", strmhz(buf, busfreq));
return 0;
}
long int initdram (int board_type)
{
int i, cnt;
volatile uchar * base= CFG_SDRAM_BASE;
volatile ulong * addr;
ulong save[32];
ulong val, ret = 0;
for (i=0, cnt=(CFG_MAX_RAM_SIZE / sizeof(long)) >> 1; cnt > 0; cnt >>= 1) {
addr = (volatile ulong *)base + cnt;
save[i++] = *addr;
*addr = ~cnt;
}
addr = (volatile ulong *)base;
save[i] = *addr;
*addr = 0;
if (*addr != 0) {
*addr = save[i];
goto Done;
}
for (cnt = 1; cnt <= CFG_MAX_RAM_SIZE / sizeof(long); cnt <<= 1) {
addr = (volatile ulong *)base + cnt;
val = *addr;
*addr = save[--i];
if (val != ~cnt) {
ulong new_bank0_end = cnt * sizeof(long) - 1;
ulong mear1 = mpc824x_mpc107_getreg(MEAR1);
ulong emear1 = mpc824x_mpc107_getreg(EMEAR1);
mear1 = (mear1 & 0xFFFFFF00) |
((new_bank0_end & MICR_ADDR_MASK) >> MICR_ADDR_SHIFT);
emear1 = (emear1 & 0xFFFFFF00) |
((new_bank0_end & MICR_ADDR_MASK) >> MICR_EADDR_SHIFT);
mpc824x_mpc107_setreg(MEAR1, mear1);
mpc824x_mpc107_setreg(EMEAR1, emear1);
ret = cnt * sizeof(long);
goto Done;
}
}
ret = CFG_MAX_RAM_SIZE;
Done:
return ret;
}
/*
* Initialize PCI Devices
*/
#if 1
#ifndef CONFIG_PCI_PNP
static struct pci_config_table pci_a3000_config_table[] = {
{ PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
0x0, 0x0, 0x0, /* unknown eth0 divice */
pci_cfgfunc_config_device, { PCI_ENET0_IOADDR,
PCI_ENET0_MEMADDR,
PCI_COMMAND_IO |
PCI_COMMAND_MEMORY |
PCI_COMMAND_MASTER }},
{ PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
0x0, 0x0, 0x0, /* unknown eth1 device */
pci_cfgfunc_config_device, { PCI_ENET1_IOADDR,
PCI_ENET1_MEMADDR,
PCI_COMMAND_IO |
PCI_COMMAND_MEMORY |
PCI_COMMAND_MASTER }},
{ PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
0x0, 0x0, 0x0, /* unknown eth1 device */
pci_cfgfunc_config_device, { PCI_ENET2_IOADDR,
PCI_ENET2_MEMADDR,
PCI_COMMAND_IO |
PCI_COMMAND_MEMORY |
PCI_COMMAND_MASTER }},
{ }
};
#endif
#else
#ifndef CONFIG_PCI_PNP
static struct pci_config_table pci_a3000_config_table[] = {
{ PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, 0x0f, PCI_ANY_ID,
pci_cfgfunc_config_device, { PCI_ENET0_IOADDR,
PCI_ENET0_MEMADDR,
PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER }},
{ PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, 0x10, PCI_ANY_ID,
pci_cfgfunc_config_device, { PCI_ENET1_IOADDR,
PCI_ENET1_MEMADDR,
PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER }},
{ }
};
#endif
#endif
struct pci_controller hose = {
#ifndef CONFIG_PCI_PNP
config_table: pci_a3000_config_table,
#endif
};
void pci_init_board(void)
{
pci_mpc824x_init(&hose);
}

30
board/a3000/config.mk Normal file
View File

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

454
board/a3000/flash.c Normal file
View File

@@ -0,0 +1,454 @@
/*
* (C) Copyright 2001
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#include <common.h>
#include <mpc824x.h>
#if defined(CFG_ENV_IS_IN_FLASH)
# ifndef CFG_ENV_ADDR
# define CFG_ENV_ADDR (CFG_FLASH_BASE + CFG_ENV_OFFSET)
# endif
# ifndef CFG_ENV_SIZE
# define CFG_ENV_SIZE CFG_ENV_SECT_SIZE
# endif
# ifndef CFG_ENV_SECT_SIZE
# define CFG_ENV_SECT_SIZE CFG_ENV_SIZE
# endif
#endif
/*---------------------------------------------------------------------*/
#define DEBUG_FLASH
#ifdef DEBUG_FLASH
#define DEBUGF(fmt,args...) printf(fmt ,##args)
#else
#define DEBUGF(fmt,args...)
#endif
/*---------------------------------------------------------------------*/
flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */
/*-----------------------------------------------------------------------
* Functions
*/
static ulong flash_get_size (vu_char *addr, flash_info_t *info);
static int write_data (flash_info_t *info, uchar *dest, uchar data);
static void flash_get_offsets (ulong base, flash_info_t *info);
#define BS(b) (b)
#define BYTEME(x) ((x) & 0xFF)
/*-----------------------------------------------------------------------
*/
unsigned long flash_init (void)
{
unsigned long flash_banks[CFG_MAX_FLASH_BANKS] = CFG_FLASH_BANKS;
unsigned long size, size_b[CFG_MAX_FLASH_BANKS];
int i;
/* Init: no FLASHes known */
for (i=0; i<CFG_MAX_FLASH_BANKS; ++i)
{
flash_info[i].flash_id = FLASH_UNKNOWN;
DEBUGF("Get flash bank %d @ 0x%08lx\n", i, flash_banks[i]);
/*
size_b[i] = flash_get_size((vu_char *)flash_banks[i], &flash_info[i]);
*/
size_b[i] = flash_get_size((vu_char *) 0xff800000 , &flash_info[i]);
if (flash_info[i].flash_id == FLASH_UNKNOWN)
{
printf ("## Unknown FLASH on Bank %d: "
"ID 0x%lx, Size = 0x%08lx = %ld MB\n",
i, flash_info[i].flash_id,
size_b[i], size_b[i]<<20);
}
else
{
DEBUGF("## Flash bank %d at 0x%08lx sizes: 0x%08lx \n",
i, flash_banks[i], size_b[i]);
flash_get_offsets (flash_banks[i], &flash_info[i]);
flash_info[i].size = size_b[i];
}
}
#if CFG_MONITOR_BASE >= CFG_FLASH_BASE
DEBUGF("protect monitor %x @ %x\n", CFG_MONITOR_BASE, CFG_MONITOR_LEN);
/* monitor protection ON by default */
flash_protect(FLAG_PROTECT_SET,
CFG_MONITOR_BASE,
CFG_MONITOR_BASE+CFG_MONITOR_LEN-1,
&flash_info[0]);
#endif
#ifdef CFG_ENV_IS_IN_FLASH
/* ENV protection ON by default */
DEBUGF("protect environtment %x @ %x\n", CFG_ENV_ADDR, CFG_ENV_SECT_SIZE);
flash_protect(FLAG_PROTECT_SET,
CFG_ENV_ADDR,
CFG_ENV_ADDR+CFG_ENV_SECT_SIZE-1,
&flash_info[0]);
#endif
size = 0;
DEBUGF("## Final Flash bank sizes: ");
for (i=0; i<CFG_MAX_FLASH_BANKS; ++i)
{
DEBUGF("%08lx ", size_b[i]);
size += size_b[i];
}
DEBUGF("\n");
return (size);
}
/*-----------------------------------------------------------------------
*/
static void flash_get_offsets (ulong base, flash_info_t *info)
{
int i;
if (info->flash_id == FLASH_UNKNOWN) {
return;
}
switch (info->flash_id & FLASH_VENDMASK) {
case FLASH_MAN_INTEL:
for (i = 0; i < info->sector_count; i++) {
info->start[i] = base;
base += 0x00020000; /* 128k per bank */
}
return;
default:
printf ("Don't know sector ofsets for flash type 0x%lx\n", info->flash_id);
return;
}
}
/*-----------------------------------------------------------------------
*/
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_SST: printf ("SST "); break;
case FLASH_MAN_STM: printf ("STM "); break;
case FLASH_MAN_INTEL: printf ("Intel "); break;
case FLASH_MAN_MT: printf ("MT "); break;
default: printf ("Unknown Vendor "); break;
}
switch (info->flash_id & FLASH_TYPEMASK) {
case FLASH_28F320J3A:
printf ("28F320J3A (32Mbit = 128K x 32)\n");
break;
case FLASH_28F640J3A:
printf ("28F640J3A (64Mbit = 128K x 64)\n");
break;
case FLASH_28F128J3A:
printf ("28F128J3A (128Mbit = 128K x 128)\n");
break;
default:
printf ("Unknown Chip Type\n");
break;
}
#if 1
if (info->size >= (1 << 20)) {
i = 20;
} else {
i = 10;
}
printf (" Size: %ld %cB in %d Sectors\n",
info->size >> i,
(i == 20) ? 'M' : 'k',
info->sector_count);
printf (" Sector Start Addresses:");
for (i=0; i<info->sector_count; ++i) {
if ((i % 5) == 0)
printf ("\n ");
printf (" %08lX%s",
info->start[i],
info->protect[i] ? " (RO)" : " "
);
}
printf ("\n");
#endif
return;
}
/*-----------------------------------------------------------------------
*/
/*-----------------------------------------------------------------------
*/
/*
* The following code cannot be run from FLASH!
*/
static ulong flash_get_size (vu_char *addr, flash_info_t *info)
{
vu_char manuf, device;
addr[0] = BS(0x90);
manuf = BS(addr[0]);
DEBUGF("Manuf. ID @ 0x%08lx: 0x%08x\n", (ulong)addr, manuf);
switch (manuf) {
case BYTEME(AMD_MANUFACT):
info->flash_id = FLASH_MAN_AMD;
break;
case BYTEME(FUJ_MANUFACT):
info->flash_id = FLASH_MAN_FUJ;
break;
case BYTEME(SST_MANUFACT):
info->flash_id = FLASH_MAN_SST;
break;
case BYTEME(STM_MANUFACT):
info->flash_id = FLASH_MAN_STM;
break;
case BYTEME(INTEL_MANUFACT):
info->flash_id = FLASH_MAN_INTEL;
break;
default:
info->flash_id = FLASH_UNKNOWN;
info->sector_count = 0;
info->size = 0;
addr[0] = BS(0xFF); /* restore read mode, (yes, BS is a NOP) */
return 0; /* no or unknown flash */
}
device = BS(addr[2]); /* device ID */
DEBUGF("Device ID @ 0x%08lx: 0x%08x\n", (ulong)(&addr[1]), device);
switch (device) {
case BYTEME(INTEL_ID_28F320J3A):
info->flash_id += FLASH_28F320J3A;
info->sector_count = 32;
info->size = 0x00400000;
break; /* => 4 MB */
case BYTEME(INTEL_ID_28F640J3A):
info->flash_id += FLASH_28F640J3A;
info->sector_count = 64;
info->size = 0x00800000;
break; /* => 8 MB */
case BYTEME(INTEL_ID_28F128J3A):
info->flash_id += FLASH_28F128J3A;
info->sector_count = 128;
info->size = 0x01000000;
break; /* => 16 MB */
default:
info->flash_id = FLASH_UNKNOWN;
addr[0] = BS(0xFF); /* restore read mode (yes, a NOP) */
return 0; /* => no or unknown flash */
}
if (info->sector_count > CFG_MAX_FLASH_SECT) {
printf ("** ERROR: sector count %d > max (%d) **\n",
info->sector_count, CFG_MAX_FLASH_SECT);
info->sector_count = CFG_MAX_FLASH_SECT;
}
addr[0] = BS(0xFF); /* restore read mode */
return (info->size);
}
/*-----------------------------------------------------------------------
*/
int flash_erase (flash_info_t *info, int s_first, int s_last)
{
int flag, prot, sect;
ulong start, now, last;
if ((s_first < 0) || (s_first > s_last)) {
if (info->flash_id == FLASH_UNKNOWN) {
printf ("- missing\n");
} else {
printf ("- no sectors to erase\n");
}
return 1;
}
if ((info->flash_id & FLASH_VENDMASK) != FLASH_MAN_INTEL) {
printf ("Can erase only Intel flash types - aborted\n");
return 1;
}
prot = 0;
for (sect=s_first; sect<=s_last; ++sect) {
if (info->protect[sect]) {
prot++;
}
}
if (prot) {
printf ("- Warning: %d protected sectors will not be erased!\n", prot);
} else {
printf ("\n");
}
start = get_timer (0);
last = start;
/* Start erase on unprotected sectors */
for (sect = s_first; sect<=s_last; sect++) {
if (info->protect[sect] == 0) { /* not protected */
vu_char *addr = (vu_char *)(info->start[sect]);
unsigned long status;
/* Disable interrupts which might cause a timeout here */
flag = disable_interrupts();
*addr = BS(0x50); /* clear status register */
*addr = BS(0x20); /* erase setup */
*addr = BS(0xD0); /* erase confirm */
/* re-enable interrupts if necessary */
if (flag) {
enable_interrupts();
}
/* wait at least 80us - let's wait 1 ms */
udelay (1000);
while (((status = BS(*addr)) & BYTEME(0x00800080)) != BYTEME(0x00800080)) {
if ((now=get_timer(start)) > CFG_FLASH_ERASE_TOUT) {
printf ("Timeout\n");
*addr = BS(0xB0); /* suspend erase */
*addr = BS(0xFF); /* reset to read mode */
return 1;
}
/* show that we're waiting */
if ((now - last) > 1000) { /* every second */
putc ('.');
last = now;
}
}
*addr = BS(0xFF); /* reset to read mode */
}
}
printf (" done\n");
return 0;
}
/*-----------------------------------------------------------------------
* Copy memory to flash, returns:
* 0 - OK
* 1 - write timeout
* 2 - Flash not erased
* 4 - Flash not identified
*/
#define FLASH_WIDTH 1 /* flash bus width in bytes */
int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
{
uchar *wp = (uchar *)addr;
int rc;
if (info->flash_id == FLASH_UNKNOWN) {
return 4;
}
while (cnt > 0) {
if ((rc = write_data(info, wp, *src)) != 0) {
return rc;
}
wp++;
src++;
cnt--;
}
return cnt;
}
/*-----------------------------------------------------------------------
* Write a word to Flash, returns:
* 0 - OK
* 1 - write timeout
* 2 - Flash not erased
*/
static int write_data (flash_info_t *info, uchar *dest, uchar data)
{
vu_char *addr = (vu_char *)dest;
ulong status;
ulong start;
int flag;
/* Check if Flash is (sufficiently) erased */
if ((BS(*addr) & data) != data) {
return 2;
}
/* Disable interrupts which might cause a timeout here */
flag = disable_interrupts();
*addr = BS(0x40); /* write setup */
*addr = data;
/* re-enable interrupts if necessary */
if (flag) {
enable_interrupts();
}
start = get_timer (0);
while (((status = BS(*addr)) & BYTEME(0x00800080)) != BYTEME(0x00800080)) {
if (get_timer(start) > CFG_FLASH_WRITE_TOUT) {
*addr = BS(0xFF); /* restore read mode */
return 1;
}
}
*addr = BS(0xFF); /* restore read mode */
return 0;
}
/*-----------------------------------------------------------------------
*/

128
board/a3000/u-boot.lds Normal file
View File

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

View File

@@ -30,28 +30,35 @@
* Miscelaneous platform dependent initialisations
*/
int board_init(void)
{
DECLARE_GLOBAL_DATA_PTR;
int board_init (void)
{
DECLARE_GLOBAL_DATA_PTR;
/* memory and cpu-speed are setup before relocation */
/* so we do _nothing_ here */
/* Enable Ctrlc */
console_init_f ();
/* arch number of AT91RM9200DK-Board */
gd->bd->bi_arch_number = 251;
/* adress of boot parameters */
gd->bd->bi_boot_params = PHYS_SDRAM + 0x100;
/* Correct IRDA resistor problem */
/* Set PA23_TXD in Output */
(AT91PS_PIO) AT91C_BASE_PIOA->PIO_OER = AT91C_PA23_TXD2;
return 0;
/* memory and cpu-speed are setup before relocation */
/* so we do _nothing_ here */
/* arch number of AT91RM9200DK-Board */
gd->bd->bi_arch_number = 251;
/* adress of boot parameters */
gd->bd->bi_boot_params = PHYS_SDRAM + 0x100;
return 0;
}
int dram_init(void)
int dram_init (void)
{
DECLARE_GLOBAL_DATA_PTR;
DECLARE_GLOBAL_DATA_PTR;
gd->bd->bi_dram[0].start = PHYS_SDRAM;
gd->bd->bi_dram[0].size = PHYS_SDRAM_SIZE;
return 0;
gd->bd->bi_dram[0].start = PHYS_SDRAM;
gd->bd->bi_dram[0].size = PHYS_SDRAM_SIZE;
return 0;
}
/*
@@ -59,47 +66,47 @@ int dram_init(void)
* The NAND lives in the CS2* space
*/
#if (CONFIG_COMMANDS & CFG_CMD_NAND)
extern void
nand_probe(ulong physadr);
extern void nand_probe (ulong physadr);
#define AT91_SMARTMEDIA_BASE 0x40000000 /* physical address to access memory on NCS3 */
void
nand_init(void)
#define AT91_SMARTMEDIA_BASE 0x40000000 /* physical address to access memory on NCS3 */
void nand_init (void)
{
/* Setup Smart Media, fitst enable the address range of CS3 */
*AT91C_EBI_CSA |= AT91C_EBI_CS3A_SMC_SmartMedia;
/* set the bus interface characteristics based on
tDS Data Set up Time 30 - ns
tDH Data Hold Time 20 - ns
tALS ALE Set up Time 20 - ns
16ns at 60 MHz ~= 3 */
*AT91C_EBI_CSA |= AT91C_EBI_CS3A_SMC_SmartMedia;
/* set the bus interface characteristics based on
tDS Data Set up Time 30 - ns
tDH Data Hold Time 20 - ns
tALS ALE Set up Time 20 - ns
16ns at 60 MHz ~= 3 */
/*memory mapping structures */
#define SM_ID_RWH (5 << 28)
#define SM_RWH (1 << 28)
#define SM_RWS (0 << 24)
#define SM_TDF (1 << 8)
#define SM_NWS (3)
AT91C_BASE_SMC2->SMC2_CSR[3] = ( SM_RWH|SM_RWS | AT91C_SMC2_ACSS_STANDARD |
AT91C_SMC2_DBW_8 | SM_TDF |
AT91C_SMC2_WSEN | SM_NWS);
AT91C_BASE_SMC2->SMC2_CSR[3] = (SM_RWH | SM_RWS |
AT91C_SMC2_ACSS_STANDARD | AT91C_SMC2_DBW_8 |
SM_TDF | AT91C_SMC2_WSEN | SM_NWS);
/* enable the SMOE line PC0=SMCE, A21=CLE, A22=ALE */
*AT91C_PIOC_ASR = AT91C_PC0_BFCK | AT91C_PC1_BFRDY_SMOE | AT91C_PC3_BFBAA_SMWE;
*AT91C_PIOC_PDR = AT91C_PC0_BFCK | AT91C_PC1_BFRDY_SMOE | AT91C_PC3_BFBAA_SMWE;
/* enable the SMOE line PC0=SMCE, A21=CLE, A22=ALE */
*AT91C_PIOC_ASR = AT91C_PC0_BFCK | AT91C_PC1_BFRDY_SMOE |
AT91C_PC3_BFBAA_SMWE;
*AT91C_PIOC_PDR = AT91C_PC0_BFCK | AT91C_PC1_BFRDY_SMOE |
AT91C_PC3_BFBAA_SMWE;
/* Configure PC2 as input (signal READY of the SmartMedia) */
*AT91C_PIOC_PER = AT91C_PC2_BFAVD; /* enable direct output enable */
*AT91C_PIOC_ODR = AT91C_PC2_BFAVD; /* disable output */
*AT91C_PIOC_PER = AT91C_PC2_BFAVD; /* enable direct output enable */
*AT91C_PIOC_ODR = AT91C_PC2_BFAVD; /* disable output */
/* Configure PB1 as input (signal Card Detect of the SmartMedia) */
*AT91C_PIOB_PER = AT91C_PIO_PB1; /* enable direct output enable */
*AT91C_PIOB_ODR = AT91C_PIO_PB1; /* disable output */
*AT91C_PIOB_PER = AT91C_PIO_PB1; /* enable direct output enable */
*AT91C_PIOB_ODR = AT91C_PIO_PB1; /* disable output */
if (*AT91C_PIOB_PDSR & AT91C_PIO_PB1)
printf ("No ");
printf ("SmartMedia card inserted\n");
if (*AT91C_PIOB_PDSR & AT91C_PIO_PB1)
printf ("No ");
printf ("SmartMedia card inserted\n");
printf("Probing at 0x%.8x\n", AT91_SMARTMEDIA_BASE);
nand_probe(AT91_SMARTMEDIA_BASE);
printf ("Probing at 0x%.8x\n", AT91_SMARTMEDIA_BASE);
nand_probe (AT91_SMARTMEDIA_BASE);
}
#endif

View File

@@ -1,2 +1,2 @@
TEXT_BASE = 0x21fa0000
TEXT_BASE = 0x21f00000

View File

@@ -31,11 +31,40 @@
ulong myflush(void);
/* Flash Organization Structure */
typedef struct OrgDef
{
unsigned int sector_number;
unsigned int sector_size;
} OrgDef;
/* Flash Organizations */
OrgDef OrgAT49BV16x4[] =
{
{ 8, 8*1024 }, /* 8 * 8kBytes sectors */
{ 2, 32*1024 }, /* 2 * 32kBytes sectors */
{ 30, 64*1024 } /* 30 * 64kBytes sectors */
};
OrgDef OrgAT49BV16x4A[] =
{
{ 8, 8*1024 }, /* 8 * 8kBytes sectors */
{ 31, 64*1024 } /* 31 * 64kBytes sectors */
};
#define FLASH_BANK_SIZE 0x200000 /* 2 MB */
#define MAIN_SECT_SIZE 0x10000 /* 64 KB */
flash_info_t flash_info[CFG_MAX_FLASH_BANKS];
/* AT49BV1614A Codes */
#define FLASH_CODE1 0xAA
#define FLASH_CODE2 0x55
#define ID_IN_CODE 0x90
#define ID_OUT_CODE 0xF0
#define CMD_READ_ARRAY 0x00F0
#define CMD_UNLOCK1 0x00AA
@@ -48,6 +77,9 @@ flash_info_t flash_info[CFG_MAX_FLASH_BANKS];
#define MEM_FLASH_ADDR1 (*(volatile u16 *)(CFG_FLASH_BASE + (0x00005555<<1)))
#define MEM_FLASH_ADDR2 (*(volatile u16 *)(CFG_FLASH_BASE + (0x00002AAA<<1)))
#define IDENT_FLASH_ADDR1 (*(volatile u16 *)(CFG_FLASH_BASE + (0x0000555<<1)))
#define IDENT_FLASH_ADDR2 (*(volatile u16 *)(CFG_FLASH_BASE + (0x0000AAA<<1)))
#define BIT_ERASE_DONE 0x0080
#define BIT_RDY_MASK 0x0080
#define BIT_PROGRAM_ERROR 0x0020
@@ -59,339 +91,375 @@ flash_info_t flash_info[CFG_MAX_FLASH_BANKS];
/*-----------------------------------------------------------------------
*/
ulong flash_init(void)
void flash_identification (flash_info_t * info)
{
int i, j;
ulong size = 0;
volatile u16 manuf_code, device_code, add_device_code;
for (i = 0; i < CFG_MAX_FLASH_BANKS; i++)
{
ulong flashbase = 0;
flash_info[i].flash_id =
(ATM_MANUFACT & FLASH_VENDMASK) |
(ATM_ID_BV1614 & FLASH_TYPEMASK);
flash_info[i].size = FLASH_BANK_SIZE;
flash_info[i].sector_count = CFG_MAX_FLASH_SECT;
memset(flash_info[i].protect, 0, CFG_MAX_FLASH_SECT);
if (i == 0)
flashbase = PHYS_FLASH_1;
else
panic("configured to many flash banks!\n");
for (j = 0; j < flash_info[i].sector_count; j++)
{
IDENT_FLASH_ADDR1 = FLASH_CODE1;
IDENT_FLASH_ADDR2 = FLASH_CODE2;
IDENT_FLASH_ADDR1 = ID_IN_CODE;
if (j <= 9)
{
/* 1st to 8th are 8 KB */
if (j <= 7)
{
flash_info[i].start[j] = flashbase + j*0x2000;
manuf_code = *(volatile u16 *) CFG_FLASH_BASE;
device_code = *(volatile u16 *) (CFG_FLASH_BASE + 2);
add_device_code = *(volatile u16 *) (CFG_FLASH_BASE + (3 << 1));
IDENT_FLASH_ADDR1 = FLASH_CODE1;
IDENT_FLASH_ADDR2 = FLASH_CODE2;
IDENT_FLASH_ADDR1 = ID_OUT_CODE;
/* Vendor type */
info->flash_id = ATM_MANUFACT & FLASH_VENDMASK;
printf ("Atmel: ");
if ((device_code & FLASH_TYPEMASK) == (ATM_ID_BV1614 & FLASH_TYPEMASK)) {
if ((add_device_code & FLASH_TYPEMASK) ==
(ATM_ID_BV1614A & FLASH_TYPEMASK)) {
info->flash_id |= ATM_ID_BV1614A & FLASH_TYPEMASK;
printf ("AT49BV1614A (16Mbit)\n");
}
/* 9th and 10th are both 32 KB */
if ((j == 8) || (j == 9))
{
flash_info[i].start[j] = flashbase + 0x10000 + (j-8)*0x8000;
}
}
else
{
flash_info[i].start[j] = flashbase + (j-8)*MAIN_SECT_SIZE;
}
} else { /* AT49BV1614 Flash */
info->flash_id |= ATM_ID_BV1614 & FLASH_TYPEMASK;
printf ("AT49BV1614 (16Mbit)\n");
}
size += flash_info[i].size;
}
}
flash_protect(FLAG_PROTECT_SET,
CFG_FLASH_BASE,
CFG_ENV_ADDR - 1,
&flash_info[0]);
flash_protect(FLAG_PROTECT_SET,
CFG_ENV_ADDR,
CFG_ENV_ADDR + CFG_ENV_SIZE - 1,
&flash_info[0]);
ulong flash_init (void)
{
int i, j, k;
unsigned int flash_nb_blocks, sector;
unsigned int start_address;
OrgDef *pOrgDef;
return size;
ulong size = 0;
for (i = 0; i < CFG_MAX_FLASH_BANKS; i++) {
ulong flashbase = 0;
flash_identification (&flash_info[i]);
flash_info[i].size = FLASH_BANK_SIZE;
if ((flash_info[i].flash_id & FLASH_TYPEMASK) ==
(ATM_ID_BV1614 & FLASH_TYPEMASK)) {
flash_info[i].sector_count = CFG_MAX_FLASH_SECT;
memset (flash_info[i].protect, 0, CFG_MAX_FLASH_SECT);
pOrgDef = OrgAT49BV16x4;
flash_nb_blocks = sizeof (OrgAT49BV16x4) / sizeof (OrgDef);
} else { /* AT49BV1614A Flash */
flash_info[i].sector_count = CFG_MAX_FLASH_SECT - 1;
memset (flash_info[i].protect, 0, CFG_MAX_FLASH_SECT - 1);
pOrgDef = OrgAT49BV16x4A;
flash_nb_blocks = sizeof (OrgAT49BV16x4A) / sizeof (OrgDef);
}
if (i == 0)
flashbase = PHYS_FLASH_1;
else
panic ("configured to many flash banks!\n");
sector = 0;
start_address = flashbase;
for (j = 0; j < flash_nb_blocks; j++) {
for (k = 0; k < pOrgDef[j].sector_number; k++) {
flash_info[i].start[sector++] = start_address;
start_address += pOrgDef[j].sector_size;
}
}
size += flash_info[i].size;
}
/* Protect binary boot image */
flash_protect (FLAG_PROTECT_SET,
CFG_FLASH_BASE,
CFG_FLASH_BASE + CFG_BOOT_SIZE - 1, &flash_info[0]);
/* Protect environment variables */
flash_protect (FLAG_PROTECT_SET,
CFG_ENV_ADDR,
CFG_ENV_ADDR + CFG_ENV_SIZE - 1, &flash_info[0]);
/* Protect U-Boot gzipped image */
flash_protect (FLAG_PROTECT_SET,
CFG_U_BOOT_BASE,
CFG_U_BOOT_BASE + CFG_U_BOOT_SIZE - 1, &flash_info[0]);
return size;
}
/*-----------------------------------------------------------------------
*/
void flash_print_info (flash_info_t *info)
void flash_print_info (flash_info_t * info)
{
int i;
int i;
switch (info->flash_id & FLASH_VENDMASK)
{
case (ATM_MANUFACT & FLASH_VENDMASK):
printf("Atmel: ");
break;
default:
printf("Unknown Vendor ");
break;
}
switch (info->flash_id & FLASH_TYPEMASK)
{
case (ATM_ID_BV1614 & FLASH_TYPEMASK):
printf("AT49BV1614 (16Mbit)\n");
break;
default:
printf("Unknown Chip Type\n");
goto Done;
break;
}
printf(" Size: %ld MB in %d Sectors\n",
info->size >> 20, info->sector_count);
printf(" Sector Start Addresses:");
for (i = 0; i < info->sector_count; i++)
{
if ((i % 5) == 0)
{
printf ("\n ");
switch (info->flash_id & FLASH_VENDMASK) {
case (ATM_MANUFACT & FLASH_VENDMASK):
printf ("Atmel: ");
break;
default:
printf ("Unknown Vendor ");
break;
}
printf (" %08lX%s", info->start[i],
info->protect[i] ? " (RO)" : " ");
}
printf ("\n");
Done:
switch (info->flash_id & FLASH_TYPEMASK) {
case (ATM_ID_BV1614 & FLASH_TYPEMASK):
printf ("AT49BV1614 (16Mbit)\n");
break;
case (ATM_ID_BV1614A & FLASH_TYPEMASK):
printf ("AT49BV1614A (16Mbit)\n");
break;
default:
printf ("Unknown Chip Type\n");
goto Done;
break;
}
printf (" Size: %ld MB in %d Sectors\n",
info->size >> 20, info->sector_count);
printf (" Sector Start Addresses:");
for (i = 0; i < info->sector_count; i++) {
if ((i % 5) == 0) {
printf ("\n ");
}
printf (" %08lX%s", info->start[i],
info->protect[i] ? " (RO)" : " ");
}
printf ("\n");
Done:
}
/*-----------------------------------------------------------------------
*/
int flash_erase (flash_info_t *info, int s_first, int s_last)
int flash_erase (flash_info_t * info, int s_first, int s_last)
{
ulong result;
int iflag, cflag, prot, sect;
int rc = ERR_OK;
int chip1;
ulong result;
int iflag, cflag, prot, sect;
int rc = ERR_OK;
int chip1;
/* first look for protection bits */
/* first look for protection bits */
if (info->flash_id == FLASH_UNKNOWN)
return ERR_UNKNOWN_FLASH_TYPE;
if (info->flash_id == FLASH_UNKNOWN)
return ERR_UNKNOWN_FLASH_TYPE;
if ((s_first < 0) || (s_first > s_last)) {
return ERR_INVAL;
}
if ((info->flash_id & FLASH_VENDMASK) !=
(ATM_MANUFACT & FLASH_VENDMASK)) {
return ERR_UNKNOWN_FLASH_VENDOR;
}
prot = 0;
for (sect=s_first; sect<=s_last; ++sect) {
if (info->protect[sect]) {
prot++;
if ((s_first < 0) || (s_first > s_last)) {
return ERR_INVAL;
}
}
if (prot)
return ERR_PROTECTED;
/*
* Disable interrupts which might cause a timeout
* here. Remember that our exception vectors are
* at address 0 in the flash, and we don't want a
* (ticker) exception to happen while the flash
* chip is in programming mode.
*/
cflag = icache_status();
icache_disable();
iflag = disable_interrupts();
if ((info->flash_id & FLASH_VENDMASK) !=
(ATM_MANUFACT & FLASH_VENDMASK)) {
return ERR_UNKNOWN_FLASH_VENDOR;
}
/* Start erase on unprotected sectors */
for (sect = s_first; sect<=s_last && !ctrlc(); sect++)
{
printf("Erasing sector %2d ... ", sect);
/* arm simple, non interrupt dependent timer */
reset_timer_masked();
if (info->protect[sect] == 0)
{ /* not protected */
volatile u16 *addr = (volatile u16 *)(info->start[sect]);
MEM_FLASH_ADDR1 = CMD_UNLOCK1;
MEM_FLASH_ADDR2 = CMD_UNLOCK2;
MEM_FLASH_ADDR1 = CMD_ERASE_SETUP;
MEM_FLASH_ADDR1 = CMD_UNLOCK1;
MEM_FLASH_ADDR2 = CMD_UNLOCK2;
*addr = CMD_ERASE_CONFIRM;
/* wait until flash is ready */
chip1 = 0;
do
{
result = *addr;
/* check timeout */
if (get_timer_masked() > CFG_FLASH_ERASE_TOUT)
{
MEM_FLASH_ADDR1 = CMD_READ_ARRAY;
chip1 = TMO;
break;
prot = 0;
for (sect = s_first; sect <= s_last; ++sect) {
if (info->protect[sect]) {
prot++;
}
if (!chip1 && (result & 0xFFFF) & BIT_ERASE_DONE)
chip1 = READY;
} while (!chip1);
MEM_FLASH_ADDR1 = CMD_READ_ARRAY;
if (chip1 == ERR)
{
rc = ERR_PROG_ERROR;
goto outahere;
}
if (chip1 == TMO)
{
rc = ERR_TIMOUT;
goto outahere;
}
printf("ok.\n");
}
else /* it was protected */
{
printf("protected!\n");
}
}
if (prot)
return ERR_PROTECTED;
if (ctrlc())
printf("User Interrupt!\n");
/*
* Disable interrupts which might cause a timeout
* here. Remember that our exception vectors are
* at address 0 in the flash, and we don't want a
* (ticker) exception to happen while the flash
* chip is in programming mode.
*/
cflag = icache_status ();
icache_disable ();
iflag = disable_interrupts ();
/* Start erase on unprotected sectors */
for (sect = s_first; sect <= s_last && !ctrlc (); sect++) {
printf ("Erasing sector %2d ... ", sect);
/* arm simple, non interrupt dependent timer */
reset_timer_masked ();
if (info->protect[sect] == 0) { /* not protected */
volatile u16 *addr = (volatile u16 *) (info->start[sect]);
MEM_FLASH_ADDR1 = CMD_UNLOCK1;
MEM_FLASH_ADDR2 = CMD_UNLOCK2;
MEM_FLASH_ADDR1 = CMD_ERASE_SETUP;
MEM_FLASH_ADDR1 = CMD_UNLOCK1;
MEM_FLASH_ADDR2 = CMD_UNLOCK2;
*addr = CMD_ERASE_CONFIRM;
/* wait until flash is ready */
chip1 = 0;
do {
result = *addr;
/* check timeout */
if (get_timer_masked () > CFG_FLASH_ERASE_TOUT) {
MEM_FLASH_ADDR1 = CMD_READ_ARRAY;
chip1 = TMO;
break;
}
if (!chip1 && (result & 0xFFFF) & BIT_ERASE_DONE)
chip1 = READY;
} while (!chip1);
MEM_FLASH_ADDR1 = CMD_READ_ARRAY;
if (chip1 == ERR) {
rc = ERR_PROG_ERROR;
goto outahere;
}
if (chip1 == TMO) {
rc = ERR_TIMOUT;
goto outahere;
}
printf ("ok.\n");
} else { /* it was protected */
printf ("protected!\n");
}
}
if (ctrlc ())
printf ("User Interrupt!\n");
outahere:
/* allow flash to settle - wait 10 ms */
udelay_masked(10000);
/* allow flash to settle - wait 10 ms */
udelay_masked (10000);
if (iflag)
enable_interrupts();
if (iflag)
enable_interrupts ();
if (cflag)
icache_enable();
if (cflag)
icache_enable ();
return rc;
return rc;
}
/*-----------------------------------------------------------------------
* Copy memory to flash
*/
volatile static int write_word (flash_info_t *info, ulong dest, ulong data)
volatile static int write_word (flash_info_t * info, ulong dest,
ulong data)
{
volatile u16 *addr = (volatile u16 *)dest;
ulong result;
int rc = ERR_OK;
int cflag, iflag;
int chip1;
volatile u16 *addr = (volatile u16 *) dest;
ulong result;
int rc = ERR_OK;
int cflag, iflag;
int chip1;
/*
* Check if Flash is (sufficiently) erased
*/
result = *addr;
if ((result & data) != data)
return ERR_NOT_ERASED;
/*
* Disable interrupts which might cause a timeout
* here. Remember that our exception vectors are
* at address 0 in the flash, and we don't want a
* (ticker) exception to happen while the flash
* chip is in programming mode.
*/
cflag = icache_status();
icache_disable();
iflag = disable_interrupts();
MEM_FLASH_ADDR1 = CMD_UNLOCK1;
MEM_FLASH_ADDR2 = CMD_UNLOCK2;
MEM_FLASH_ADDR1 = CMD_PROGRAM;
*addr = data;
/* arm simple, non interrupt dependent timer */
reset_timer_masked();
/* wait until flash is ready */
chip1 = 0;
do
{
/*
* Check if Flash is (sufficiently) erased
*/
result = *addr;
if ((result & data) != data)
return ERR_NOT_ERASED;
/* check timeout */
if (get_timer_masked() > CFG_FLASH_ERASE_TOUT)
{
chip1 = ERR | TMO;
break;
}
if (!chip1 && ((result & 0x80) == (data & 0x80)))
chip1 = READY;
} while (!chip1);
/*
* Disable interrupts which might cause a timeout
* here. Remember that our exception vectors are
* at address 0 in the flash, and we don't want a
* (ticker) exception to happen while the flash
* chip is in programming mode.
*/
cflag = icache_status ();
icache_disable ();
iflag = disable_interrupts ();
*addr = CMD_READ_ARRAY;
MEM_FLASH_ADDR1 = CMD_UNLOCK1;
MEM_FLASH_ADDR2 = CMD_UNLOCK2;
MEM_FLASH_ADDR1 = CMD_PROGRAM;
*addr = data;
if (chip1 == ERR || *addr != data)
rc = ERR_PROG_ERROR;
/* arm simple, non interrupt dependent timer */
reset_timer_masked ();
if (iflag)
enable_interrupts();
/* wait until flash is ready */
chip1 = 0;
do {
result = *addr;
if (cflag)
icache_enable();
/* check timeout */
if (get_timer_masked () > CFG_FLASH_ERASE_TOUT) {
chip1 = ERR | TMO;
break;
}
if (!chip1 && ((result & 0x80) == (data & 0x80)))
chip1 = READY;
return rc;
} while (!chip1);
*addr = CMD_READ_ARRAY;
if (chip1 == ERR || *addr != data)
rc = ERR_PROG_ERROR;
if (iflag)
enable_interrupts ();
if (cflag)
icache_enable ();
return rc;
}
/*-----------------------------------------------------------------------
* Copy memory to flash.
*/
int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt)
{
ulong wp, data;
int rc;
ulong wp, data;
int rc;
if(addr & 1) {
printf("unaligned destination not supported\n");
return ERR_ALIGN;
};
if (addr & 1) {
printf ("unaligned destination not supported\n");
return ERR_ALIGN;
};
if((int)src & 1) {
printf("unaligned source not supported\n");
return ERR_ALIGN;
};
if ((int) src & 1) {
printf ("unaligned source not supported\n");
return ERR_ALIGN;
};
wp = addr;
wp = addr;
while (cnt >= 2) {
data = *((volatile u16*)src);
if ((rc = write_word(info, wp, data)) != 0) {
return (rc);
while (cnt >= 2) {
data = *((volatile u16 *) src);
if ((rc = write_word (info, wp, data)) != 0) {
return (rc);
}
src += 2;
wp += 2;
cnt -= 2;
}
src += 2;
wp += 2;
cnt -= 2;
}
if(cnt == 1) {
data = (*((volatile u8*)src)) | (*((volatile u8*)(wp+1)) << 8);
if ((rc = write_word(info, wp, data)) != 0) {
return (rc);
}
src += 1;
wp += 1;
cnt -= 1;
};
if (cnt == 1) {
data = (*((volatile u8 *) src)) | (*((volatile u8 *) (wp + 1)) <<
8);
if ((rc = write_word (info, wp, data)) != 0) {
return (rc);
}
src += 1;
wp += 1;
cnt -= 1;
};
return ERR_OK;
return ERR_OK;
}

View File

@@ -203,6 +203,49 @@ const iop_conf_t iop_conf_tab[4][32] = {
}
};
/*
* UPMB initialization table
*/
#define _NOT_USED_ 0xFFFFFFFF
static const uint rtc_table[] =
{
/*
* Single Read. (Offset 0 in UPMA RAM)
*/
0xfffec00, 0xfffac00, 0xfff2d00, 0xfef2800,
0xfaf2080, 0xfaf2080, 0xfff2400, 0x1fff6c05, /* last */
/*
* Burst Read. (Offset 8 in UPMA RAM)
*/
_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
/*
* Single Write. (Offset 18 in UPMA RAM)
*/
0xfffec00, 0xfffac00, 0xfff2d00, 0xfef2800,
0xfaf2080, 0xfaf2080, 0xfaf2400, 0x1fbf6c05, /* last */
/*
* Burst Write. (Offset 20 in UPMA RAM)
*/
_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
/*
* Refresh (Offset 30 in UPMA RAM)
*/
_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
/*
* Exception. (Offset 3c in UPMA RAM)
*/
_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
};
/* ------------------------------------------------------------------------- */
/* Check Board Identity:
@@ -319,6 +362,17 @@ static long int try_init (volatile memctl8260_t * memctl, ulong sdmr,
return (maxsize);
}
int misc_init_r(void)
{
volatile immap_t *immap = (immap_t *) CFG_IMMR;
volatile memctl8260_t *memctl = &immap->im_memctl;
upmconfig(UPMA, (uint *)rtc_table, sizeof(rtc_table) / sizeof(uint));
memctl->memc_mamr = MxMR_RLFx_6X | MxMR_WLFx_6X | MxMR_OP_NORM;
return (0);
}
long int initdram (int board_type)
{
volatile immap_t *immap = (immap_t *) CFG_IMMR;

View File

@@ -30,12 +30,7 @@
# in RAM where U-Boot is loaded at for debugging.
#
ifeq ($(CONFIG_BOOT_ROM),y)
TEXT_BASE := 0xFF800000
PLATFORM_CPPFLAGS += -DCONFIG_BOOT_ROM
else
TEXT_BASE := 0xFF000000
endif
TEXT_BASE := 0xFF000000
# RAM version
#TEXT_BASE := 0x100000

View File

@@ -25,7 +25,7 @@ include $(TOPDIR)/config.mk
LIB = lib$(BOARD).a
OBJS = $(BOARD).o flash.o bsp.o eeprom.o fetch.o
OBJS = $(BOARD).o flash.o bsp.o eeprom.o fetch.o input.o env.o
$(LIB): .depend $(OBJS)
$(AR) crv $@ $^

View File

@@ -20,13 +20,12 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*
* hacked for Hymod FPGA support by Murray.Jensen@cmst.csiro.au, 29-Jan-01
* hacked for Hymod FPGA support by Murray.Jensen@csiro.au, 29-Jan-01
*/
#include <common.h>
#include <command.h>
#include <net.h>
#include <i2c.h>
#include <asm/iopin_8260.h>
#include <cmd_bsp.h>
@@ -74,28 +73,29 @@
* has not worked (wait several ms?)
*/
int fpga_load (int mezz, uchar * addr, ulong size)
int
fpga_load (int mezz, uchar *addr, ulong size)
{
DECLARE_GLOBAL_DATA_PTR;
hymod_conf_t *cp = &gd->bd->bi_hymod_conf;
xlx_info_t *fp;
xlx_iopins_t *fpgaio;
volatile uchar *fpgabase;
volatile uint cnt;
uchar *eaddr = addr + size;
int result;
if (mezz) {
if (!cp->mezz.mmap[0].prog.exists)
return (LOAD_FAIL_NOCONF);
fpgabase = (uchar *) cp->mezz.mmap[0].prog.base;
fpgaio = &cp->mezz.iopins[0];
} else {
if (!cp->main.mmap[0].prog.exists)
return (LOAD_FAIL_NOCONF);
fpgabase = (uchar *) cp->main.mmap[0].prog.base;
fpgaio = &cp->main.iopins[0];
}
if (mezz)
fp = &cp->mezz.xlx[0];
else
fp = &cp->main.xlx[0];
if (!fp->mmap.prog.exists)
return (LOAD_FAIL_NOCONF);
fpgabase = (uchar *)fp->mmap.prog.base;
fpgaio = &fp->iopins;
/* set enable HIGH if required */
if (fpgaio->enable_pin.flag)
@@ -106,7 +106,7 @@ int fpga_load (int mezz, uchar * addr, ulong size)
/* toggle PROG Low then High (will already be Low after Power-On) */
iopin_set_low (&fpgaio->prog_pin);
udelay (1); /* minimum 300ns - 1usec should do it */
udelay (1); /* minimum 300ns - 1usec should do it */
iopin_set_high (&fpgaio->prog_pin);
/* wait for INIT High */
@@ -157,15 +157,15 @@ do_fpga (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
case 2:
if (strcmp (argv[1], "info") == 0) {
printf ("\nHymod FPGA Info...\n");
printf (" Address Size\n");
printf (" Main Configuration: 0x%08x %d\n",
FPGA_MAIN_CFG_BASE, FPGA_MAIN_CFG_SIZE);
printf (" Main Register: 0x%08x %d\n",
FPGA_MAIN_REG_BASE, FPGA_MAIN_REG_SIZE);
printf (" Main Port: 0x%08x %d\n",
FPGA_MAIN_PORT_BASE, FPGA_MAIN_PORT_SIZE);
printf (" Mezz Configuration: 0x%08x %d\n",
FPGA_MEZZ_CFG_BASE, FPGA_MEZZ_CFG_SIZE);
printf ("\t\t\t\tAddress\t\tSize\n");
printf ("\tMain Configuration:\t0x%08x\t%d\n",
FPGA_MAIN_CFG_BASE, FPGA_MAIN_CFG_SIZE);
printf ("\tMain Register:\t\t0x%08x\t%d\n",
FPGA_MAIN_REG_BASE, FPGA_MAIN_REG_SIZE);
printf ("\tMain Port:\t\t0x%08x\t%d\n",
FPGA_MAIN_PORT_BASE, FPGA_MAIN_PORT_SIZE);
printf ("\tMezz Configuration:\t0x%08x\t%d\n",
FPGA_MEZZ_CFG_BASE, FPGA_MEZZ_CFG_SIZE);
return 0;
}
break;
@@ -176,18 +176,21 @@ do_fpga (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
save_addr = addr;
#if 0
/* reading config data unimplemented */
while VM
:more config data * addr++ = *fpga;
result = VM:? ? ?
/* fpga readback unimplemented */
while (more readback data)
*addr++ = *fpga;
result = error ? STORE_FAIL_XXX : STORE_SUCCESS;
#else
result = 0;
result = STORE_SUCCESS;
#endif
if (result == STORE_SUCCESS) {
printf ("SUCCEEDED (%d bytes)\n", addr - save_addr);
printf ("SUCCEEDED (%d bytes)\n",
addr - save_addr);
return 0;
} else
printf ("FAILED (%d bytes)\n", addr - save_addr);
printf ("FAILED (%d bytes)\n",
addr - save_addr);
return 1;
}
break;
@@ -196,25 +199,32 @@ do_fpga (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
if (strcmp (argv[1], "tftp") == 0) {
copy_filename (BootFile, argv[2], sizeof (BootFile));
load_addr = simple_strtoul (argv[3], NULL, 16);
NetBootFileXferSize = 0;
if (NetLoop (TFTP) <= 0) {
printf ("tftp transfer failed - aborting fgpa load\n");
printf ("tftp transfer failed - aborting "
"fgpa load\n");
return 1;
}
if (NetBootFileXferSize == 0) {
printf ("can't determine file size - aborting fpga load\n");
printf ("can't determine file size - "
"aborting fpga load\n");
return 1;
}
printf ("File transfer succeeded - beginning fpga load...");
printf ("File transfer succeeded - "
"beginning fpga load...");
result = fpga_load (0, (uchar *) load_addr,
NetBootFileXferSize);
NetBootFileXferSize);
if (result == LOAD_SUCCESS) {
printf ("SUCCEEDED\n");
return 0;
} else if (result == LOAD_FAIL_NOINIT)
} else if (result == LOAD_FAIL_NOCONF)
printf ("FAILED (no CONF)\n");
else if (result == LOAD_FAIL_NOINIT)
printf ("FAILED (no INIT)\n");
else
printf ("FAILED (no DONE)\n");
@@ -231,7 +241,8 @@ do_fpga (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
else if (strcmp (argv[2], "mezz") == 0)
mezz = 1;
else {
printf ("FPGA type must be either `main' or `mezz'\n");
printf ("FPGA type must be either "
"`main' or `mezz'\n");
return 1;
}
arg = 3;
@@ -239,14 +250,18 @@ do_fpga (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
mezz = 0;
arg = 2;
}
addr = (uchar *) simple_strtoul (argv[arg++], NULL, 16);
size = (ulong) simple_strtoul (argv[arg], NULL, 16);
result = fpga_load (mezz, addr, size);
if (result == LOAD_SUCCESS) {
printf ("SUCCEEDED\n");
return 0;
} else if (result == LOAD_FAIL_NOINIT)
} else if (result == LOAD_FAIL_NOCONF)
printf ("FAILED (no CONF)\n");
else if (result == LOAD_FAIL_NOINIT)
printf ("FAILED (no INIT)\n");
else
printf ("FAILED (no DONE)\n");
@@ -267,22 +282,21 @@ int
do_eecl (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
{
uchar data[HYMOD_EEPROM_SIZE];
uint offset;
int rcode = 0;
uint addr = CFG_I2C_EEPROM_ADDR;
switch (argc) {
case 1:
offset = HYMOD_EEOFF_MAIN;
addr |= HYMOD_EEOFF_MAIN;
break;
case 2:
if (strcmp (argv[1], "main") == 0) {
offset = HYMOD_EEOFF_MAIN;
addr |= HYMOD_EEOFF_MAIN;
break;
}
if (strcmp (argv[1], "mezz") == 0) {
offset = HYMOD_EEOFF_MEZZ;
addr |= HYMOD_EEOFF_MEZZ;
break;
}
/* fall through ... */
@@ -293,15 +307,77 @@ do_eecl (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
}
memset (data, 0, HYMOD_EEPROM_SIZE);
if (i2c_write
(CFG_I2C_EEPROM_ADDR | offset, 0, CFG_I2C_EEPROM_ADDR_LEN, data,
HYMOD_EEPROM_SIZE)) {
rcode = 1;
}
return rcode;
eeprom_write (addr, 0, data, HYMOD_EEPROM_SIZE);
return 0;
}
#endif /* CFG_CMD_BSP */
/* ------------------------------------------------------------------------- */
#if 0
static uchar test_bitfile[] = {
/* one day ... */
};
#endif
int
do_htest (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
#if 0
int rc;
#endif
#ifdef CONFIG_ETHER_LOOPBACK_TEST
extern void eth_loopback_test (void);
#endif /* CONFIG_ETHER_LOOPBACK_TEST */
printf ("HYMOD tests - ensure loopbacks etc. are connected\n\n");
#if 0
/* Load FPGA with test program */
printf ("Loading test FPGA program ...");
rc = fpga_load (0, test_bitfile, sizeof (test_bitfile));
switch (rc) {
case LOAD_SUCCESS:
printf (" SUCCEEDED\n");
break;
case LOAD_FAIL_NOCONF:
printf (" FAILED (no configuration space defined)\n");
return 1;
case LOAD_FAIL_NOINIT:
printf (" FAILED (timeout - no INIT signal seen)\n");
return 1;
case LOAD_FAIL_NODONE:
printf (" FAILED (timeout - no DONE signal seen)\n");
return 1;
default:
printf (" FAILED (unknown return code from fpga_load\n");
return 1;
}
/* run Local Bus <=> Xilinx tests */
/* tell Xilinx to run ZBT Ram, High Speed serial and Mezzanine tests */
/* run SDRAM test */
#endif
#ifdef CONFIG_ETHER_LOOPBACK_TEST
/* run Ethernet test */
eth_loopback_test ();
#endif /* CONFIG_ETHER_LOOPBACK_TEST */
return 0;
}
#endif /* CFG_CMD_BSP */
/* ------------------------------------------------------------------------- */

View File

@@ -27,6 +27,6 @@
TEXT_BASE = 0x40000000
PLATFORM_CPPFLAGS += -DTEXT_BASE=$(TEXT_BASE) -I$(TOPDIR)
PLATFORM_CPPFLAGS += -I$(TOPDIR)
OBJCFLAGS = --set-section-flags=.ppcenv=contents,alloc,load,data
OBJCFLAGS = --remove-section=.ppcenv

File diff suppressed because it is too large Load Diff

236
board/hymod/env.c Normal file
View File

@@ -0,0 +1,236 @@
/*
* (C) Copyright 2003
* Murray Jensen, CSIRO-MIT, <Murray.Jensen@csiro.au>
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public 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>
/* imports from fetch.c */
extern int fetch_and_parse (char *, ulong, int (*)(uchar *, uchar *));
/* this is relative to the root of the server's tftp directory */
static char *def_global_env_path = "/hymod/global_env";
static int
env_callback (uchar *name, uchar *value)
{
DECLARE_GLOBAL_DATA_PTR;
hymod_conf_t *cp = &gd->bd->bi_hymod_conf;
char ov[CFG_CBSIZE], nv[CFG_CBSIZE], *p, *q, *nn, c, *curver, *newver;
int override = 1, append = 0, remove = 0, nnl, ovl, nvl;
nn = name;
if (*nn == '-') {
override = 0;
nn++;
}
while (*nn == ' ' || *nn == '\t')
nn++;
if ((nnl = strlen (nn)) == 0) {
printf ("Empty name in global env file\n");
return (0);
}
if ((c = nn[nnl - 1]) == '+' || c == '-') {
if (c == '+')
append = 1;
else
remove = 1;
nn[--nnl] = '\0';
}
while (nnl > 0 && ((c = nn[nnl - 1]) == ' ' || c == '\t'))
nn[--nnl] = '\0';
if (nnl == 0) {
printf ("Empty name in global env file\n");
return (0);
}
p = value;
q = nv;
while ((c = *p) == ' ' || c == '\t')
p++;
nvl = strlen (p);
while (nvl > 0 && ((c = p[nvl - 1]) == ' ' || c == '\t'))
p[--nvl] = '\0';
while ((*q = *p++) != '\0') {
if (*q == '%') {
switch (*p++) {
case '\0': /* whoops - back up */
p--;
break;
case '%': /* a single percent character */
q++;
break;
case 's': /* main board serial number as string */
q += sprintf (q, "%010lu",
cp->main.eeprom.serno);
break;
case 'S': /* main board serial number as number */
q += sprintf (q, "%lu", cp->main.eeprom.serno);
break;
default: /* ignore any others */
break;
}
}
else
q++;
}
if ((nvl = q - nv) == 0) {
setenv (nn, NULL);
return (1);
}
if ((curver = getenv ("global_env_version")) == NULL)
curver = "unknown";
if ((newver = getenv ("new_genv_version")) == NULL || \
strcmp (curver, newver) == 0) {
if (strcmp (nn, "version") == 0)
setenv ("new_genv_version", nv);
return (1);
}
if ((p = getenv (nn)) != NULL) {
strcpy (ov, p);
ovl = strlen (ov);
if (append) {
if (strstr (ov, nv) == NULL) {
printf ("Appending '%s' to env var '%s'\n",
nv, nn);
while (nvl >= 0) {
nv[ovl + 1 + nvl] = nv[nvl];
nvl--;
}
nv[ovl] = ' ';
while (--ovl >= 0)
nv[ovl] = ov[ovl];
setenv (nn, nv);
}
return (1);
}
if (remove) {
if (strstr (ov, nv) != NULL) {
printf ("Removing '%s' from env var '%s'\n",
nv, nn);
while ((p = strstr (ov, nv)) != NULL) {
q = p + nvl;
if (*q == ' ')
q++;
strcpy(p, q);
}
setenv (nn, ov);
}
return (1);
}
if (!override || strcmp (ov, nv) == 0)
return (1);
printf ("Re-setting env cmd '%s' from '%s' to '%s'\n",
nn, ov, nv);
}
else
printf ("Setting env cmd '%s' to '%s'\n", nn, nv);
setenv (nn, nv);
return (1);
}
void
hymod_check_env (void)
{
char *p, *path, *curver, *newver;
int firsttime = 0, needsave = 0;
if (getenv ("global_env_loaded") == NULL) {
puts ("*** global environment has never been loaded\n");
puts ("*** fetching from server");
firsttime = 1;
}
else if ((p = getenv ("always_check_env")) != NULL &&
strcmp (p, "yes") == 0)
puts ("*** checking for updated global environment");
else
return;
puts (" (Control-C to Abort)\n");
if ((path = getenv ("global_env_path")) == NULL || *path == '\0')
path = def_global_env_path;
if (fetch_and_parse (path, CFG_LOAD_ADDR, env_callback) == 0) {
puts ("*** Fetch of global environment failed!\n");
return;
}
if ((newver = getenv ("new_genv_version")) == NULL) {
puts ("*** Version number not set - contents ignored!\n");
return;
}
if ((curver = getenv ("global_env_version")) == NULL || \
strcmp (curver, newver) != 0) {
setenv ("global_env_version", newver);
needsave = 1;
}
else
printf ("*** Global environment up-to-date (ver %s)\n", curver);
setenv ("new_genv_version", NULL);
if (firsttime) {
setenv ("global_env_loaded", "yes");
needsave = 1;
}
if (needsave)
puts ("\n*** Remember to run the 'saveenv' "
"command to save the changes\n\n");
}

View File

@@ -1,7 +1,6 @@
/*
* (C) Copyright 2001
* Murray Jensen, CSIRO Manufacturing Science and Technology,
* <Murray.Jensen@cmst.csiro.au>
* Murray Jensen, CSIRO-MIT, <Murray.Jensen@csiro.au>
*
* See file CREDITS for list of people who contributed to this
* project.
@@ -25,118 +24,84 @@
#include <common.h>
#include <net.h>
/* imports from common/main.c */
extern char console_buffer[CFG_CBSIZE];
/* imports from input.c */
extern int hymod_get_ethaddr (void);
int
fetch_and_parse(bd_t *bd, char *fn, ulong addr, int (*cback)(uchar *, uchar *))
fetch_and_parse (char *fn, ulong addr, int (*cback)(uchar *, uchar *))
{
char *ethaddr;
uchar *fp, *efp;
char *ethaddr;
uchar *fp, *efp;
int rc, count = 0;
while ((ethaddr = getenv("ethaddr")) == NULL || *ethaddr == '\0') {
while ((ethaddr = getenv ("ethaddr")) == NULL || *ethaddr == '\0') {
puts("*** Ethernet address is not set\n");
printf ("*** Ethernet address is%s not set\n",
count == 0 ? "" : " STILL");
for (;;) {
int n;
if ((rc = hymod_get_ethaddr ()) < 0) {
if (rc == -1)
puts ("\n*** interrupted!");
else
puts ("\n*** timeout!");
printf (" - fetch of '%s' aborted\n", fn);
return (0);
}
n = readline("Enter board ethernet address: ");
count++;
}
if (n < 0) {
puts("\n");
copy_filename (BootFile, fn, sizeof (BootFile));
load_addr = addr;
NetBootFileXferSize = 0;
if (NetLoop (TFTP) == 0) {
printf ("tftp transfer of file '%s' failed\n", fn);
return (0);
}
if (n == 0)
continue;
if (n == 17) {
int i;
char *p, *q;
uchar ea[6];
/* see if it looks like an ethernet address */
p = console_buffer;
for (i = 0; i < 6; i++) {
char term = (i == 5 ? '\0' : ':');
ea[i] = simple_strtol(p, &q, 16);
if ((q - p) != 2 || *q++ != term)
break;
p = q;
}
if (i == 6) {
/* it looks ok - set it */
printf("Setting ethernet address to %s\n", console_buffer);
setenv("ethaddr", console_buffer);
puts("Remember to do a 'saveenv' to make it permanent\n");
break;
}
}
printf("Invalid ethernet address (%s) - please re-enter\n",
console_buffer);
}
}
copy_filename(BootFile, fn, sizeof (BootFile));
load_addr = addr;
if (NetLoop(TFTP) <= 0) {
printf("tftp transfer of file '%s' failed\n", fn);
return (0);
}
if (NetBootFileXferSize == 0) {
printf("can't determine size of file '%s'\n", fn);
return (0);
}
fp = (uchar *)load_addr;
efp = fp + NetBootFileXferSize;
do {
uchar *name, *value;
if (*fp == '#' || *fp == '\n') {
while (fp < efp && *fp++ != '\n')
;
continue;
}
name = fp;
if (NetBootFileXferSize == 0) {
printf ("can't determine size of file '%s'\n", fn);
return (0);
}
fp = (uchar *)load_addr;
efp = fp + NetBootFileXferSize;
do {
uchar *name, *value;
if (*fp == '#' || *fp == '\n') {
/* skip this line */
while (fp < efp && *fp++ != '\n')
;
continue;
}
while (fp < efp && *fp != '=')
if (*fp++ == '\n')
name = fp;
if (fp >= efp)
break;
while (fp < efp && *fp != '=' && *fp != '\n')
fp++;
if (fp >= efp)
break;
if (*fp == '\n') {
fp++;
continue;
}
*fp++ = '\0';
*fp++ = '\0';
value = fp;
value = fp;
while (fp < efp && *fp != '\n')
fp++;
if (fp[-1] == '\r')
fp[-1] = '\0';
*fp++ = '\0'; /* ok if we go off the end here */
while (fp < efp && *fp != '\n')
fp++;
if ((*cback)(name, value) == 0)
return (0);
/* ok if we go off the end here */
} while (fp < efp);
if (fp[-1] == '\r')
fp[-1] = '\0';
*fp++ = '\0';
if ((*cback)(name, value) == 0)
return (0);
} while (fp < efp);
return (1);
return (1);
}

View File

@@ -20,7 +20,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*
* Hacked for the Hymod board by Murray.Jensen@cmst.csiro.au, 20-Oct-00
* Hacked for the Hymod board by Murray.Jensen@csiro.au, 20-Oct-00
*/
#include <common.h>
@@ -35,235 +35,155 @@ flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */
#define FLAG_PROTECT_SET 0x01
#define FLAG_PROTECT_CLEAR 0x02
/*-----------------------------------------------------------------------
* Functions
*/
#if 0
static ulong flash_get_size (vu_long *addr, flash_info_t *info);
static void flash_get_offsets (ulong base, flash_info_t *info);
#endif
static int write_word (flash_info_t *info, ulong dest, ulong data);
/*-----------------------------------------------------------------------
*/
/*
* probe for the existence of flash at bank word address "addr"
* 0 = yes, 1 = bad Manufacturer's Id, 2 = bad Device Id
* probe for flash bank at address "base" and store info about it
* in the flash_info entry "fip". Fatal error if nothing there.
*/
static int
bank_probe_word(bank_addr_t addr)
static void
bank_probe (flash_info_t *fip, volatile bank_addr_t base)
{
int retval;
volatile bank_addr_t addr;
bank_word_t word;
int i;
/* reset the flash */
*addr = BANK_CMD_RST;
*base = BANK_CMD_RST;
/* check the manufacturer id */
*addr = BANK_CMD_RD_ID;
if (*BANK_ADDR_REG_MAN(addr) != BANK_RD_ID_MAN) {
retval = -1;
goto out;
}
/* put flash into read id mode */
*base = BANK_CMD_RD_ID;
/* check the manufacturer id - must be intel */
word = *BANK_REG_MAN_CODE (base);
if (word != BANK_FILL_WORD (INTEL_MANUFACT&0xff))
panic ("\nbad manufacturer's code (0x%08lx) at addr 0x%08lx",
(unsigned long)word, (unsigned long)base);
/* check the device id */
*addr = BANK_CMD_RD_ID;
if (*BANK_ADDR_REG_DEV(addr) != BANK_RD_ID_DEV) {
retval = -2;
goto out;
word = *BANK_REG_DEV_CODE (base);
switch (word) {
case BANK_FILL_WORD (INTEL_ID_28F320J5&0xff):
fip->flash_id = FLASH_MAN_INTEL | FLASH_28F320J5;
fip->sector_count = 32;
break;
case BANK_FILL_WORD (INTEL_ID_28F640J5&0xff):
fip->flash_id = FLASH_MAN_INTEL | FLASH_28F640J5;
fip->sector_count = 64;
break;
case BANK_FILL_WORD (INTEL_ID_28F320J3A&0xff):
fip->flash_id = FLASH_MAN_INTEL | FLASH_28F320J3A;
fip->sector_count = 32;
break;
case BANK_FILL_WORD (INTEL_ID_28F640J3A&0xff):
fip->flash_id = FLASH_MAN_INTEL | FLASH_28F640J3A;
fip->sector_count = 64;
break;
case BANK_FILL_WORD (INTEL_ID_28F128J3A&0xff):
fip->flash_id = FLASH_MAN_INTEL | FLASH_28F128J3A;
fip->sector_count = 128;
break;
default:
panic ("\nbad device code (0x%08lx) at addr 0x%08lx",
(unsigned long)word, (unsigned long)base);
}
retval = CFG_FLASH_TYPE;
out:
/* reset the flash again */
*addr = BANK_CMD_RST;
return retval;
}
/*
* probe for flash banks at address "base" and store info for any found
* into flash_info entry "fip". Must find at least one bank.
*/
static void
bank_probe(flash_info_t *fip, bank_addr_t base)
{
bank_addr_t addr, eaddr;
int nbanks;
fip->flash_id = FLASH_UNKNOWN;
fip->size = 0L;
fip->sector_count = 0;
if (fip->sector_count >= CFG_MAX_FLASH_SECT)
panic ("\ntoo many sectors (%d) in flash at address 0x%08lx",
fip->sector_count, (unsigned long)base);
addr = base;
eaddr = BANK_ADDR_BASE(addr, MAX_BANKS);
nbanks = 0;
while (addr < eaddr) {
bank_addr_t addrw, eaddrw, addrb;
int i, osc, nsc, curtype = -1;
addrw = addr;
eaddrw = BANK_ADDR_NEXT_WORD(addrw);
while (addrw < eaddrw) {
int thistype;
#ifdef FLASH_DEBUG
printf(" probing for flash at addr 0x%08lx\n",
(unsigned long)addrw);
#endif
if ((thistype = bank_probe_word(addrw++)) < 0)
goto out;
if (curtype < 0)
curtype = thistype;
else {
if (thistype != curtype) {
printf("Differing flash type found!\n");
goto out;
}
}
}
if (curtype < 0)
goto out;
/* bank exists - append info for this bank to *fip */
fip->flash_id = FLASH_MAN_INTEL|curtype;
fip->size += BANK_SIZE;
osc = fip->sector_count;
fip->sector_count += BANK_NBLOCKS;
if ((nsc = fip->sector_count) >= CFG_MAX_FLASH_SECT)
panic("Too many sectors in flash at address 0x%08lx\n",
(unsigned long)base);
addrb = addr;
for (i = osc; i < nsc; i++) {
fip->start[i] = (ulong)addrb;
fip->protect[i] = 0;
addrb = BANK_ADDR_NEXT_BLK(addrb);
}
addr = BANK_ADDR_NEXT_BANK(addr);
nbanks++;
for (i = 0; i < fip->sector_count; i++) {
fip->start[i] = (unsigned long)addr;
fip->protect[i] = 0;
addr = BANK_ADDR_NEXT_BLK (addr);
}
out:
if (nbanks == 0)
panic("ERROR: no flash found at address 0x%08lx\n",
(unsigned long)base);
fip->size = (bank_size_t)addr - (bank_size_t)base;
/* reset the flash */
*base = BANK_CMD_RST;
}
static void
bank_reset(flash_info_t *info, int sect)
bank_reset (flash_info_t *info, int sect)
{
bank_addr_t addrw, eaddrw;
volatile bank_addr_t addr = (bank_addr_t)info->start[sect];
addrw = (bank_addr_t)info->start[sect];
eaddrw = BANK_ADDR_NEXT_WORD(addrw);
while (addrw < eaddrw) {
#ifdef FLASH_DEBUG
printf(" writing reset cmd to addr 0x%08lx\n",
(unsigned long)addrw);
printf ("writing reset cmd to addr 0x%08lx\n", (unsigned long)addr);
#endif
*addrw = BANK_CMD_RST;
addrw++;
}
*addr = BANK_CMD_RST;
}
static void
bank_erase_init(flash_info_t *info, int sect)
bank_erase_init (flash_info_t *info, int sect)
{
bank_addr_t addrw, saddrw, eaddrw;
volatile bank_addr_t addr = (bank_addr_t)info->start[sect];
int flag;
#ifdef FLASH_DEBUG
printf("0x%08lx BANK_CMD_PROG\n", BANK_CMD_PROG);
printf("0x%08lx BANK_CMD_ERASE1\n", BANK_CMD_ERASE1);
printf("0x%08lx BANK_CMD_ERASE2\n", BANK_CMD_ERASE2);
printf("0x%08lx BANK_CMD_CLR_STAT\n", BANK_CMD_CLR_STAT);
printf("0x%08lx BANK_CMD_RST\n", BANK_CMD_RST);
printf("0x%08lx BANK_STAT_RDY\n", BANK_STAT_RDY);
printf("0x%08lx BANK_STAT_ERR\n", BANK_STAT_ERR);
#endif
saddrw = (bank_addr_t)info->start[sect];
eaddrw = BANK_ADDR_NEXT_WORD(saddrw);
#ifdef FLASH_DEBUG
printf("erasing sector %d, start addr = 0x%08lx "
"(bank next word addr = 0x%08lx)\n", sect,
(unsigned long)saddrw, (unsigned long)eaddrw);
printf ("erasing sector %d, addr = 0x%08lx\n",
sect, (unsigned long)addr);
#endif
/* Disable intrs which might cause a timeout here */
flag = disable_interrupts();
flag = disable_interrupts ();
for (addrw = saddrw; addrw < eaddrw; addrw++) {
#ifdef FLASH_DEBUG
printf(" writing erase cmd to addr 0x%08lx\n",
(unsigned long)addrw);
printf ("writing erase cmd to addr 0x%08lx\n", (unsigned long)addr);
#endif
*addrw = BANK_CMD_ERASE1;
*addrw = BANK_CMD_ERASE2;
}
*addr = BANK_CMD_ERASE1;
*addr = BANK_CMD_ERASE2;
/* re-enable interrupts if necessary */
if (flag)
enable_interrupts();
enable_interrupts ();
}
static int
bank_erase_poll(flash_info_t *info, int sect)
bank_erase_poll (flash_info_t *info, int sect)
{
bank_addr_t addrw, saddrw, eaddrw;
int sectdone, haderr;
saddrw = (bank_addr_t)info->start[sect];
eaddrw = BANK_ADDR_NEXT_WORD(saddrw);
sectdone = 1;
haderr = 0;
for (addrw = saddrw; addrw < eaddrw; addrw++) {
bank_word_t stat = *addrw;
volatile bank_addr_t addr = (bank_addr_t)info->start[sect];
bank_word_t stat = *addr;
#ifdef FLASH_DEBUG
printf(" checking status at addr "
"0x%08lx [0x%08lx]\n",
(unsigned long)addrw, stat);
printf ("checking status at addr 0x%08lx [0x%08lx]\n",
(unsigned long)addr, (unsigned long)stat);
#endif
if ((stat & BANK_STAT_RDY) != BANK_STAT_RDY)
sectdone = 0;
else if ((stat & BANK_STAT_ERR) != 0) {
printf(" failed on sector %d "
"(stat = 0x%08lx) at "
"address 0x%08lx\n",
sect, stat,
(unsigned long)addrw);
*addrw = BANK_CMD_CLR_STAT;
haderr = 1;
}
}
if (haderr)
return (-1);
if ((stat & BANK_STAT_RDY) == BANK_STAT_RDY) {
if ((stat & BANK_STAT_ERR) != 0) {
printf ("failed on sector %d [0x%08lx] at "
"address 0x%08lx\n", sect,
(unsigned long)stat, (unsigned long)addr);
*addr = BANK_CMD_CLR_STAT;
return (-1);
}
else
return (1);
}
else
return (sectdone);
return (0);
}
static int
bank_write_word(bank_addr_t addr, bank_word_t value)
bank_write_word (volatile bank_addr_t addr, bank_word_t value)
{
bank_word_t stat;
ulong start;
int flag, retval;
/* Disable interrupts which might cause a timeout here */
flag = disable_interrupts();
flag = disable_interrupts ();
*addr = BANK_CMD_PROG;
@@ -271,14 +191,14 @@ bank_write_word(bank_addr_t addr, bank_word_t value)
/* re-enable interrupts if necessary */
if (flag)
enable_interrupts();
enable_interrupts ();
retval = 0;
/* data polling for D7 */
start = get_timer (0);
do {
if (get_timer(start) > CFG_FLASH_WRITE_TOUT) {
if (get_timer (start) > CFG_FLASH_WRITE_TOUT) {
retval = 1;
goto done;
}
@@ -286,8 +206,8 @@ bank_write_word(bank_addr_t addr, bank_word_t value)
} while ((stat & BANK_STAT_RDY) != BANK_STAT_RDY);
if ((stat & BANK_STAT_ERR) != 0) {
printf("flash program failed (stat = 0x%08lx) "
"at address 0x%08lx\n", (ulong)stat, (ulong)addr);
printf ("flash program failed [0x%08lx] at address 0x%08lx\n",
(unsigned long)stat, (unsigned long)addr);
*addr = BANK_CMD_CLR_STAT;
retval = 3;
}
@@ -303,7 +223,7 @@ done:
*/
unsigned long
flash_init(void)
flash_init (void)
{
int i;
@@ -312,21 +232,21 @@ flash_init(void)
flash_info[i].flash_id = FLASH_UNKNOWN;
}
bank_probe(&flash_info[0], (bank_addr_t)CFG_FLASH_BASE);
bank_probe (&flash_info[0], (bank_addr_t)CFG_FLASH_BASE);
/*
* protect monitor and environment sectors
*/
#if CFG_MONITOR_BASE == CFG_FLASH_BASE
(void)flash_protect(FLAG_PROTECT_SET,
(void)flash_protect (FLAG_PROTECT_SET,
CFG_MONITOR_BASE,
CFG_MONITOR_BASE+monitor_flash_len-1,
&flash_info[0]);
#endif
#if defined(CFG_FLASH_ENV_ADDR)
(void)flash_protect(FLAG_PROTECT_SET,
(void)flash_protect (FLAG_PROTECT_SET,
CFG_FLASH_ENV_ADDR,
#if defined(CFG_FLASH_ENV_BUF)
CFG_FLASH_ENV_ADDR + CFG_FLASH_ENV_BUF - 1,
@@ -339,42 +259,10 @@ flash_init(void)
return flash_info[0].size;
}
/*-----------------------------------------------------------------------
*/
#if 0
static void
flash_get_offsets(ulong base, flash_info_t *info)
{
int i;
/* set up sector start adress table */
if (info->flash_id & FLASH_BTYPE) {
/* set sector offsets for bottom boot block type */
info->start[0] = base + 0x00000000;
info->start[1] = base + 0x00008000;
info->start[2] = base + 0x0000C000;
info->start[3] = base + 0x00010000;
for (i = 4; i < info->sector_count; i++) {
info->start[i] = base + (i * 0x00020000) - 0x00060000;
}
} else {
/* set sector offsets for top boot block type */
i = info->sector_count - 1;
info->start[i--] = base + info->size - 0x00008000;
info->start[i--] = base + info->size - 0x0000C000;
info->start[i--] = base + info->size - 0x00010000;
for (; i >= 0; i--) {
info->start[i] = base + i * 0x00020000;
}
}
}
#endif /* 0 */
/*-----------------------------------------------------------------------
*/
void
flash_print_info(flash_info_t *info)
flash_print_info (flash_info_t *info)
{
int i;
@@ -391,6 +279,14 @@ flash_print_info(flash_info_t *info)
switch (info->flash_id & FLASH_TYPEMASK) {
case FLASH_28F320J5: printf ("28F320J5 (32 Mbit, 2 x 16bit)\n");
break;
case FLASH_28F640J5: printf ("28F640J5 (64 Mbit, 2 x 16bit)\n");
break;
case FLASH_28F320J3A: printf ("28F320J3A (32 Mbit, 2 x 16bit)\n");
break;
case FLASH_28F640J3A: printf ("28F640J3A (64 Mbit, 2 x 16bit)\n");
break;
case FLASH_28F128J3A: printf ("28F320J3A (128 Mbit, 2 x 16bit)\n");
break;
default: printf ("Unknown Chip Type\n");
break;
}
@@ -411,157 +307,25 @@ flash_print_info(flash_info_t *info)
return;
}
/*-----------------------------------------------------------------------
*/
/*
* The following code cannot be run from FLASH!
*/
#if 0
static ulong
flash_get_size(vu_long *addr, flash_info_t *info)
{
short i;
ulong value;
ulong base = (ulong)addr;
/* Write auto select command: read Manufacturer ID */
addr[0x0555] = 0x00AA00AA;
addr[0x02AA] = 0x00550055;
addr[0x0555] = 0x00900090;
value = addr[0];
switch (value) {
case AMD_MANUFACT:
info->flash_id = FLASH_MAN_AMD;
break;
case FUJ_MANUFACT:
info->flash_id = FLASH_MAN_FUJ;
break;
default:
info->flash_id = FLASH_UNKNOWN;
info->sector_count = 0;
info->size = 0;
return (0); /* no or unknown flash */
}
value = addr[1]; /* device ID */
switch (value) {
case AMD_ID_LV400T:
info->flash_id += FLASH_AM400T;
info->sector_count = 11;
info->size = 0x00100000;
break; /* => 1 MB */
case AMD_ID_LV400B:
info->flash_id += FLASH_AM400B;
info->sector_count = 11;
info->size = 0x00100000;
break; /* => 1 MB */
case AMD_ID_LV800T:
info->flash_id += FLASH_AM800T;
info->sector_count = 19;
info->size = 0x00200000;
break; /* => 2 MB */
case AMD_ID_LV800B:
info->flash_id += FLASH_AM800B;
info->sector_count = 19;
info->size = 0x00200000;
break; /* => 2 MB */
case AMD_ID_LV160T:
info->flash_id += FLASH_AM160T;
info->sector_count = 35;
info->size = 0x00400000;
break; /* => 4 MB */
case AMD_ID_LV160B:
info->flash_id += FLASH_AM160B;
info->sector_count = 35;
info->size = 0x00400000;
break; /* => 4 MB */
#if 0 /* enable when device IDs are available */
case AMD_ID_LV320T:
info->flash_id += FLASH_AM320T;
info->sector_count = 67;
info->size = 0x00800000;
break; /* => 8 MB */
case AMD_ID_LV320B:
info->flash_id += FLASH_AM320B;
info->sector_count = 67;
info->size = 0x00800000;
break; /* => 8 MB */
#endif
default:
info->flash_id = FLASH_UNKNOWN;
return (0); /* => no or unknown flash */
}
/* set up sector start adress table */
if (info->flash_id & FLASH_BTYPE) {
/* set sector offsets for bottom boot block type */
info->start[0] = base + 0x00000000;
info->start[1] = base + 0x00008000;
info->start[2] = base + 0x0000C000;
info->start[3] = base + 0x00010000;
for (i = 4; i < info->sector_count; i++) {
info->start[i] = base + (i * 0x00020000) - 0x00060000;
}
} else {
/* set sector offsets for top boot block type */
i = info->sector_count - 1;
info->start[i--] = base + info->size - 0x00008000;
info->start[i--] = base + info->size - 0x0000C000;
info->start[i--] = base + info->size - 0x00010000;
for (; i >= 0; i--) {
info->start[i] = base + i * 0x00020000;
}
}
/* check for protected sectors */
for (i = 0; i < info->sector_count; i++) {
/* read sector protection at sector address, (A7 .. A0) = 0x02 */
/* D0 = 1 if protected */
addr = (volatile unsigned long *)(info->start[i]);
info->protect[i] = addr[2] & 1;
}
/*
* Prevent writes to uninitialized FLASH.
*/
if (info->flash_id != FLASH_UNKNOWN) {
addr = (volatile unsigned long *)info->start[0];
*addr = 0x00F000F0; /* reset bank */
}
return (info->size);
}
#endif /* 0 */
/*-----------------------------------------------------------------------
*/
int
flash_erase(flash_info_t *info, int s_first, int s_last)
flash_erase (flash_info_t *info, int s_first, int s_last)
{
int prot, sect, haderr;
ulong start, now, last;
int rcode = 0;
#ifdef FLASH_DEBUG
printf("\nflash_erase: erase %d sectors (%d to %d incl.) from\n"
printf ("\nflash_erase: erase %d sectors (%d to %d incl.) from\n"
" Bank # %d: ", s_last - s_first + 1, s_first, s_last,
(info - flash_info) + 1);
flash_print_info(info);
flash_print_info (info);
#endif
if ((s_first < 0) || (s_first > s_last)) {
@@ -574,14 +338,14 @@ flash_erase(flash_info_t *info, int s_first, int s_last)
}
prot = 0;
for (sect=s_first; sect<=s_last; ++sect) {
for (sect = s_first; sect <= s_last; ++sect) {
if (info->protect[sect]) {
prot++;
}
}
if (prot) {
printf("- Warning: %d protected sector%s will not be erased!\n",
printf ("- Warning: %d protected sector%s will not be erased\n",
prot, (prot > 1 ? "s" : ""));
}
@@ -594,15 +358,15 @@ flash_erase(flash_info_t *info, int s_first, int s_last)
ulong estart;
int sectdone;
bank_erase_init(info, sect);
bank_erase_init (info, sect);
/* wait at least 80us - let's wait 1 ms */
udelay (1000);
estart = get_timer(start);
estart = get_timer (start);
do {
now = get_timer(start);
now = get_timer (start);
if (now - estart > CFG_FLASH_ERASE_TOUT) {
printf ("Timeout (sect %d)\n", sect);
@@ -619,7 +383,7 @@ flash_erase(flash_info_t *info, int s_first, int s_last)
}
#endif
sectdone = bank_erase_poll(info, sect);
sectdone = bank_erase_poll (info, sect);
if (sectdone < 0) {
haderr = 1;
@@ -642,21 +406,39 @@ flash_erase(flash_info_t *info, int s_first, int s_last)
/* reset to read mode */
for (sect = s_first; sect <= s_last; sect++) {
if (info->protect[sect] == 0) { /* not protected */
bank_reset(info, sect);
bank_reset (info, sect);
}
}
return rcode;
}
/*-----------------------------------------------------------------------
* Write a word to Flash, returns:
* 0 - OK
* 1 - write timeout
* 2 - Flash not erased
* 3 - Program failed
*/
static int
write_word (flash_info_t *info, ulong dest, ulong data)
{
/* Check if Flash is (sufficiently) erased */
if ((*(ulong *)dest & data) != data)
return (2);
return (bank_write_word ((bank_addr_t)dest, (bank_word_t)data));
}
/*-----------------------------------------------------------------------
* Copy memory to flash, returns:
* 0 - OK
* 1 - write timeout
* 2 - Flash not erased
* 3 - Program failed
*/
int
write_buff(flash_info_t *info, uchar *src, ulong addr, ulong cnt)
write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
{
ulong cp, wp, data;
int i, l, rc;
@@ -680,7 +462,7 @@ write_buff(flash_info_t *info, uchar *src, ulong addr, ulong cnt)
data = (data << 8) | (*(uchar *)cp);
}
if ((rc = write_word(info, wp, data)) != 0) {
if ((rc = write_word (info, wp, data)) != 0) {
return (rc);
}
wp += 4;
@@ -694,7 +476,7 @@ write_buff(flash_info_t *info, uchar *src, ulong addr, ulong cnt)
for (i=0; i<4; ++i) {
data = (data << 8) | *src++;
}
if ((rc = write_word(info, wp, data)) != 0) {
if ((rc = write_word (info, wp, data)) != 0) {
return (rc);
}
wp += 4;
@@ -717,28 +499,7 @@ write_buff(flash_info_t *info, uchar *src, ulong addr, ulong cnt)
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)
{
int retval;
/* Check if Flash is (sufficiently) erased */
if ((*(ulong *)dest & data) != data) {
return (2);
}
retval = bank_write_word((bank_addr_t)dest, (bank_word_t)data);
return (retval);
return (write_word (info, wp, data));
}
/*-----------------------------------------------------------------------

View File

@@ -1,163 +1,156 @@
/*************** DEFINES for Intel StrataFlash FLASH chip ********************/
/*
* acceptable chips types are:
* (C) Copyright 2000
* Murray Jensen, CSIRO-MIT, <Murray.Jensen@csiro.au>
*
* 28F320J5, 28F640J5, 28F320J3A, 28F640J3A and 28F128J3A
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
/* register addresses, valid only following an CHIP_CMD_RD_ID command */
#define CHIP_ADDR_REG_MAN 0x000000 /* manufacturer's id */
#define CHIP_ADDR_REG_DEV 0x000001 /* device id */
#define CHIP_ADDR_REG_CFGM 0x000003 /* master lock config */
#define CHIP_ADDR_REG_CFG(b) (((b)<<16)|2) /* lock config for block b */
/*************** DEFINES for Intel StrataFlash FLASH chip ********************/
/* Commands */
#define CHIP_CMD_RST 0xFF /* reset flash */
#define CHIP_CMD_RD_ID 0x90 /* read the id and lock bits */
#define CHIP_CMD_RD_QUERY 0x98 /* read device capabilities */
#define CHIP_CMD_RD_STAT 0x70 /* read the status register */
#define CHIP_CMD_CLR_STAT 0x50 /* clear the staus register */
#define CHIP_CMD_WR_BUF 0xE8 /* clear the staus register */
#define CHIP_CMD_PROG 0x40 /* program word command */
#define CHIP_CMD_ERASE1 0x20 /* 1st word for block erase */
#define CHIP_CMD_ERASE2 0xD0 /* 2nd word for block erase */
#define CHIP_CMD_ERASE_SUSP 0xB0 /* suspend block erase */
#define CHIP_CMD_LOCK 0x60 /* 1st word for all lock cmds */
#define CHIP_CMD_SET_LOCK_BLK 0x01 /* 2nd wrd set block lock bit */
#define CHIP_CMD_SET_LOCK_MSTR 0xF1 /* 2nd wrd set master lck bit */
#define CHIP_CMD_CLR_LOCK_BLK 0xD0 /* 2nd wrd clear blk lck bit */
#define ISF_CMD_RST 0xFF /* reset flash */
#define ISF_CMD_RD_ID 0x90 /* read the id and lock bits */
#define ISF_CMD_RD_QUERY 0x98 /* read device capabilities */
#define ISF_CMD_RD_STAT 0x70 /* read the status register */
#define ISF_CMD_CLR_STAT 0x50 /* clear the staus register */
#define ISF_CMD_WR_BUF 0xE8 /* clear the staus register */
#define ISF_CMD_PROG 0x40 /* program word command */
#define ISF_CMD_ERASE1 0x20 /* 1st word for block erase */
#define ISF_CMD_ERASE2 0xD0 /* 2nd word for block erase */
#define ISF_CMD_ERASE_SUSP 0xB0 /* suspend block erase */
#define ISF_CMD_LOCK 0x60 /* 1st word for all lock cmds */
#define ISF_CMD_SET_LOCK_BLK 0x01 /* 2nd wrd set block lock bit */
#define ISF_CMD_SET_LOCK_MSTR 0xF1 /* 2nd wrd set master lck bit */
#define ISF_CMD_CLR_LOCK_BLK 0xD0 /* 2nd wrd clear blk lck bit */
/* status register bits */
#define CHIP_STAT_DPS 0x02 /* Device Protect Status */
#define CHIP_STAT_VPPS 0x08 /* VPP Status */
#define CHIP_STAT_PSLBS 0x10 /* Program+Set Lock Bit Stat */
#define CHIP_STAT_ECLBS 0x20 /* Erase+Clr Lock Bit Stat */
#define CHIP_STAT_ESS 0x40 /* Erase Suspend Status */
#define CHIP_STAT_RDY 0x80 /* WSM Mach Status, 1=rdy */
#define ISF_STAT_DPS 0x02 /* Device Protect Status */
#define ISF_STAT_VPPS 0x08 /* VPP Status */
#define ISF_STAT_PSLBS 0x10 /* Program+Set Lock Bit Stat */
#define ISF_STAT_ECLBS 0x20 /* Erase+Clr Lock Bit Stat */
#define ISF_STAT_ESS 0x40 /* Erase Suspend Status */
#define ISF_STAT_RDY 0x80 /* WSM Mach Status, 1=rdy */
#define CHIP_STAT_ERR (CHIP_STAT_VPPS | CHIP_STAT_DPS | \
CHIP_STAT_ECLBS | CHIP_STAT_PSLBS)
#define ISF_STAT_ERR (ISF_STAT_VPPS | ISF_STAT_DPS | \
ISF_STAT_ECLBS | ISF_STAT_PSLBS)
/* ID and Lock Configuration */
#define CHIP_RD_ID_LOCK 0x01 /* Bit 0 of each byte */
#define CHIP_RD_ID_MAN 0x89 /* Manufacturer code = 0x89 */
#define CHIP_RD_ID_DEV CFG_FLASH_ID
/* dimensions */
#define CHIP_WIDTH 2 /* chips are in 16 bit mode */
#define CHIP_WSHIFT 1 /* (log2 of CHIP_WIDTH) */
#define CHIP_NBLOCKS CFG_FLASH_NBLOCKS
#define CHIP_BLKSZ (128 * 1024) /* of 128Kbytes each */
#define CHIP_SIZE (CHIP_BLKSZ * CHIP_NBLOCKS)
/* register addresses, valid only following an ISF_CMD_RD_ID command */
#define ISF_REG_MAN_CODE 0x00 /* manufacturer code */
#define ISF_REG_DEV_CODE 0x01 /* device code */
#define ISF_REG_BLK_LCK 0x02 /* block lock configuration */
#define ISF_REG_MST_LCK 0x03 /* master lock configuration */
/********************** DEFINES for Hymod Flash ******************************/
/*
* The hymod board has 2 x 28F320J5 chips running in
* 16 bit mode, for a 32 bit wide bank.
* this code requires that the flash on any Hymod board appear as a bank
* of two (identical) 16bit Intel StrataFlash chips with 64Kword erase
* sectors (or blocks), running in x16 bit mode and connected side-by-side
* to make a 32-bit wide bus.
*/
typedef unsigned long bank_word_t; /* 8/16/32/64bit unsigned int */
typedef volatile bank_word_t *bank_addr_t;
typedef unsigned long bank_size_t; /* want this big - >= 32 bit */
typedef unsigned long bank_word_t;
typedef bank_word_t bank_blk_t[64 * 1024];
#define BANK_CHIP_WIDTH 2 /* each bank is 2 chips wide */
#define BANK_CHIP_WSHIFT 1 /* (log2 of BANK_CHIP_WIDTH) */
#define BANK_FILL_WORD(b) (((bank_word_t)(b) << 16) | (bank_word_t)(b))
#define BANK_WIDTH (CHIP_WIDTH * BANK_CHIP_WIDTH)
#define BANK_WSHIFT (CHIP_WSHIFT + BANK_CHIP_WSHIFT)
#define BANK_NBLOCKS CHIP_NBLOCKS
#define BANK_BLKSZ (CHIP_BLKSZ * BANK_CHIP_WIDTH)
#define BANK_SIZE (CHIP_SIZE * BANK_CHIP_WIDTH)
#ifdef EXAMPLE
#define MAX_BANKS 1 /* only one bank possible */
/* theoretically the following examples should also work */
/* one flash chip in x8 mode with 128Kword sectors and 8bit bus */
typedef unsigned char bank_word_t;
typedef bank_word_t bank_blk_t[128 * 1024];
#define BANK_FILL_WORD(b) ((bank_word_t)(b))
/* four flash chips in x16 mode with 32Kword sectors and 64bit bus */
typedef unsigned long long bank_word_t;
typedef bank_word_t bank_blk_t[32 * 1024];
#define BANK_FILL_WORD(b) ( \
((bank_word_t)(b) << 48) \
((bank_word_t)(b) << 32) \
((bank_word_t)(b) << 16) \
((bank_word_t)(b) << 0) \
)
#endif /* EXAMPLE */
/* the sizes of these two types should probably be the same */
typedef bank_word_t *bank_addr_t;
typedef unsigned long bank_size_t;
/* align bank addresses and sizes to bank word boundaries */
#define BANK_ADDR_WORD_ALIGN(a) ((bank_addr_t)((bank_size_t)(a) \
& ~(BANK_WIDTH - 1)))
#define BANK_SIZE_WORD_ALIGN(s) ((bank_size_t)BANK_ADDR_WORD_ALIGN( \
(bank_size_t)(s) + (BANK_WIDTH - 1)))
& ~(sizeof (bank_word_t) - 1)))
#define BANK_SIZE_WORD_ALIGN(s) (((bank_size_t)(s) + sizeof (bank_word_t) - 1) \
& ~(sizeof (bank_word_t) - 1))
/* align bank addresses and sizes to bank block boundaries */
#define BANK_ADDR_BLK_ALIGN(a) ((bank_addr_t)((bank_size_t)(a) \
& ~(BANK_BLKSZ - 1)))
#define BANK_SIZE_BLK_ALIGN(s) ((bank_size_t)BANK_ADDR_BLK_ALIGN( \
(bank_size_t)(s) + (BANK_BLKSZ - 1)))
/* align bank addresses and sizes to bank boundaries */
#define BANK_ADDR_BANK_ALIGN(a) ((bank_addr_t)((bank_size_t)(a) \
& ~(BANK_SIZE - 1)))
#define BANK_SIZE_BANK_ALIGN(s) ((bank_size_t)BANK_ADDR_BANK_ALIGN( \
(bank_size_t)(s) + (BANK_SIZE - 1)))
& ~(sizeof (bank_blk_t) - 1)))
#define BANK_SIZE_BLK_ALIGN(s) (((bank_size_t)(s) + sizeof (bank_blk_t) - 1) \
& ~(sizeof (bank_blk_t) - 1))
/* add an offset to a bank address */
#define BANK_ADDR_OFFSET(a, o) (bank_addr_t)((bank_size_t)(a) + \
(bank_size_t)(o))
/* get base address of bank b, given flash base address a */
#define BANK_ADDR_BASE(a, b) BANK_ADDR_OFFSET(BANK_ADDR_BANK_ALIGN(a), \
(bank_size_t)(b) * BANK_SIZE)
#define BANK_ADDR_OFFSET(a, o) ((bank_addr_t)((bank_size_t)(a) + \
(bank_size_t)(o)))
/* adjust a bank address to start of next word, block or bank */
#define BANK_ADDR_NEXT_WORD(a) BANK_ADDR_OFFSET(BANK_ADDR_WORD_ALIGN(a), \
BANK_WIDTH)
sizeof (bank_word_t))
#define BANK_ADDR_NEXT_BLK(a) BANK_ADDR_OFFSET(BANK_ADDR_BLK_ALIGN(a), \
BANK_BLKSZ)
#define BANK_ADDR_NEXT_BANK(a) BANK_ADDR_OFFSET(BANK_ADDR_BANK_ALIGN(a), \
BANK_SIZE)
sizeof (bank_blk_t))
/* get bank address of chip register r given a bank base address a */
#define BANK_ADDR_REG(a, r) BANK_ADDR_OFFSET(BANK_ADDR_BANK_ALIGN(a), \
((bank_size_t)(r) << BANK_WSHIFT))
/* get bank address of register r given a bank base address a and block num b */
#define BANK_ADDR_REG(a, b, r) BANK_ADDR_OFFSET(BANK_ADDR_OFFSET((a), \
(bank_size_t)(b) * sizeof (bank_blk_t)), \
(bank_size_t)(r) * sizeof (bank_word_t))
/* make a bank address for each chip register address */
#define BANK_ADDR_REG_MAN(a) BANK_ADDR_REG((a), CHIP_ADDR_REG_MAN)
#define BANK_ADDR_REG_DEV(a) BANK_ADDR_REG((a), CHIP_ADDR_REG_DEV)
#define BANK_ADDR_REG_CFGM(a) BANK_ADDR_REG((a), CHIP_ADDR_REG_CFGM)
#define BANK_ADDR_REG_CFG(b,a) BANK_ADDR_REG((a), CHIP_ADDR_REG_CFG(b))
/*
* replicate a chip cmd/stat/rd value into each byte position within a word
* so that multiple chips are accessed in a single word i/o operation
*
* this must be as wide as the bank_word_t type, and take into account the
* chip width and bank layout
*/
#define BANK_FILL_WORD(o) ((bank_word_t)( \
((unsigned long)(o) << 16) | \
((unsigned long)(o) << 0) \
))
/* make a bank word value for each chip cmd/stat/rd value */
/* make a bank word value for each StrataFlash value */
/* Commands */
#define BANK_CMD_RST BANK_FILL_WORD(CHIP_CMD_RST)
#define BANK_CMD_RD_ID BANK_FILL_WORD(CHIP_CMD_RD_ID)
#define BANK_CMD_RD_STAT BANK_FILL_WORD(CHIP_CMD_RD_STAT)
#define BANK_CMD_CLR_STAT BANK_FILL_WORD(CHIP_CMD_CLR_STAT)
#define BANK_CMD_ERASE1 BANK_FILL_WORD(CHIP_CMD_ERASE1)
#define BANK_CMD_ERASE2 BANK_FILL_WORD(CHIP_CMD_ERASE2)
#define BANK_CMD_PROG BANK_FILL_WORD(CHIP_CMD_PROG)
#define BANK_CMD_LOCK BANK_FILL_WORD(CHIP_CMD_LOCK)
#define BANK_CMD_SET_LOCK_BLK BANK_FILL_WORD(CHIP_CMD_SET_LOCK_BLK)
#define BANK_CMD_SET_LOCK_MSTR BANK_FILL_WORD(CHIP_CMD_SET_LOCK_MSTR)
#define BANK_CMD_CLR_LOCK_BLK BANK_FILL_WORD(CHIP_CMD_CLR_LOCK_BLK)
#define BANK_CMD_RST BANK_FILL_WORD(ISF_CMD_RST)
#define BANK_CMD_RD_ID BANK_FILL_WORD(ISF_CMD_RD_ID)
#define BANK_CMD_RD_STAT BANK_FILL_WORD(ISF_CMD_RD_STAT)
#define BANK_CMD_CLR_STAT BANK_FILL_WORD(ISF_CMD_CLR_STAT)
#define BANK_CMD_ERASE1 BANK_FILL_WORD(ISF_CMD_ERASE1)
#define BANK_CMD_ERASE2 BANK_FILL_WORD(ISF_CMD_ERASE2)
#define BANK_CMD_PROG BANK_FILL_WORD(ISF_CMD_PROG)
#define BANK_CMD_LOCK BANK_FILL_WORD(ISF_CMD_LOCK)
#define BANK_CMD_SET_LOCK_BLK BANK_FILL_WORD(ISF_CMD_SET_LOCK_BLK)
#define BANK_CMD_SET_LOCK_MSTR BANK_FILL_WORD(ISF_CMD_SET_LOCK_MSTR)
#define BANK_CMD_CLR_LOCK_BLK BANK_FILL_WORD(ISF_CMD_CLR_LOCK_BLK)
/* status register bits */
#define BANK_STAT_DPS BANK_FILL_WORD(CHIP_STAT_DPS)
#define BANK_STAT_PSS BANK_FILL_WORD(CHIP_STAT_PSS)
#define BANK_STAT_VPPS BANK_FILL_WORD(CHIP_STAT_VPPS)
#define BANK_STAT_PSLBS BANK_FILL_WORD(CHIP_STAT_PSLBS)
#define BANK_STAT_ECLBS BANK_FILL_WORD(CHIP_STAT_ECLBS)
#define BANK_STAT_ESS BANK_FILL_WORD(CHIP_STAT_ESS)
#define BANK_STAT_RDY BANK_FILL_WORD(CHIP_STAT_RDY)
#define BANK_STAT_DPS BANK_FILL_WORD(ISF_STAT_DPS)
#define BANK_STAT_PSS BANK_FILL_WORD(ISF_STAT_PSS)
#define BANK_STAT_VPPS BANK_FILL_WORD(ISF_STAT_VPPS)
#define BANK_STAT_PSLBS BANK_FILL_WORD(ISF_STAT_PSLBS)
#define BANK_STAT_ECLBS BANK_FILL_WORD(ISF_STAT_ECLBS)
#define BANK_STAT_ESS BANK_FILL_WORD(ISF_STAT_ESS)
#define BANK_STAT_RDY BANK_FILL_WORD(ISF_STAT_RDY)
#define BANK_STAT_ERR BANK_FILL_WORD(CHIP_STAT_ERR)
#define BANK_STAT_ERR BANK_FILL_WORD(ISF_STAT_ERR)
/* ID and Lock Configuration */
#define BANK_RD_ID_LOCK BANK_FILL_WORD(CHIP_RD_ID_LOCK)
#define BANK_RD_ID_MAN BANK_FILL_WORD(CHIP_RD_ID_MAN)
#define BANK_RD_ID_DEV BANK_FILL_WORD(CHIP_RD_ID_DEV)
/* make a bank register address for each StrataFlash register address */
#define BANK_REG_MAN_CODE(a) BANK_ADDR_REG((a), 0, ISF_REG_MAN_CODE)
#define BANK_REG_DEV_CODE(a) BANK_ADDR_REG((a), 0, ISF_REG_DEV_CODE)
#define BANK_REG_BLK_LCK(a, b) BANK_ADDR_REG((a), (b), ISF_REG_BLK_LCK)
#define BANK_REG_MST_LCK(a) BANK_ADDR_REG((a), 0, ISF_REG_MST_LCK)

View File

@@ -1,3 +1,33 @@
# DONT FORGET TO CHANGE THE "version" VAR BELOW IF YOU MAKE CHANGES TO THIS FILE
# (C) Copyright 2001
# Murray Jensen, CSIRO-MIT, <Murray.Jensen@csiro.au>
#
# See file CREDITS for list of people who contributed to this
# project.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 2 of
# the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
# MA 02111-1307 USA
#
# global_env
#
# file used by Hymod boards to initialise the u-boot non-volatile
# environment when u-boot is first run (it determines this by the
# absence of the environment variable "global_env_loaded")
#
# format of this file is:
#
# 1. blank lines and lines beginning with '#' are ignored
@@ -7,32 +37,94 @@
# %s serial number of the main board (10 digit zero filled)
# %S serial number of the main board (plain number)
# %% a percentage character
#
# no whitespace is removed in either <name> or <value>
# ... otherwise the %x is discarded
#
# if first character in <name> is a dash ('-'), then an existing env var
# will not be overwritten (the dash is removed).
# will not be overwritten (the dash is removed). i.e. it is only set if
# it does not exist
#
# if last character in <name> is a plus ('+'), then <value> will be appended
# to any existing env var (the plus is removed). Duplicates of <value> are
# to any existing env var (the plus is ignored). Duplicates of <value> are
# removed.
#
# similarly, if the last character in <name> is a minus ('-'), then any
# occurences of <value> in the current value of <name> will removed (the
# minus is ignored).
#
# leading and trailing whitespace is removed in both <name> and <value>
# (after processing any initial or final plus/minus in <name>).
#
# MISCELLANEOUS PARAMETERS
# version must always come first
version=4
# set the ip address based on the main board serial number
ipaddr=192.168.1.%S
serverip=192.168.1.254
# stop auto execute after tftp
# stop auto execute after tftp (not a very good name really)
autostart=no
# setting this to "yes" forces the global_env file to be loaded and processed
# if the current version is different to the version in the file
always_check_env=no
# BOOTING COMMANDS AND PARAMETERS
# command to run when "auto-booting"
bootcmd=bootm 40080000
# how long the "countdown" to automatically running "bootcmd" is
bootdelay=2
# how long before it "times out" console input and attempts to run "bootcmd"
bootretry=5
# arguments passed to the boot program (i.e. linux kernel) via register 6
# the linux kernel (v2.4) uses the following registers:
# r3 - address of board information structure
# r4 - address of initial ramdisk image (0 means no initrd)
# r5 - size of initial ramdisk image
# r6 - address of command line string
-bootargs=root=/dev/mtdblock5 rootfstype=squashfs ro
# these four are for hymod linux integrated into our Sun network
bootargs+=serialno=%S
bootargs+=nisclient nisdomain=mlb.dmt.csiro.au nissrvadr=138.194.112.4
bootargs+=nfsclient
bootargs+=automount
# start a web server by default
bootargs+=webserver
# give negotiation time to finish
bootargs+=netsleep=5
# then our ciscos don't pass packets for 25-30 secs after that, so
# pinging the server until it responds prevents network connections
# from failing...
bootargs+=netping
# these are old bootargs - we don't need them anymore
bootargs-=preload=unix,i2c-cpm,i2c-dev
bootargs-=ramdisk_size=32768
bootargs-=ramdisk_size=24576
# FLASH MANIPULATION COMMANDS
#
# 16M flash map, 64 x 256K sectors, mapped at address 0x40000000
# 16M flash, 64 x 256K sectors, mapped at address 0x40000000
#
# sector 0: boot
# sector 1: non volatile environment
# sectors 2-4: linux kernel image
# sectors 5-7: alternate linux kernel image
# sectors 8-63: linux initial ramdisk image
# Sector(s) Address Size Description
#
# 0 - 0 0x40000000 256K boot code
# 1 - 1 0x40040000 256K non volatile environment
# 2 - 4 0x40080000 768K linux kernel image
# 5 - 7 0x40140000 768K alternate linux kernel image
# 8 - 47 0x40200000 10M linux initial ramdisk image
# 48 - 63 0x40c00000 4M ramdisk image for applications
#
fetchboot=tftp 100000 /hymod/u-boot.bin
@@ -49,21 +141,21 @@ newlinux=run fetchlinux eraselinux copylinux cmplinux
fetchaltlinux=tftp 100000 /hymod/altlinux.bin
erasealtlinux=erase 1:5-7
copyaltlinux=cp.b 100000 40080000 $(filesize)
cmpaltlinux=cmp.b 100000 40080000 $(filesize)
copyaltlinux=cp.b 100000 40140000 $(filesize)
cmpaltlinux=cmp.b 100000 40140000 $(filesize)
newaltlinux=run fetchaltlinux erasealtlinux copyaltlinux cmpaltlinux
fetchird=tftp 100000 /hymod/initrd.bin
eraseird=erase 1:8-63
copyird=cp.b 100000 40200000 $(filesize)
cmpird=cmp.b 100000 40200000 $(filesize)
newinitrd=run fetchird eraseird copyird cmpird
fetchroot=tftp 100000 /hymod/root.bin
eraseroot=erase 1:8-47
copyroot=cp.b 100000 40200000 $(filesize)
cmproot=cmp.b 100000 40200000 $(filesize)
newroot=run fetchroot eraseroot copyroot cmproot
bootcmd=bootm 40080000 40200000
-bootargs=root=/dev/ram rw
# these are for hymod linux
bootargs+=preload=unix,i2c-cpm,i2c-dev
bootargs+=serialno=%S
bootargs+=ramdisk_size=32768
bootargs+=automount nisclient nisdomain=mlb.dmt.csiro.au nissrvadr=138.194.112.4
bootdelay=2
fetchard=tftp 100000 /hymod/apprd.bin
eraseard=erase 1:48-63
copyard=cp.b 100000 40c00000 $(filesize)
cmpard=cmp.b 100000 40c00000 $(filesize)
newapprd=run fetchard eraseard copyard cmpard
# pass above map to linux mtd driver
bootargs+=mtdparts=phys:256k(u-boot),256k(u-boot-env),768k(linux),768k(altlinux),10m(root),4m(hymod)

View File

@@ -20,11 +20,12 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*
* Hacked for the Hymod board by Murray.Jensen@cmst.csiro.au, 20-Oct-00
* Hacked for the Hymod board by Murray.Jensen@csiro.au, 20-Oct-00
*/
#include <common.h>
#include <mpc8260.h>
#include <mpc8260_irq.h>
#include <ioports.h>
#include <i2c.h>
#include <asm/iopin_8260.h>
@@ -32,15 +33,11 @@
/* ------------------------------------------------------------------------- */
/* imports from eeprom.c */
extern int eeprom_load (unsigned, hymod_eeprom_t *);
extern int eeprom_fetch (unsigned, char *, ulong);
extern void eeprom_print (hymod_eeprom_t *);
extern int hymod_eeprom_read (int, hymod_eeprom_t *);
extern void hymod_eeprom_print (hymod_eeprom_t *);
/* imports from fetch.c */
extern int fetch_and_parse (char *, ulong, int (*)(uchar *, uchar *));
/* imports from common/main.c */
extern char console_buffer[CFG_CBSIZE];
/* imports from env.c */
extern void hymod_check_env (void);
/* ------------------------------------------------------------------------- */
@@ -54,274 +51,152 @@ extern char console_buffer[CFG_CBSIZE];
const iop_conf_t iop_conf_tab[4][32] = {
/* Port A configuration */
{ /* conf ppar psor pdir podr pdat */
/* PA31 */ {1, 1, 1, 0, 0, 0},
/* FCC1 MII COL */
/* PA30 */ {1, 1, 1, 0, 0, 0},
/* FCC1 MII CRS */
/* PA29 */ {1, 1, 1, 1, 0, 0},
/* FCC1 MII TX_ER */
/* PA28 */ {1, 1, 1, 1, 0, 0},
/* FCC1 MII TX_EN */
/* PA27 */ {1, 1, 1, 0, 0, 0},
/* FCC1 MII RX_DV */
/* PA26 */ {1, 1, 1, 0, 0, 0},
/* FCC1 MII RX_ER */
/* PA25 */ {1, 0, 0, 1, 0, 0},
/* FCC2 MII MDIO */
/* PA24 */ {1, 0, 0, 1, 0, 0},
/* FCC2 MII MDC */
/* PA23 */ {1, 0, 0, 1, 0, 0},
/* FCC3 MII MDIO */
/* PA22 */ {1, 0, 0, 1, 0, 0},
/* FCC3 MII MDC */
/* PA21 */ {1, 1, 0, 1, 0, 0},
/* FCC1 MII TxD[3] */
/* PA20 */ {1, 1, 0, 1, 0, 0},
/* FCC1 MII TxD[2] */
/* PA19 */ {1, 1, 0, 1, 0, 0},
/* FCC1 MII TxD[1] */
/* PA18 */ {1, 1, 0, 1, 0, 0},
/* FCC1 MII TxD[0] */
/* PA17 */ {1, 1, 0, 0, 0, 0},
/* FCC1 MII RxD[3] */
/* PA16 */ {1, 1, 0, 0, 0, 0},
/* FCC1 MII RxD[2] */
/* PA15 */ {1, 1, 0, 0, 0, 0},
/* FCC1 MII RxD[1] */
/* PA14 */ {1, 1, 0, 0, 0, 0},
/* FCC1 MII RxD[0] */
/* PA13 */ {1, 0, 0, 1, 0, 0},
/* FCC1 MII MDIO */
/* PA12 */ {1, 0, 0, 1, 0, 0},
/* FCC1 MII MDC */
/* PA11 */ {1, 0, 0, 1, 0, 0},
/* SEL_CD */
/* PA10 */ {1, 0, 0, 0, 0, 0},
/* FLASH STS1 */
/* PA9 */ {1, 0, 0, 0, 0, 0},
/* FLASH STS0 */
/* PA8 */ {1, 0, 0, 0, 0, 0},
/* FLASH ~PE */
/* PA7 */ {1, 0, 0, 0, 0, 0},
/* WATCH ~HRESET */
/* PA6 */ {1, 0, 0, 0, 1, 0},
/* VC DONE */
/* PA5 */ {1, 0, 0, 1, 1, 0},
/* VC INIT */
/* PA4 */ {1, 0, 0, 1, 0, 0},
/* VC ~PROG */
/* PA3 */ {1, 0, 0, 1, 0, 0},
/* VM ENABLE */
/* PA2 */ {1, 0, 0, 0, 1, 0},
/* VM DONE */
/* PA1 */ {1, 0, 0, 1, 1, 0},
/* VM INIT */
/* PA0 */ {1, 0, 0, 1, 0, 0}
/* VM ~PROG */
},
{
/* cnf par sor dir odr dat */
{ 1, 1, 1, 0, 0, 0 }, /* PA31: FCC1 MII COL */
{ 1, 1, 1, 0, 0, 0 }, /* PA30: FCC1 MII CRS */
{ 1, 1, 1, 1, 0, 0 }, /* PA29: FCC1 MII TX_ER */
{ 1, 1, 1, 1, 0, 0 }, /* PA28: FCC1 MII TX_EN */
{ 1, 1, 1, 0, 0, 0 }, /* PA27: FCC1 MII RX_DV */
{ 1, 1, 1, 0, 0, 0 }, /* PA26: FCC1 MII RX_ER */
{ 1, 0, 0, 1, 0, 0 }, /* PA25: FCC2 MII MDIO */
{ 1, 0, 0, 1, 0, 0 }, /* PA24: FCC2 MII MDC */
{ 1, 0, 0, 1, 0, 0 }, /* PA23: FCC3 MII MDIO */
{ 1, 0, 0, 1, 0, 0 }, /* PA22: FCC3 MII MDC */
{ 1, 1, 0, 1, 0, 0 }, /* PA21: FCC1 MII TxD[3] */
{ 1, 1, 0, 1, 0, 0 }, /* PA20: FCC1 MII TxD[2] */
{ 1, 1, 0, 1, 0, 0 }, /* PA19: FCC1 MII TxD[1] */
{ 1, 1, 0, 1, 0, 0 }, /* PA18: FCC1 MII TxD[0] */
{ 1, 1, 0, 0, 0, 0 }, /* PA17: FCC1 MII RxD[3] */
{ 1, 1, 0, 0, 0, 0 }, /* PA16: FCC1 MII RxD[2] */
{ 1, 1, 0, 0, 0, 0 }, /* PA15: FCC1 MII RxD[1] */
{ 1, 1, 0, 0, 0, 0 }, /* PA14: FCC1 MII RxD[0] */
{ 1, 0, 0, 1, 0, 0 }, /* PA13: FCC1 MII MDIO */
{ 1, 0, 0, 1, 0, 0 }, /* PA12: FCC1 MII MDC */
{ 1, 0, 0, 1, 0, 0 }, /* PA11: SEL_CD */
{ 1, 0, 0, 0, 0, 0 }, /* PA10: FLASH STS1 */
{ 1, 0, 0, 0, 0, 0 }, /* PA09: FLASH STS0 */
{ 1, 0, 0, 0, 0, 0 }, /* PA08: FLASH ~PE */
{ 1, 0, 0, 0, 0, 0 }, /* PA07: WATCH ~HRESET */
{ 1, 0, 0, 0, 1, 0 }, /* PA06: VC DONE */
{ 1, 0, 0, 1, 1, 0 }, /* PA05: VC INIT */
{ 1, 0, 0, 1, 0, 0 }, /* PA04: VC ~PROG */
{ 1, 0, 0, 1, 0, 0 }, /* PA03: VM ENABLE */
{ 1, 0, 0, 0, 1, 0 }, /* PA02: VM DONE */
{ 1, 0, 0, 1, 1, 0 }, /* PA01: VM INIT */
{ 1, 0, 0, 1, 0, 0 } /* PA00: VM ~PROG */
},
/* Port B configuration */
{ /* conf ppar psor pdir podr pdat */
/* PB31 */ {1, 1, 0, 1, 0, 0},
/* FCC2 MII TX_ER */
/* PB30 */ {1, 1, 0, 0, 0, 0},
/* FCC2 MII RX_DV */
/* PB29 */ {1, 1, 1, 1, 0, 0},
/* FCC2 MII TX_EN */
/* PB28 */ {1, 1, 0, 0, 0, 0},
/* FCC2 MII RX_ER */
/* PB27 */ {1, 1, 0, 0, 0, 0},
/* FCC2 MII COL */
/* PB26 */ {1, 1, 0, 0, 0, 0},
/* FCC2 MII CRS */
/* PB25 */ {1, 1, 0, 1, 0, 0},
/* FCC2 MII TxD[3] */
/* PB24 */ {1, 1, 0, 1, 0, 0},
/* FCC2 MII TxD[2] */
/* PB23 */ {1, 1, 0, 1, 0, 0},
/* FCC2 MII TxD[1] */
/* PB22 */ {1, 1, 0, 1, 0, 0},
/* FCC2 MII TxD[0] */
/* PB21 */ {1, 1, 0, 0, 0, 0},
/* FCC2 MII RxD[0] */
/* PB20 */ {1, 1, 0, 0, 0, 0},
/* FCC2 MII RxD[1] */
/* PB19 */ {1, 1, 0, 0, 0, 0},
/* FCC2 MII RxD[2] */
/* PB18 */ {1, 1, 0, 0, 0, 0},
/* FCC2 MII RxD[3] */
/* PB17 */ {1, 1, 0, 0, 0, 0},
/* FCC3 MII RX_DV */
/* PB16 */ {1, 1, 0, 0, 0, 0},
/* FCC3 MII RX_ER */
/* PB15 */ {1, 1, 0, 1, 0, 0},
/* FCC3 MII TX_ER */
/* PB14 */ {1, 1, 0, 1, 0, 0},
/* FCC3 MII TX_EN */
/* PB13 */ {1, 1, 0, 0, 0, 0},
/* FCC3 MII COL */
/* PB12 */ {1, 1, 0, 0, 0, 0},
/* FCC3 MII CRS */
/* PB11 */ {1, 1, 0, 0, 0, 0},
/* FCC3 MII RxD[3] */
/* PB10 */ {1, 1, 0, 0, 0, 0},
/* FCC3 MII RxD[2] */
/* PB9 */ {1, 1, 0, 0, 0, 0},
/* FCC3 MII RxD[1] */
/* PB8 */ {1, 1, 0, 0, 0, 0},
/* FCC3 MII RxD[0] */
/* PB7 */ {1, 1, 0, 1, 0, 0},
/* FCC3 MII TxD[3] */
/* PB6 */ {1, 1, 0, 1, 0, 0},
/* FCC3 MII TxD[2] */
/* PB5 */ {1, 1, 0, 1, 0, 0},
/* FCC3 MII TxD[1] */
/* PB4 */ {1, 1, 0, 1, 0, 0},
/* FCC3 MII TxD[0] */
/* PB3 */ {0, 0, 0, 0, 0, 0},
/* pin doesn't exist */
/* PB2 */ {0, 0, 0, 0, 0, 0},
/* pin doesn't exist */
/* PB1 */ {0, 0, 0, 0, 0, 0},
/* pin doesn't exist */
/* PB0 */ {0, 0, 0, 0, 0, 0}
/* pin doesn't exist */
},
{
/* cnf par sor dir odr dat */
{ 1, 1, 0, 1, 0, 0 }, /* PB31: FCC2 MII TX_ER */
{ 1, 1, 0, 0, 0, 0 }, /* PB30: FCC2 MII RX_DV */
{ 1, 1, 1, 1, 0, 0 }, /* PB29: FCC2 MII TX_EN */
{ 1, 1, 0, 0, 0, 0 }, /* PB28: FCC2 MII RX_ER */
{ 1, 1, 0, 0, 0, 0 }, /* PB27: FCC2 MII COL */
{ 1, 1, 0, 0, 0, 0 }, /* PB26: FCC2 MII CRS */
{ 1, 1, 0, 1, 0, 0 }, /* PB25: FCC2 MII TxD[3] */
{ 1, 1, 0, 1, 0, 0 }, /* PB24: FCC2 MII TxD[2] */
{ 1, 1, 0, 1, 0, 0 }, /* PB23: FCC2 MII TxD[1] */
{ 1, 1, 0, 1, 0, 0 }, /* PB22: FCC2 MII TxD[0] */
{ 1, 1, 0, 0, 0, 0 }, /* PB21: FCC2 MII RxD[0] */
{ 1, 1, 0, 0, 0, 0 }, /* PB20: FCC2 MII RxD[1] */
{ 1, 1, 0, 0, 0, 0 }, /* PB19: FCC2 MII RxD[2] */
{ 1, 1, 0, 0, 0, 0 }, /* PB18: FCC2 MII RxD[3] */
{ 1, 1, 0, 0, 0, 0 }, /* PB17: FCC3 MII RX_DV */
{ 1, 1, 0, 0, 0, 0 }, /* PB16: FCC3 MII RX_ER */
{ 1, 1, 0, 1, 0, 0 }, /* PB15: FCC3 MII TX_ER */
{ 1, 1, 0, 1, 0, 0 }, /* PB14: FCC3 MII TX_EN */
{ 1, 1, 0, 0, 0, 0 }, /* PB13: FCC3 MII COL */
{ 1, 1, 0, 0, 0, 0 }, /* PB12: FCC3 MII CRS */
{ 1, 1, 0, 0, 0, 0 }, /* PB11: FCC3 MII RxD[3] */
{ 1, 1, 0, 0, 0, 0 }, /* PB10: FCC3 MII RxD[2] */
{ 1, 1, 0, 0, 0, 0 }, /* PB09: FCC3 MII RxD[1] */
{ 1, 1, 0, 0, 0, 0 }, /* PB08: FCC3 MII RxD[0] */
{ 1, 1, 0, 1, 0, 0 }, /* PB07: FCC3 MII TxD[3] */
{ 1, 1, 0, 1, 0, 0 }, /* PB06: FCC3 MII TxD[2] */
{ 1, 1, 0, 1, 0, 0 }, /* PB05: FCC3 MII TxD[1] */
{ 1, 1, 0, 1, 0, 0 }, /* PB04: FCC3 MII TxD[0] */
{ 0, 0, 0, 0, 0, 0 }, /* PB03: pin doesn't exist */
{ 0, 0, 0, 0, 0, 0 }, /* PB02: pin doesn't exist */
{ 0, 0, 0, 0, 0, 0 }, /* PB01: pin doesn't exist */
{ 0, 0, 0, 0, 0, 0 } /* PB00: pin doesn't exist */
},
/* Port C */
{ /* conf ppar psor pdir podr pdat */
/* PC31 */ {1, 0, 0, 0, 0, 0},
/* MEZ ~IACK */
/* PC30 */ {0, 0, 0, 0, 0, 0},
/* PC29 */ {1, 1, 0, 0, 0, 0},
/* CLK SCCx */
/* PC28 */ {1, 1, 0, 0, 0, 0},
/* CLK4 */
/* PC27 */ {1, 1, 0, 0, 0, 0},
/* CLK SCCF */
/* PC26 */ {1, 1, 0, 0, 0, 0},
/* CLK 32K */
/* PC25 */ {1, 1, 0, 0, 0, 0},
/* BRG4/CLK7 */
/* PC24 */ {0, 0, 0, 0, 0, 0},
/* PC23 */ {1, 1, 0, 0, 0, 0},
/* CLK SCCx */
/* PC22 */ {1, 1, 0, 0, 0, 0},
/* FCC1 MII RX_CLK */
/* PC21 */ {1, 1, 0, 0, 0, 0},
/* FCC1 MII TX_CLK */
/* PC20 */ {1, 1, 0, 0, 0, 0},
/* CLK SCCF */
/* PC19 */ {1, 1, 0, 0, 0, 0},
/* FCC2 MII RX_CLK */
/* PC18 */ {1, 1, 0, 0, 0, 0},
/* FCC2 MII TX_CLK */
/* PC17 */ {1, 1, 0, 0, 0, 0},
/* FCC3 MII RX_CLK */
/* PC16 */ {1, 1, 0, 0, 0, 0},
/* FCC3 MII TX_CLK */
/* PC15 */ {1, 0, 0, 0, 0, 0},
/* SCC1 UART ~CTS */
/* PC14 */ {1, 0, 0, 0, 0, 0},
/* SCC1 UART ~CD */
/* PC13 */ {1, 0, 0, 0, 0, 0},
/* SCC2 UART ~CTS */
/* PC12 */ {1, 0, 0, 0, 0, 0},
/* SCC2 UART ~CD */
/* PC11 */ {1, 0, 0, 1, 0, 0},
/* SCC1 UART ~DTR */
/* PC10 */ {1, 0, 0, 1, 0, 0},
/* SCC1 UART ~DSR */
/* PC9 */ {1, 0, 0, 1, 0, 0},
/* SCC2 UART ~DTR */
/* PC8 */ {1, 0, 0, 1, 0, 0},
/* SCC2 UART ~DSR */
/* PC7 */ {1, 0, 0, 0, 0, 0},
/* TEMP ~ALERT */
/* PC6 */ {1, 0, 0, 0, 0, 0},
/* FCC3 INT */
/* PC5 */ {1, 0, 0, 0, 0, 0},
/* FCC2 INT */
/* PC4 */ {1, 0, 0, 0, 0, 0},
/* FCC1 INT */
/* PC3 */ {1, 1, 1, 1, 0, 0},
/* SDMA IDMA2 ~DACK */
/* PC2 */ {1, 1, 1, 0, 0, 0},
/* SDMA IDMA2 ~DONE */
/* PC1 */ {1, 1, 0, 0, 0, 0},
/* SDMA IDMA2 ~DREQ */
/* PC0 */ {1, 1, 0, 1, 0, 0}
/* BRG7 */
},
/* Port C configuration */
{
/* cnf par sor dir odr dat */
{ 1, 0, 0, 0, 0, 0 }, /* PC31: MEZ ~IACK */
{ 0, 0, 0, 0, 0, 0 }, /* PC30: ? */
{ 1, 1, 0, 0, 0, 0 }, /* PC29: CLK SCCx */
{ 1, 1, 0, 0, 0, 0 }, /* PC28: CLK4 */
{ 1, 1, 0, 0, 0, 0 }, /* PC27: CLK SCCF */
{ 1, 1, 0, 0, 0, 0 }, /* PC26: CLK 32K */
{ 1, 1, 0, 0, 0, 0 }, /* PC25: BRG4/CLK7 */
{ 0, 0, 0, 0, 0, 0 }, /* PC24: ? */
{ 1, 1, 0, 0, 0, 0 }, /* PC23: CLK SCCx */
{ 1, 1, 0, 0, 0, 0 }, /* PC22: FCC1 MII RX_CLK */
{ 1, 1, 0, 0, 0, 0 }, /* PC21: FCC1 MII TX_CLK */
{ 1, 1, 0, 0, 0, 0 }, /* PC20: CLK SCCF */
{ 1, 1, 0, 0, 0, 0 }, /* PC19: FCC2 MII RX_CLK */
{ 1, 1, 0, 0, 0, 0 }, /* PC18: FCC2 MII TX_CLK */
{ 1, 1, 0, 0, 0, 0 }, /* PC17: FCC3 MII RX_CLK */
{ 1, 1, 0, 0, 0, 0 }, /* PC16: FCC3 MII TX_CLK */
{ 1, 0, 0, 0, 0, 0 }, /* PC15: SCC1 UART ~CTS */
{ 1, 0, 0, 0, 0, 0 }, /* PC14: SCC1 UART ~CD */
{ 1, 0, 0, 0, 0, 0 }, /* PC13: SCC2 UART ~CTS */
{ 1, 0, 0, 0, 0, 0 }, /* PC12: SCC2 UART ~CD */
{ 1, 0, 0, 1, 0, 0 }, /* PC11: SCC1 UART ~DTR */
{ 1, 0, 0, 1, 0, 0 }, /* PC10: SCC1 UART ~DSR */
{ 1, 0, 0, 1, 0, 0 }, /* PC09: SCC2 UART ~DTR */
{ 1, 0, 0, 1, 0, 0 }, /* PC08: SCC2 UART ~DSR */
{ 1, 0, 0, 0, 0, 0 }, /* PC07: TEMP ~ALERT */
{ 1, 0, 0, 0, 0, 0 }, /* PC06: FCC3 INT */
{ 1, 0, 0, 0, 0, 0 }, /* PC05: FCC2 INT */
{ 1, 0, 0, 0, 0, 0 }, /* PC04: FCC1 INT */
{ 0, 1, 1, 1, 0, 0 }, /* PC03: SDMA IDMA2 ~DACK */
{ 0, 1, 1, 0, 0, 0 }, /* PC02: SDMA IDMA2 ~DONE */
{ 0, 1, 0, 0, 0, 0 }, /* PC01: SDMA IDMA2 ~DREQ */
{ 1, 1, 0, 1, 0, 0 } /* PC00: BRG7 */
},
/* Port D */
{ /* conf ppar psor pdir podr pdat */
/* PD31 */ {1, 1, 0, 0, 0, 0},
/* SCC1 UART RxD */
/* PD30 */ {1, 1, 1, 1, 0, 0},
/* SCC1 UART TxD */
/* PD29 */ {1, 0, 0, 1, 0, 0},
/* SCC1 UART ~RTS */
/* PD28 */ {1, 1, 0, 0, 0, 0},
/* SCC2 UART RxD */
/* PD27 */ {1, 1, 0, 1, 0, 0},
/* SCC2 UART TxD */
/* PD26 */ {1, 0, 0, 1, 0, 0},
/* SCC2 UART ~RTS */
/* PD25 */ {1, 0, 0, 0, 0, 0},
/* SCC1 UART ~RI */
/* PD24 */ {1, 0, 0, 0, 0, 0},
/* SCC2 UART ~RI */
/* PD23 */ {1, 0, 0, 1, 0, 0},
/* CLKGEN PD */
/* PD22 */ {1, 0, 0, 0, 0, 0},
/* USER3 */
/* PD21 */ {1, 0, 0, 0, 0, 0},
/* USER2 */
/* PD20 */ {1, 0, 0, 0, 0, 0},
/* USER1 */
/* PD19 */ {1, 1, 1, 0, 0, 0},
/* SPI ~SEL */
/* PD18 */ {1, 1, 1, 0, 0, 0},
/* SPI CLK */
/* PD17 */ {1, 1, 1, 0, 0, 0},
/* SPI MOSI */
/* PD16 */ {1, 1, 1, 0, 0, 0},
/* SPI MISO */
/* PD15 */ {1, 1, 1, 0, 1, 0},
/* I2C SDA */
/* PD14 */ {1, 1, 1, 0, 1, 0},
/* I2C SCL */
/* PD13 */ {1, 0, 0, 1, 0, 1},
/* TEMP ~STDBY */
/* PD12 */ {1, 0, 0, 1, 0, 1},
/* FCC3 ~RESET */
/* PD11 */ {1, 0, 0, 1, 0, 1},
/* FCC2 ~RESET */
/* PD10 */ {1, 0, 0, 1, 0, 1},
/* FCC1 ~RESET */
/* PD9 */ {1, 0, 0, 0, 0, 0},
/* PD9 */
/* PD8 */ {1, 0, 0, 0, 0, 0},
/* PD8 */
/* PD7 */ {1, 0, 0, 1, 0, 1},
/* PD7 */
/* PD6 */ {1, 0, 0, 1, 0, 1},
/* PD6 */
/* PD5 */ {1, 0, 0, 1, 0, 1},
/* PD5 */
/* PD4 */ {1, 0, 0, 1, 0, 1},
/* PD4 */
/* PD3 */ {0, 0, 0, 0, 0, 0},
/* pin doesn't exist */
/* PD2 */ {0, 0, 0, 0, 0, 0},
/* pin doesn't exist */
/* PD1 */ {0, 0, 0, 0, 0, 0},
/* pin doesn't exist */
/* PD0 */ {0, 0, 0, 0, 0, 0}
/* pin doesn't exist */
}
/* Port D configuration */
{
/* cnf par sor dir odr dat */
{ 1, 1, 0, 0, 0, 0 }, /* PD31: SCC1 UART RxD */
{ 1, 1, 1, 1, 0, 0 }, /* PD30: SCC1 UART TxD */
{ 1, 0, 0, 1, 0, 0 }, /* PD29: SCC1 UART ~RTS */
{ 1, 1, 0, 0, 0, 0 }, /* PD28: SCC2 UART RxD */
{ 1, 1, 0, 1, 0, 0 }, /* PD27: SCC2 UART TxD */
{ 1, 0, 0, 1, 0, 0 }, /* PD26: SCC2 UART ~RTS */
{ 1, 0, 0, 0, 0, 0 }, /* PD25: SCC1 UART ~RI */
{ 1, 0, 0, 0, 0, 0 }, /* PD24: SCC2 UART ~RI */
{ 1, 0, 0, 1, 0, 0 }, /* PD23: CLKGEN PD */
{ 1, 0, 0, 0, 0, 0 }, /* PD22: USER3 */
{ 1, 0, 0, 0, 0, 0 }, /* PD21: USER2 */
{ 1, 0, 0, 0, 0, 0 }, /* PD20: USER1 */
{ 1, 1, 1, 0, 0, 0 }, /* PD19: SPI ~SEL */
{ 1, 1, 1, 0, 0, 0 }, /* PD18: SPI CLK */
{ 1, 1, 1, 0, 0, 0 }, /* PD17: SPI MOSI */
{ 1, 1, 1, 0, 0, 0 }, /* PD16: SPI MISO */
{ 1, 1, 1, 0, 1, 0 }, /* PD15: I2C SDA */
{ 1, 1, 1, 0, 1, 0 }, /* PD14: I2C SCL */
{ 1, 0, 0, 1, 0, 1 }, /* PD13: TEMP ~STDBY */
{ 1, 0, 0, 1, 0, 1 }, /* PD12: FCC3 ~RESET */
{ 1, 0, 0, 1, 0, 1 }, /* PD11: FCC2 ~RESET */
{ 1, 0, 0, 1, 0, 1 }, /* PD10: FCC1 ~RESET */
{ 1, 0, 0, 0, 0, 0 }, /* PD09: PD9 */
{ 1, 0, 0, 0, 0, 0 }, /* PD08: PD8 */
{ 1, 0, 0, 1, 0, 1 }, /* PD07: PD7 */
{ 1, 0, 0, 1, 0, 1 }, /* PD06: PD6 */
{ 1, 0, 0, 1, 0, 1 }, /* PD05: PD5 */
{ 1, 0, 0, 1, 0, 1 }, /* PD04: PD4 */
{ 0, 0, 0, 0, 0, 0 }, /* PD03: pin doesn't exist */
{ 0, 0, 0, 0, 0, 0 }, /* PD02: pin doesn't exist */
{ 0, 0, 0, 0, 0, 0 }, /* PD01: pin doesn't exist */
{ 0, 0, 0, 0, 0, 0 } /* PD00: pin doesn't exist */
}
};
/* ------------------------------------------------------------------------- */
@@ -334,17 +209,36 @@ const iop_conf_t iop_conf_tab[4][32] = {
*
* the data is written to the FS6377 via the i2c bus using address in
* "fs6377_addr" (address is 7 bits - R/W bit not included).
*
* The fs6377 has four clock outputs: A, B, C and D.
*
* Outputs C and D can each provide two different clock outputs C1/D1 or
* C2/D2 depending on the state of the SEL_CD input which is connected to
* the MPC8260 I/O port pin PA11. PA11 output (SEL_CD input) low (or 0)
* selects C1/D1 and PA11 output (SEL_CD input) high (or 1) selects C2/D2.
*
* PA11 defaults to output low (or 0) in the i/o port config table above.
*
* Output A provides a 100MHz for the High Speed Serial chips. Output B
* provides a 3.6864MHz clock for more accurate asynchronous serial bit
* rates. Output C is routed to the mezzanine connector but is currently
* unused - both C1 and C2 are set to 16MHz. Output D is used by both the
* alt-input and display mezzanine boards for their video chips. The
* alt-input board requires a clock of 24.576MHz and this is available on
* D1 (PA11=SEL_CD=0). The display board requires a clock of 27MHz and this
* is available on D2 (PA11=SEL_CD=1).
*
* So the default is a clock suitable for the alt-input board. PA11 is toggled
* later in misc_init_r(), if a display board is detected.
*/
uchar fs6377_addr = 0x5c;
uchar fs6377_regs[16] = {
12, 75, 64, 25, 144, 128, 25, 192,
0, 16, 135, 192, 224, 64, 64, 192
12, 75, 64, 25, 144, 128, 25, 192,
0, 16, 135, 192, 224, 64, 64, 192
};
iopin_t pa11 = { IOPIN_PORTA, 11, 0 };
/* ------------------------------------------------------------------------- */
/*
@@ -356,7 +250,8 @@ iopin_t pa11 = { IOPIN_PORTA, 11, 0 };
* the timebase, for udelay())
*/
int board_postclk_init (void)
int
board_postclk_init (void)
{
i2c_init (CFG_I2C_SPEED, CFG_I2C_SLAVE);
@@ -371,7 +266,7 @@ int board_postclk_init (void)
* if this doesn't work
*/
(void) i2c_write (fs6377_addr, 0, 1, fs6377_regs,
sizeof (fs6377_regs));
sizeof (fs6377_regs));
return (0);
}
@@ -382,7 +277,8 @@ int board_postclk_init (void)
* Check Board Identity: Hardwired to HYMOD
*/
int checkboard (void)
int
checkboard (void)
{
puts ("Board: HYMOD\n");
return (0);
@@ -446,7 +342,8 @@ uint upmc_table[] = {
_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_
};
int misc_init_f (void)
int
misc_init_f (void)
{
volatile immap_t *immap = (immap_t *) CFG_IMMR;
volatile memctl8260_t *memctl = &immap->im_memctl;
@@ -465,7 +362,8 @@ int misc_init_f (void)
/* ------------------------------------------------------------------------- */
long initdram (int board_type)
long
initdram (int board_type)
{
volatile immap_t *immap = (immap_t *) CFG_IMMR;
volatile memctl8260_t *memctl = &immap->im_memctl;
@@ -523,280 +421,95 @@ long initdram (int board_type)
/* containing information to be stored in the eeprom from the tftp server */
/* (the file name is based on the serial number and a built-in path) */
/* these are relative to the root of the server's tftp directory */
static char *bddb_cfgdir = "/hymod/bddb";
static char *global_env_path = "/hymod/global_env";
static ulong get_serno (const char *prompt)
{
for (;;) {
int n;
char *p;
ulong serno;
n = readline (prompt);
if (n < 0)
return (0);
if (n == 0)
continue;
serno = simple_strtol (console_buffer, &p, 10);
if (p > console_buffer && *p == '\0')
return (serno);
printf ("Invalid number (%s) - please re-enter\n", console_buffer);
}
}
static int read_eeprom (char *label, unsigned offset, hymod_eeprom_t * ep)
{
char filename[50], prompt[50];
ulong serno;
int count = 0;
sprintf (prompt, "Enter %s board serial number: ", label);
for (;;) {
if (eeprom_load (offset, ep))
return (1);
printf ("*** %s board EEPROM contents are %sinvalid\n",
label, count == 0 ? "" : "STILL ");
puts ("*** will attempt to fetch from server (Ctrl-C to abort)\n");
if ((serno = get_serno (prompt)) == 0) {
puts ("\n*** interrupted! - ignoring eeprom contents\n");
return (0);
}
sprintf (filename, "%s/%010lu.cfg", bddb_cfgdir, serno);
printf ("*** fetching %s board EEPROM contents from server\n",
label);
if (eeprom_fetch (offset, filename, 0x100000) == 0) {
puts ("*** fetch failed - ignoring eeprom contents\n");
return (0);
}
count++;
}
}
static ulong main_serno;
static int env_fetch_callback (uchar * name, uchar * value)
{
char *ov, nv[CFG_CBSIZE], *p, *q, *nn;
int override = 1, append = 0, nl;
nn = name;
if (*nn == '-') {
override = 0;
nn++;
}
if ((nl = strlen (nn)) > 0 && nn[nl - 1] == '+') {
append = 1;
nn[--nl] = '\0';
}
p = value;
q = nv;
while ((*q = *p++) != '\0')
if (*q == '%') {
switch (*p++) {
case '\0': /* whoops - back up */
p--;
break;
case '%': /* a single percent character */
q++;
break;
case 's': /* main board serial number as string */
q += sprintf (q, "%010lu", main_serno);
break;
case 'S': /* main board serial number as number */
q += sprintf (q, "%lu", main_serno);
break;
default: /* ignore any others */
break;
}
} else
q++;
if ((ov = getenv (nn)) != NULL) {
if (append) {
if (strstr (ov, nv) == NULL) {
int ovl, nvl;
printf ("Appending '%s' to env cmd '%s'\n", nv, nn);
ovl = strlen (ov);
nvl = strlen (nv);
while (nvl >= 0) {
nv[ovl + 1 + nvl] = nv[nvl];
nvl--;
}
nv[ovl] = ' ';
while (--ovl >= 0)
nv[ovl] = ov[ovl];
setenv (nn, nv);
}
return (1);
}
if (!override || strcmp (ov, nv) == 0)
return (1);
printf ("Re-setting env cmd '%s' from '%s' to '%s'\n", nn, ov, nv);
} else
printf ("Setting env cmd '%s' to '%s'\n", nn, nv);
setenv (nn, nv);
return (1);
}
int misc_init_r (void)
int
last_stage_init (void)
{
DECLARE_GLOBAL_DATA_PTR;
hymod_conf_t *cp = &gd->bd->bi_hymod_conf;
int rc;
#ifdef CONFIG_BOOT_RETRY_TIME
/*
* we use the readline () function, but we also want
* command timeout enabled
*/
init_cmd_timeout ();
#endif
memset ((void *) cp, 0, sizeof (*cp));
/* set up main board config info */
if (i2c_probe (CFG_I2C_EEPROM_ADDR | HYMOD_EEOFF_MAIN)) {
rc = hymod_eeprom_read (0, &cp->main.eeprom);
if (read_eeprom
("main", HYMOD_EEOFF_MAIN << 8, &cp->main.eeprom))
cp->main.eeprom_valid = 1;
puts ("EEPROM:main...");
if (rc < 0)
puts ("NOT PRESENT\n");
else if (rc == 0)
puts ("INVALID\n");
else {
cp->main.eeprom.valid = 1;
puts ("EEPROM:main...");
printf ("OK (ver %u)\n", cp->main.eeprom.ver);
hymod_eeprom_print (&cp->main.eeprom);
if (cp->main.eeprom_valid) {
printf ("OK (ver %u)\n", cp->main.eeprom.ver);
eeprom_print (&cp->main.eeprom);
main_serno = cp->main.eeprom.serno;
} else
puts ("BAD\n");
/*
* hard-wired assumption here: all hymod main boards will have
* one xilinx fpga, with the interrupt line connected to IRQ2
*
* One day, this might be based on the board type
*/
cp->main.mmap[0].prog.exists = 1;
cp->main.mmap[0].prog.size = FPGA_MAIN_CFG_SIZE;
cp->main.mmap[0].prog.base = FPGA_MAIN_CFG_BASE;
cp->main.xlx[0].mmap.prog.exists = 1;
cp->main.xlx[0].mmap.prog.size = FPGA_MAIN_CFG_SIZE;
cp->main.xlx[0].mmap.prog.base = FPGA_MAIN_CFG_BASE;
cp->main.mmap[0].reg.exists = 1;
cp->main.mmap[0].reg.size = FPGA_MAIN_REG_SIZE;
cp->main.mmap[0].reg.base = FPGA_MAIN_REG_BASE;
cp->main.xlx[0].mmap.reg.exists = 1;
cp->main.xlx[0].mmap.reg.size = FPGA_MAIN_REG_SIZE;
cp->main.xlx[0].mmap.reg.base = FPGA_MAIN_REG_BASE;
cp->main.mmap[0].port.exists = 1;
cp->main.mmap[0].port.size = FPGA_MAIN_PORT_SIZE;
cp->main.mmap[0].port.base = FPGA_MAIN_PORT_BASE;
cp->main.xlx[0].mmap.port.exists = 1;
cp->main.xlx[0].mmap.port.size = FPGA_MAIN_PORT_SIZE;
cp->main.xlx[0].mmap.port.base = FPGA_MAIN_PORT_BASE;
cp->main.iopins[0].prog_pin.port = FPGA_MAIN_PROG_PORT;
cp->main.iopins[0].prog_pin.pin = FPGA_MAIN_PROG_PIN;
cp->main.iopins[0].prog_pin.flag = 1;
cp->main.iopins[0].init_pin.port = FPGA_MAIN_INIT_PORT;
cp->main.iopins[0].init_pin.pin = FPGA_MAIN_INIT_PIN;
cp->main.iopins[0].init_pin.flag = 1;
cp->main.iopins[0].done_pin.port = FPGA_MAIN_DONE_PORT;
cp->main.iopins[0].done_pin.pin = FPGA_MAIN_DONE_PIN;
cp->main.iopins[0].done_pin.flag = 1;
cp->main.xlx[0].iopins.prog_pin.port = FPGA_MAIN_PROG_PORT;
cp->main.xlx[0].iopins.prog_pin.pin = FPGA_MAIN_PROG_PIN;
cp->main.xlx[0].iopins.prog_pin.flag = 1;
cp->main.xlx[0].iopins.init_pin.port = FPGA_MAIN_INIT_PORT;
cp->main.xlx[0].iopins.init_pin.pin = FPGA_MAIN_INIT_PIN;
cp->main.xlx[0].iopins.init_pin.flag = 1;
cp->main.xlx[0].iopins.done_pin.port = FPGA_MAIN_DONE_PORT;
cp->main.xlx[0].iopins.done_pin.pin = FPGA_MAIN_DONE_PIN;
cp->main.xlx[0].iopins.done_pin.flag = 1;
#ifdef FPGA_MAIN_ENABLE_PORT
cp->main.iopins[0].enable_pin.port = FPGA_MAIN_ENABLE_PORT;
cp->main.iopins[0].enable_pin.pin = FPGA_MAIN_ENABLE_PIN;
cp->main.iopins[0].enable_pin.flag = 1;
cp->main.xlx[0].iopins.enable_pin.port = FPGA_MAIN_ENABLE_PORT;
cp->main.xlx[0].iopins.enable_pin.pin = FPGA_MAIN_ENABLE_PIN;
cp->main.xlx[0].iopins.enable_pin.flag = 1;
#endif
} else
puts ("EEPROM:main...NOT PRESENT\n");
cp->main.xlx[0].irq = FPGA_MAIN_IRQ;
}
/* set up mezzanine board config info */
if (i2c_probe (CFG_I2C_EEPROM_ADDR | HYMOD_EEOFF_MEZZ)) {
rc = hymod_eeprom_read (1, &cp->mezz.eeprom);
if (read_eeprom
("mezz", HYMOD_EEOFF_MEZZ << 8, &cp->mezz.eeprom))
cp->mezz.eeprom_valid = 1;
puts ("EEPROM:mezz...");
if (rc < 0)
puts ("NOT PRESENT\n");
else if (rc == 0)
puts ("INVALID\n");
else {
cp->main.eeprom.valid = 1;
puts ("EEPROM:mezz...");
if (cp->mezz.eeprom_valid) {
printf ("OK (ver %u)\n", cp->mezz.eeprom.ver);
eeprom_print (&cp->mezz.eeprom);
} else
puts ("BAD\n");
cp->mezz.mmap[0].prog.exists = 1;
cp->mezz.mmap[0].prog.size = FPGA_MEZZ_CFG_SIZE;
cp->mezz.mmap[0].prog.base = FPGA_MEZZ_CFG_BASE;
cp->mezz.mmap[0].reg.exists = 0;
cp->mezz.mmap[0].port.exists = 0;
cp->mezz.iopins[0].prog_pin.port = FPGA_MEZZ_PROG_PORT;
cp->mezz.iopins[0].prog_pin.pin = FPGA_MEZZ_PROG_PIN;
cp->mezz.iopins[0].prog_pin.flag = 1;
cp->mezz.iopins[0].init_pin.port = FPGA_MEZZ_INIT_PORT;
cp->mezz.iopins[0].init_pin.pin = FPGA_MEZZ_INIT_PIN;
cp->mezz.iopins[0].init_pin.flag = 1;
cp->mezz.iopins[0].done_pin.port = FPGA_MEZZ_DONE_PORT;
cp->mezz.iopins[0].done_pin.pin = FPGA_MEZZ_DONE_PIN;
cp->mezz.iopins[0].done_pin.flag = 1;
#ifdef FPGA_MEZZ_ENABLE_PORT
cp->mezz.iopins[0].enable_pin.port = FPGA_MEZZ_ENABLE_PORT;
cp->mezz.iopins[0].enable_pin.pin = FPGA_MEZZ_ENABLE_PIN;
cp->mezz.iopins[0].enable_pin.flag = 1;
#endif
if (cp->mezz.eeprom_valid &&
cp->mezz.eeprom.bdtype == HYMOD_BDTYPE_DISPLAY) {
/*
* mezzanine board is a display board - switch the SEL_CD
* input of the FS6377 clock generator (via I/O Port Pin PA11) to
* high (or 1) to select the 27MHz required by the display board
*/
iopin_set_high (&pa11);
puts ("SEL_CD:toggled for display board\n");
}
} else
puts ("EEPROM:mezz...NOT PRESENT\n");
cp->crc =
crc32 (0, (unsigned char *) cp, offsetof (hymod_conf_t, crc));
if (getenv ("global_env_loaded") == NULL) {
puts ("*** global environment has not been loaded\n");
puts ("*** fetching from server (Control-C to Abort)\n");
rc = fetch_and_parse (global_env_path, 0x100000,
env_fetch_callback);
if (rc == 0)
puts ("*** Fetch of environment failed!\n");
else
setenv ("global_env_loaded", "yes");
printf ("OK (ver %u)\n", cp->mezz.eeprom.ver);
hymod_eeprom_print (&cp->mezz.eeprom);
}
cp->crc = crc32 (0, (unsigned char *)cp, offsetof (hymod_conf_t, crc));
hymod_check_env ();
return (0);
}

322
board/hymod/hymod.h Normal file
View File

@@ -0,0 +1,322 @@
/*
* (C) Copyright 2001
* Murray Jensen, CSIRO-MIT, <Murray.Jensen@csiro.au>
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public 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 _HYMOD_H_
#define _HYMOD_H_
#include <linux/config.h>
#ifdef CONFIG_8260
#include <asm/iopin_8260.h>
#endif
/*
* hymod configuration data - passed by boot code via the board information
* structure (only U-Boot has support for this at the moment)
*
* there are three types of data passed up from the boot monitor. the first
* (type hymod_eeprom_t) is the eeprom data that was read off both the main
* (or mother) board and the mezzanine board (if any). this data defines how
* many Xilinx fpgas are on each board, and their types (among other things).
* the second type of data (type xlx_mmap_t, one per Xilinx fpga) defines where
* in the physical address space the various Xilinx fpga access regions have
* been mapped by the boot rom. the third type of data (type xlx_iopins_t,
* one per Xilinx fpga) defines which io port pins are connected to the various
* signals required to program a Xilinx fpga.
*
* A ram/flash "bank" refers to memory controlled by the same chip select.
*
* the eeprom contents are defined as in technical note #2 - basically,
* a header, zero or more records in no particular order, and a 32 bit crc
* a record is 1 or more type bytes, a length byte and "length" bytes.
*/
#define HYMOD_EEPROM_ID 0xAA /* eeprom id byte */
#define HYMOD_EEPROM_VER 1 /* eeprom contents version (0-127) */
#define HYMOD_EEPROM_SIZE 256 /* number of bytes in the eeprom */
/* eeprom header */
typedef
struct {
unsigned char id; /* eeprom id byte */
unsigned char :1;
unsigned char ver:7; /* eeprom contents version number */
unsigned long len; /* total # of bytes btw hdr and crc */
}
hymod_eehdr_t;
/* maximum number of bytes available for eeprom data records */
#define HYMOD_EEPROM_MAXLEN (HYMOD_EEPROM_SIZE \
- sizeof (hymod_eehdr_t) \
- sizeof (unsigned long))
/* eeprom data record */
typedef
union {
struct {
unsigned char topbit:1;
unsigned char type:7;
unsigned char len;
unsigned char data[1]; /* variable length */
} small;
struct {
unsigned short topbit:1;
unsigned short nxtbit:1;
unsigned short type:14;
unsigned short len;
unsigned char data[1]; /* variable length */
} medium;
struct {
unsigned long topbit:1;
unsigned long nxtbit:1;
unsigned long type:30;
unsigned long len;
unsigned char data[1]; /* variable length */
} large;
}
hymod_eerec_t;
#define HYMOD_EEOFF_MAIN 0x00 /* i2c addr offset for main eeprom */
#define HYMOD_EEOFF_MEZZ 0x04 /* i2c addr offset for mezz eepomr */
/* eeprom record types */
#define HYMOD_EEREC_SERNO 1 /* serial number */
#define HYMOD_EEREC_DATE 2 /* date */
#define HYMOD_EEREC_BATCH 3 /* batch id */
#define HYMOD_EEREC_TYPE 4 /* board type */
#define HYMOD_EEREC_REV 5 /* revision number */
#define HYMOD_EEREC_SDRAM 6 /* sdram sizes */
#define HYMOD_EEREC_FLASH 7 /* flash sizes */
#define HYMOD_EEREC_ZBT 8 /* zbt ram sizes */
#define HYMOD_EEREC_XLXTYP 9 /* Xilinx fpga types */
#define HYMOD_EEREC_XLXSPD 10 /* Xilinx fpga speeds */
#define HYMOD_EEREC_XLXTMP 11 /* Xilinx fpga temperatures */
#define HYMOD_EEREC_XLXGRD 12 /* Xilinx fpga grades */
#define HYMOD_EEREC_CPUTYP 13 /* Motorola CPU type */
#define HYMOD_EEREC_CPUSPD 14 /* CPU speed */
#define HYMOD_EEREC_BUSSPD 15 /* bus speed */
#define HYMOD_EEREC_CPMSPD 16 /* CPM speed */
#define HYMOD_EEREC_HSTYPE 17 /* high-speed serial chip type */
#define HYMOD_EEREC_HSCHIN 18 /* high-speed serial input channels */
#define HYMOD_EEREC_HSCHOUT 19 /* high-speed serial output channels */
/* some dimensions */
#define HYMOD_MAX_BATCH 32 /* max no. of bytes in batch id */
#define HYMOD_MAX_SDRAM 4 /* max sdram "banks" on any board */
#define HYMOD_MAX_FLASH 4 /* max flash "banks" on any board */
#define HYMOD_MAX_ZBT 16 /* max ZBT rams on any board */
#define HYMOD_MAX_XLX 4 /* max Xilinx fpgas on any board */
#define HYMOD_MAX_BYTES 16 /* enough to store any bytes array */
/* board types */
#define HYMOD_BDTYPE_NONE 0 /* information not present */
#define HYMOD_BDTYPE_IO 1 /* I/O main board */
#define HYMOD_BDTYPE_CLP 2 /* CLP main board */
#define HYMOD_BDTYPE_DSP 3 /* DSP main board */
#define HYMOD_BDTYPE_INPUT 4 /* video input mezzanine board */
#define HYMOD_BDTYPE_ALTINPUT 5 /* video input mezzanine board */
#define HYMOD_BDTYPE_DISPLAY 6 /* video display mezzanine board */
#define HYMOD_BDTYPE_MAX 7 /* first invalid value */
/* Xilinx fpga types */
#define HYMOD_XTYP_NONE 0 /* information not present */
#define HYMOD_XTYP_XCV300E 1 /* Xilinx Virtex 300 */
#define HYMOD_XTYP_XCV400E 2 /* Xilinx Virtex 400 */
#define HYMOD_XTYP_XCV600E 3 /* Xilinx Virtex 600 */
#define HYMOD_XTYP_MAX 4 /* first invalid value */
/* Xilinx fpga speeds */
#define HYMOD_XSPD_NONE 0 /* information not present */
#define HYMOD_XSPD_SIX 1
#define HYMOD_XSPD_SEVEN 2
#define HYMOD_XSPD_EIGHT 3
#define HYMOD_XSPD_MAX 4 /* first invalid value */
/* Xilinx fpga temperatures */
#define HYMOD_XTMP_NONE 0 /* information not present */
#define HYMOD_XTMP_COM 1
#define HYMOD_XTMP_IND 2
#define HYMOD_XTMP_MAX 3 /* first invalid value */
/* Xilinx fpga grades */
#define HYMOD_XTMP_NONE 0 /* information not present */
#define HYMOD_XTMP_NORMAL 1
#define HYMOD_XTMP_ENGSAMP 2
#define HYMOD_XTMP_MAX 3 /* first invalid value */
/* CPU types */
#define HYMOD_CPUTYPE_NONE 0 /* information not present */
#define HYMOD_CPUTYPE_MPC8260 1 /* Motorola MPC8260 embedded powerpc */
#define HYMOD_CPUTYPE_MAX 2 /* first invalid value */
/* CPU/BUS/CPM clock speeds */
#define HYMOD_CLKSPD_NONE 0 /* information not present */
#define HYMOD_CLKSPD_33MHZ 1
#define HYMOD_CLKSPD_66MHZ 2
#define HYMOD_CLKSPD_100MHZ 3
#define HYMOD_CLKSPD_133MHZ 4
#define HYMOD_CLKSPD_166MHZ 5
#define HYMOD_CLKSPD_200MHZ 6
#define HYMOD_CLKSPD_MAX 7 /* first invalid value */
/* high speed serial chip types */
#define HYMOD_HSSTYPE_NONE 0 /* information not present */
#define HYMOD_HSSTYPE_AMCC52064 1
#define HYMOD_HSSTYPE_MAX 2 /* first invalid value */
/* a date (yyyy-mm-dd) */
typedef
struct {
unsigned short year;
unsigned char month;
unsigned char day;
}
hymod_date_t;
/* describes a Xilinx fpga */
typedef
struct {
unsigned char type; /* chip type */
unsigned char speed; /* chip speed rating */
unsigned char temp; /* chip temperature rating */
unsigned char grade; /* chip grade */
}
hymod_xlx_t;
/* describes a Motorola embedded processor */
typedef
struct {
unsigned char type; /* CPU type */
unsigned char cpuspd; /* speed of the PowerPC core */
unsigned char busspd; /* speed of the system and 60x bus */
unsigned char cpmspd; /* speed of the CPM co-processor */
}
hymod_mpc_t;
/* info about high-speed (1Gbit) serial interface */
typedef
struct {
unsigned char type; /* high-speed serial chip type */
unsigned char nchin; /* number of input channels mounted */
unsigned char nchout; /* number of output channels mounted */
}
hymod_hss_t;
/*
* this defines the contents of the serial eeprom that exists on every
* hymod board, including mezzanine boards (the serial eeprom will be
* faked for early development boards that don't have one)
*/
typedef
struct {
unsigned char valid:1; /* contents of this struct is valid */
unsigned char ver:7; /* eeprom contents version */
unsigned char bdtype; /* board type */
unsigned char bdrev; /* board revision */
unsigned char batchlen; /* length of batch string below */
unsigned long serno; /* serial number */
hymod_date_t date; /* manufacture date */
unsigned char batch[32]; /* manufacturer specific batch id */
unsigned char nsdram; /* # of ram "banks" */
unsigned char nflash; /* # of flash "banks" */
unsigned char nzbt; /* # of ZBT rams */
unsigned char nxlx; /* # of Xilinx fpgas */
unsigned char sdramsz[HYMOD_MAX_SDRAM]; /* log2 of sdram size */
unsigned char flashsz[HYMOD_MAX_FLASH]; /* log2 of flash size */
unsigned char zbtsz[HYMOD_MAX_ZBT]; /* log2 of ZBT ram size */
hymod_xlx_t xlx[HYMOD_MAX_XLX]; /* Xilinx fpga info */
hymod_mpc_t mpc; /* Motorola MPC CPU info */
hymod_hss_t hss; /* high-speed serial info */
}
hymod_eeprom_t;
/*
* this defines a region in the processor's physical address space
*/
typedef
struct {
unsigned long exists:1; /* 1 if the region exists, 0 if not */
unsigned long size:31; /* size in bytes */
unsigned long base; /* base address */
}
xlx_prgn_t;
/*
* this defines where the various Xilinx fpga access regions are mapped
* into the physical address space of the processor
*/
typedef
struct {
xlx_prgn_t prog; /* program access region */
xlx_prgn_t reg; /* register access region */
xlx_prgn_t port; /* port access region */
}
xlx_mmap_t;
/*
* this defines which 8260 i/o port pins are connected to the various
* signals required for programming a Xilinx fpga
*/
typedef
struct {
iopin_t prog_pin; /* assert for >= 300ns to program */
iopin_t init_pin; /* goes high when fpga is cleared */
iopin_t done_pin; /* goes high when program is done */
iopin_t enable_pin; /* some fpgas need enabling */
}
xlx_iopins_t;
/* all info about one Xilinx chip */
typedef
struct {
xlx_mmap_t mmap;
xlx_iopins_t iopins;
unsigned long irq:8; /* h/w intr req number for this fpga */
}
xlx_info_t;
/* all info about one hymod board */
typedef
struct {
hymod_eeprom_t eeprom;
xlx_info_t xlx[HYMOD_MAX_XLX];
}
hymod_board_t;
/*
* this defines the configuration information of a hymod board-set
* (main board + possible mezzanine board). In future, there may be
* more than one mezzanine board (stackable?) - if so, add a "mezz2"
* field, and so on... or make mezz an array?
*/
typedef
struct {
unsigned long ver:8; /* version control */
hymod_board_t main; /* main board info */
hymod_board_t mezz; /* mezzanine board info */
unsigned long crc; /* ensures kernel and boot prom agree */
}
hymod_conf_t;
#endif /* _HYMOD_H_ */

113
board/hymod/input.c Normal file
View File

@@ -0,0 +1,113 @@
/*
* (C) Copyright 2003
* Murray Jensen, CSIRO-MIT, <Murray.Jensen@csiro.au>
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public 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>
/* imports from common/main.c */
extern char console_buffer[CFG_CBSIZE];
int
hymod_get_serno (const char *prompt)
{
for (;;) {
int n, serno;
char *p;
#ifdef CONFIG_BOOT_RETRY_TIME
reset_cmd_timeout ();
#endif
n = readline (prompt);
if (n < 0)
return (n);
if (n == 0)
continue;
serno = (int) simple_strtol (console_buffer, &p, 10);
if (p > console_buffer && *p == '\0' && serno > 0)
return (serno);
printf ("Invalid number (%s) - please re-enter\n",
console_buffer);
}
}
int
hymod_get_ethaddr (void)
{
for (;;) {
int n;
#ifdef CONFIG_BOOT_RETRY_TIME
reset_cmd_timeout ();
#endif
n = readline ("Enter board ethernet address: ");
if (n < 0)
return (n);
if (n == 0)
continue;
if (n == 17) {
int i;
char *p, *q;
uchar ea[6];
/* see if it looks like an ethernet address */
p = console_buffer;
for (i = 0; i < 6; i++) {
char term = (i == 5 ? '\0' : ':');
ea[i] = simple_strtol (p, &q, 16);
if ((q - p) != 2 || *q++ != term)
break;
p = q;
}
if (i == 6) {
/* it looks ok - set it */
printf ("Setting ethernet addr to %s\n",
console_buffer);
setenv ("ethaddr", console_buffer);
puts ("Remember to do a 'saveenv' to "
"make it permanent\n");
return (0);
}
}
printf ("Invalid ethernet addr (%s) - please re-enter\n",
console_buffer);
}
}

View File

@@ -299,12 +299,6 @@ int misc_init_r (void)
void lcd_logo (bd_t * bd)
{
volatile immap_t *immap = (immap_t *) CFG_IMMR;
FB_INFO_S1D13xxx fb_info;
S1D_INDEX s1dReg;
S1D_VALUE s1dValue;
@@ -328,8 +322,8 @@ void lcd_logo (bd_t * bd)
/**/
/*----------------------------------------------------------------------------- */
memctl = &immr->im_memctl;
/* memctl->memc_or5 = 0xFFC007F0; / * 4 MB 17 WS or externel TA */
/* memctl->memc_br5 = 0x80000801; / * Start at 0x80000000 */
/* memctl->memc_or5 = 0xFFC007F0; / * 4 MB 17 WS or externel TA */
/* memctl->memc_br5 = 0x80000801; / * Start at 0x80000000 */
memctl->memc_or5 = 0xFFC00708; /* 4 MB 17 WS or externel TA */
memctl->memc_br5 = 0x80080801; /* Start at 0x80080000 */

47
board/logodl/Makefile Normal file
View File

@@ -0,0 +1,47 @@
#
# (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 := logodl.o flash.o
SOBJS := memsetup.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
#########################################################################

15
board/logodl/config.mk Normal file
View File

@@ -0,0 +1,15 @@
#
# Linux-Kernel is expected to be at c000'8000, entry c000'8000
#
# we load ourself to c170'0000, the upper 1 MB of second bank
#
# download areas is c800'0000
#
#TEXT_BASE = 0
# FIXME: armboot does only work correctly when being compiled
# # for the addresses _after_ relocation to RAM!! Otherwhise the
# # .bss segment is assumed in flash...
#
TEXT_BASE = 0x083E0000

844
board/logodl/flash.c Normal file
View File

@@ -0,0 +1,844 @@
/*
* (C) 2000 Wolfgang Denk, DENX Software Engineering, wd@denx.de.
* (C) 2003 August Hoeraendl, Logotronic GmbH
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#undef CONFIG_FLASH_16BIT
#include <common.h>
#define FLASH_BANK_SIZE 0x1000000
#define MAIN_SECT_SIZE 0x20000 /* 2x64k = 128k per sector */
flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */
/* NOTE - CONFIG_FLASH_16BIT means the CPU interface is 16-bit, it
* has nothing to do with the flash chip being 8-bit or 16-bit.
*/
#ifdef CONFIG_FLASH_16BIT
typedef unsigned short FLASH_PORT_WIDTH;
typedef volatile unsigned short FLASH_PORT_WIDTHV;
#define FLASH_ID_MASK 0xFFFF
#else
typedef unsigned long FLASH_PORT_WIDTH;
typedef volatile unsigned long FLASH_PORT_WIDTHV;
#define FLASH_ID_MASK 0xFFFFFFFF
#endif
#define FPW FLASH_PORT_WIDTH
#define FPWV FLASH_PORT_WIDTHV
#define ORMASK(size) ((-size) & OR_AM_MSK)
/*-----------------------------------------------------------------------
* Functions
*/
static ulong flash_get_size (FPWV * addr, flash_info_t * info);
static void flash_reset (flash_info_t * info);
static int write_word_intel (flash_info_t * info, FPWV * dest, FPW data);
static int write_word_amd (flash_info_t * info, FPWV * dest, FPW data);
#define write_word(in, de, da) write_word_amd(in, de, da)
static void flash_get_offsets (ulong base, flash_info_t * info);
#ifdef CFG_FLASH_PROTECTION
static void flash_sync_real_protect (flash_info_t * info);
#endif
/*-----------------------------------------------------------------------
* flash_init()
*
* sets up flash_info and returns size of FLASH (bytes)
*/
ulong flash_init (void)
{
int i, j;
ulong size = 0;
for (i = 0; i < CFG_MAX_FLASH_BANKS; i++) {
ulong flashbase = 0;
flash_info[i].flash_id =
(FLASH_MAN_AMD & FLASH_VENDMASK) |
(FLASH_AM640U & FLASH_TYPEMASK);
flash_info[i].size = FLASH_BANK_SIZE;
flash_info[i].sector_count = CFG_MAX_FLASH_SECT;
memset (flash_info[i].protect, 0, CFG_MAX_FLASH_SECT);
switch (i) {
case 0:
flashbase = PHYS_FLASH_1;
break;
case 1:
flashbase = PHYS_FLASH_2;
break;
default:
panic ("configured to many flash banks!\n");
break;
}
for (j = 0; j < flash_info[i].sector_count; j++) {
flash_info[i].start[j] = flashbase + j * MAIN_SECT_SIZE;
}
size += flash_info[i].size;
}
/* Protect monitor and environment sectors
*/
flash_protect (FLAG_PROTECT_SET,
CFG_FLASH_BASE,
CFG_FLASH_BASE + _armboot_end_data - _armboot_start,
&flash_info[0]);
flash_protect (FLAG_PROTECT_SET,
CFG_ENV_ADDR,
CFG_ENV_ADDR + CFG_ENV_SIZE - 1, &flash_info[0]);
return size;
}
/*-----------------------------------------------------------------------
*/
static void flash_reset (flash_info_t * info)
{
FPWV *base = (FPWV *) (info->start[0]);
/* Put FLASH back in read mode */
if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL)
*base = (FPW) 0x00FF00FF; /* Intel Read Mode */
else if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_AMD)
*base = (FPW) 0x00F000F0; /* AMD Read Mode */
}
/*-----------------------------------------------------------------------
*/
static void flash_get_offsets (ulong base, flash_info_t * info)
{
int i;
/* set up sector start address table */
if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL
&& (info->flash_id & FLASH_BTYPE)) {
int bootsect_size; /* number of bytes/boot sector */
int sect_size; /* number of bytes/regular sector */
bootsect_size = 0x00002000 * (sizeof (FPW) / 2);
sect_size = 0x00010000 * (sizeof (FPW) / 2);
/* set sector offsets for bottom boot block type */
for (i = 0; i < 8; ++i) {
info->start[i] = base + (i * bootsect_size);
}
for (i = 8; i < info->sector_count; i++) {
info->start[i] = base + ((i - 7) * sect_size);
}
} else if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_AMD
&& (info->flash_id & FLASH_TYPEMASK) == FLASH_AM640U) {
int sect_size; /* number of bytes/sector */
sect_size = 0x00010000 * (sizeof (FPW) / 2);
/* set up sector start address table (uniform sector type) */
for (i = 0; i < info->sector_count; i++)
info->start[i] = base + (i * sect_size);
}
}
/*-----------------------------------------------------------------------
*/
void flash_print_info (flash_info_t * info)
{
int i;
uchar *boottype;
uchar *bootletter;
uchar *fmt;
uchar botbootletter[] = "B";
uchar topbootletter[] = "T";
uchar botboottype[] = "bottom boot sector";
uchar topboottype[] = "top boot sector";
if (info->flash_id == FLASH_UNKNOWN) {
printf ("missing or unknown FLASH type\n");
return;
}
switch (info->flash_id & FLASH_VENDMASK) {
case FLASH_MAN_AMD:
printf ("AMD ");
break;
case FLASH_MAN_BM:
printf ("BRIGHT MICRO ");
break;
case FLASH_MAN_FUJ:
printf ("FUJITSU ");
break;
case FLASH_MAN_SST:
printf ("SST ");
break;
case FLASH_MAN_STM:
printf ("STM ");
break;
case FLASH_MAN_INTEL:
printf ("INTEL ");
break;
default:
printf ("Unknown Vendor ");
break;
}
/* check for top or bottom boot, if it applies */
if (info->flash_id & FLASH_BTYPE) {
boottype = botboottype;
bootletter = botbootletter;
} else {
boottype = topboottype;
bootletter = topbootletter;
}
switch (info->flash_id & FLASH_TYPEMASK) {
case FLASH_AM640U:
fmt = "29LV641D (64 Mbit, uniform sectors)\n";
break;
case FLASH_28F800C3B:
case FLASH_28F800C3T:
fmt = "28F800C3%s (8 Mbit, %s)\n";
break;
case FLASH_INTEL800B:
case FLASH_INTEL800T:
fmt = "28F800B3%s (8 Mbit, %s)\n";
break;
case FLASH_28F160C3B:
case FLASH_28F160C3T:
fmt = "28F160C3%s (16 Mbit, %s)\n";
break;
case FLASH_INTEL160B:
case FLASH_INTEL160T:
fmt = "28F160B3%s (16 Mbit, %s)\n";
break;
case FLASH_28F320C3B:
case FLASH_28F320C3T:
fmt = "28F320C3%s (32 Mbit, %s)\n";
break;
case FLASH_INTEL320B:
case FLASH_INTEL320T:
fmt = "28F320B3%s (32 Mbit, %s)\n";
break;
case FLASH_28F640C3B:
case FLASH_28F640C3T:
fmt = "28F640C3%s (64 Mbit, %s)\n";
break;
case FLASH_INTEL640B:
case FLASH_INTEL640T:
fmt = "28F640B3%s (64 Mbit, %s)\n";
break;
default:
fmt = "Unknown Chip Type\n";
break;
}
printf (fmt, bootletter, boottype);
printf (" Size: %ld MB in %d Sectors\n",
info->size >> 20, info->sector_count);
printf (" Sector Start Addresses:");
for (i = 0; i < info->sector_count; ++i) {
if ((i % 5) == 0) {
printf ("\n ");
}
printf (" %08lX%s", info->start[i],
info->protect[i] ? " (RO)" : " ");
}
printf ("\n");
}
/*-----------------------------------------------------------------------
*/
/*
* The following code cannot be run from FLASH!
*/
ulong flash_get_size (FPWV * addr, flash_info_t * info)
{
/* Write auto select command: read Manufacturer ID */
/* Write auto select command sequence and test FLASH answer */
addr[0x0555] = (FPW) 0x00AA00AA; /* for AMD, Intel ignores this */
addr[0x02AA] = (FPW) 0x00550055; /* for AMD, Intel ignores this */
addr[0x0555] = (FPW) 0x00900090; /* selects Intel or AMD */
/* The manufacturer codes are only 1 byte, so just use 1 byte.
* This works for any bus width and any FLASH device width.
*/
switch (addr[0] & 0xff) {
case (uchar) AMD_MANUFACT:
info->flash_id = FLASH_MAN_AMD;
break;
case (uchar) INTEL_MANUFACT:
info->flash_id = FLASH_MAN_INTEL;
break;
default:
info->flash_id = FLASH_UNKNOWN;
info->sector_count = 0;
info->size = 0;
break;
}
/* Check 16 bits or 32 bits of ID so work on 32 or 16 bit bus. */
if (info->flash_id != FLASH_UNKNOWN)
switch (addr[1]) {
case (FPW) AMD_ID_LV640U: /* 29LV640 and 29LV641 have same ID */
info->flash_id += FLASH_AM640U;
info->sector_count = 128;
info->size = 0x00800000 * (sizeof (FPW) / 2);
break; /* => 8 or 16 MB */
case (FPW) INTEL_ID_28F800C3B:
info->flash_id += FLASH_28F800C3B;
info->sector_count = 23;
info->size = 0x00100000 * (sizeof (FPW) / 2);
break; /* => 1 or 2 MB */
case (FPW) INTEL_ID_28F800B3B:
info->flash_id += FLASH_INTEL800B;
info->sector_count = 23;
info->size = 0x00100000 * (sizeof (FPW) / 2);
break; /* => 1 or 2 MB */
case (FPW) INTEL_ID_28F160C3B:
info->flash_id += FLASH_28F160C3B;
info->sector_count = 39;
info->size = 0x00200000 * (sizeof (FPW) / 2);
break; /* => 2 or 4 MB */
case (FPW) INTEL_ID_28F160B3B:
info->flash_id += FLASH_INTEL160B;
info->sector_count = 39;
info->size = 0x00200000 * (sizeof (FPW) / 2);
break; /* => 2 or 4 MB */
case (FPW) INTEL_ID_28F320C3B:
info->flash_id += FLASH_28F320C3B;
info->sector_count = 71;
info->size = 0x00400000 * (sizeof (FPW) / 2);
break; /* => 4 or 8 MB */
case (FPW) INTEL_ID_28F320B3B:
info->flash_id += FLASH_INTEL320B;
info->sector_count = 71;
info->size = 0x00400000 * (sizeof (FPW) / 2);
break; /* => 4 or 8 MB */
case (FPW) INTEL_ID_28F640C3B:
info->flash_id += FLASH_28F640C3B;
info->sector_count = 135;
info->size = 0x00800000 * (sizeof (FPW) / 2);
break; /* => 8 or 16 MB */
case (FPW) INTEL_ID_28F640B3B:
info->flash_id += FLASH_INTEL640B;
info->sector_count = 135;
info->size = 0x00800000 * (sizeof (FPW) / 2);
break; /* => 8 or 16 MB */
default:
info->flash_id = FLASH_UNKNOWN;
info->sector_count = 0;
info->size = 0;
return (0); /* => no or unknown flash */
}
flash_get_offsets ((ulong) addr, info);
/* Put FLASH back in read mode */
flash_reset (info);
return (info->size);
}
#ifdef CFG_FLASH_PROTECTION
/*-----------------------------------------------------------------------
*/
static void flash_sync_real_protect (flash_info_t * info)
{
FPWV *addr = (FPWV *) (info->start[0]);
FPWV *sect;
int i;
switch (info->flash_id & FLASH_TYPEMASK) {
case FLASH_28F800C3B:
case FLASH_28F800C3T:
case FLASH_28F160C3B:
case FLASH_28F160C3T:
case FLASH_28F320C3B:
case FLASH_28F320C3T:
case FLASH_28F640C3B:
case FLASH_28F640C3T:
/* check for protected sectors */
*addr = (FPW) 0x00900090;
for (i = 0; i < info->sector_count; i++) {
/* read sector protection at sector address, (A7 .. A0) = 0x02.
* D0 = 1 for each device if protected.
* If at least one device is protected the sector is marked
* protected, but mixed protected and unprotected devices
* within a sector should never happen.
*/
sect = (FPWV *) (info->start[i]);
info->protect[i] = (sect[2] & (FPW) (0x00010001)) ? 1 : 0;
}
/* Put FLASH back in read mode */
flash_reset (info);
break;
case FLASH_AM640U:
default:
/* no hardware protect that we support */
break;
}
}
#endif
/*-----------------------------------------------------------------------
*/
int flash_erase (flash_info_t * info, int s_first, int s_last)
{
FPWV *addr;
int flag, prot, sect;
int intel = (info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL;
ulong start, now, last;
int rcode = 0;
if ((s_first < 0) || (s_first > s_last)) {
if (info->flash_id == FLASH_UNKNOWN) {
printf ("- missing\n");
} else {
printf ("- no sectors to erase\n");
}
return 1;
}
switch (info->flash_id & FLASH_TYPEMASK) {
case FLASH_INTEL800B:
case FLASH_INTEL160B:
case FLASH_INTEL320B:
case FLASH_INTEL640B:
case FLASH_28F800C3B:
case FLASH_28F160C3B:
case FLASH_28F320C3B:
case FLASH_28F640C3B:
case FLASH_AM640U:
break;
case FLASH_UNKNOWN:
default:
printf ("Can't erase unknown flash type %08lx - aborted\n",
info->flash_id);
return 1;
}
prot = 0;
for (sect = s_first; sect <= s_last; ++sect) {
if (info->protect[sect]) {
prot++;
}
}
if (prot) {
printf ("- Warning: %d protected sectors will not be erased!\n",
prot);
} else {
printf ("\n");
}
start = get_timer (0);
last = start;
/* Start erase on unprotected sectors */
for (sect = s_first; sect <= s_last && rcode == 0; sect++) {
if (info->protect[sect] != 0) /* protected, skip it */
continue;
/* Disable interrupts which might cause a timeout here */
flag = disable_interrupts ();
addr = (FPWV *) (info->start[sect]);
if (intel) {
*addr = (FPW) 0x00500050; /* clear status register */
*addr = (FPW) 0x00200020; /* erase setup */
*addr = (FPW) 0x00D000D0; /* erase confirm */
} else {
/* must be AMD style if not Intel */
FPWV *base; /* first address in bank */
base = (FPWV *) (info->start[0]);
base[0x0555] = (FPW) 0x00AA00AA; /* unlock */
base[0x02AA] = (FPW) 0x00550055; /* unlock */
base[0x0555] = (FPW) 0x00800080; /* erase mode */
base[0x0555] = (FPW) 0x00AA00AA; /* unlock */
base[0x02AA] = (FPW) 0x00550055; /* unlock */
*addr = (FPW) 0x00300030; /* erase sector */
}
/* re-enable interrupts if necessary */
if (flag)
enable_interrupts ();
/* wait at least 50us for AMD, 80us for Intel.
* Let's wait 1 ms.
*/
udelay (1000);
while ((*addr & (FPW) 0x00800080) != (FPW) 0x00800080) {
if ((now = get_timer (start)) > CFG_FLASH_ERASE_TOUT) {
printf ("Timeout\n");
if (intel) {
/* suspend erase */
*addr = (FPW) 0x00B000B0;
}
flash_reset (info); /* reset to read mode */
rcode = 1; /* failed */
break;
}
/* show that we're waiting */
if ((now - last) > 1000) { /* every second */
putc ('.');
last = now;
}
}
flash_reset (info); /* reset to read mode */
}
printf (" done\n");
return rcode;
}
/*-----------------------------------------------------------------------
* Copy memory to flash, returns:
* 0 - OK
* 1 - write timeout
* 2 - Flash not erased
*/
int bad_write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
{
FPW data = 0; /* 16 or 32 bit word, matches flash bus width */
int bytes; /* number of bytes to program in current word */
int left; /* number of bytes left to program */
int i, res;
/* printf("write_buff: src: %8p addr %08lx count: %ld\n", src, addr, cnt); */
for (left = cnt, res = 0;
left > 0 && res == 0;
addr += sizeof (data), left -= sizeof (data) - bytes) {
bytes = addr & (sizeof (data) - 1);
addr &= ~(sizeof (data) - 1);
/* combine source and destination data so can program
* an entire word of 16 or 32 bits
*/
for (i = 0; i < sizeof (data); i++) {
data <<= 8;
if (i < bytes || i - bytes >= left)
data += *((uchar *) addr + i);
else
data += *src++;
}
/* write one word to the flash */
switch (info->flash_id & FLASH_VENDMASK) {
case FLASH_MAN_AMD:
res = write_word_amd (info, (FPWV *) addr, data);
break;
case FLASH_MAN_INTEL:
res = write_word_intel (info, (FPWV *) addr, data);
break;
default:
/* unknown flash type, error! */
printf ("missing or unknown FLASH type\n");
res = 1; /* not really a timeout, but gives error */
break;
}
}
return (res);
}
/**
* write_buf: - Copy memory to flash.
*
* @param info:
* @param src: source of copy transaction
* @param addr: where to copy to
* @param cnt: number of bytes to copy
*
* @return error code
*/
int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt)
{
ulong cp, wp;
FPW data;
int l;
int i, rc;
wp = (addr & ~1); /* get lower word aligned address */
/*
* handle unaligned start bytes
*/
if ((l = addr - wp) != 0) {
data = 0;
for (i = 0, cp = wp; i < l; ++i, ++cp) {
data = (data >> 8) | (*(uchar *) cp << 8);
}
for (; i < 2 && cnt > 0; ++i) {
data = (data >> 8) | (*src++ << 8);
--cnt;
++cp;
}
for (; cnt == 0 && i < 2; ++i, ++cp) {
data = (data >> 8) | (*(uchar *) cp << 8);
}
if ((rc = write_word (info, wp, data)) != 0) {
return (rc);
}
wp += 2;
}
/*
* handle word aligned part
*/
while (cnt >= 2) {
/* data = *((vushort*)src); */
data = *((FPW *) src);
if ((rc = write_word (info, wp, data)) != 0) {
return (rc);
}
src += sizeof (FPW);
wp += sizeof (FPW);
cnt -= sizeof (FPW);
}
if (cnt == 0)
return ERR_OK;
/*
* handle unaligned tail bytes
*/
data = 0;
for (i = 0, cp = wp; i < 2 && cnt > 0; ++i, ++cp) {
data = (data >> 8) | (*src++ << 8);
--cnt;
}
for (; i < 2; ++i, ++cp) {
data = (data >> 8) | (*(uchar *) cp << 8);
}
return write_word (info, wp, data);
}
/*-----------------------------------------------------------------------
* Write a word to Flash for AMD FLASH
* A word is 16 or 32 bits, whichever the bus width of the flash bank
* (not an individual chip) is.
*
* returns:
* 0 - OK
* 1 - write timeout
* 2 - Flash not erased
*/
static int write_word_amd (flash_info_t * info, FPWV * dest, FPW data)
{
ulong start;
int flag;
int res = 0; /* result, assume success */
FPWV *base; /* first address in flash bank */
/* Check if Flash is (sufficiently) erased */
if ((*dest & data) != data) {
return (2);
}
base = (FPWV *) (info->start[0]);
/* Disable interrupts which might cause a timeout here */
flag = disable_interrupts ();
base[0x0555] = (FPW) 0x00AA00AA; /* unlock */
base[0x02AA] = (FPW) 0x00550055; /* unlock */
base[0x0555] = (FPW) 0x00A000A0; /* selects program mode */
*dest = data; /* start programming the data */
/* re-enable interrupts if necessary */
if (flag)
enable_interrupts ();
start = get_timer (0);
/* data polling for D7 */
while (res == 0
&& (*dest & (FPW) 0x00800080) != (data & (FPW) 0x00800080)) {
if (get_timer (start) > CFG_FLASH_WRITE_TOUT) {
*dest = (FPW) 0x00F000F0; /* reset bank */
res = 1;
}
}
return (res);
}
/*-----------------------------------------------------------------------
* Write a word to Flash for Intel FLASH
* A word is 16 or 32 bits, whichever the bus width of the flash bank
* (not an individual chip) is.
*
* returns:
* 0 - OK
* 1 - write timeout
* 2 - Flash not erased
*/
static int write_word_intel (flash_info_t * info, FPWV * dest, FPW data)
{
ulong start;
int flag;
int res = 0; /* result, assume success */
/* Check if Flash is (sufficiently) erased */
if ((*dest & data) != data) {
return (2);
}
/* Disable interrupts which might cause a timeout here */
flag = disable_interrupts ();
*dest = (FPW) 0x00500050; /* clear status register */
*dest = (FPW) 0x00FF00FF; /* make sure in read mode */
*dest = (FPW) 0x00400040; /* program setup */
*dest = data; /* start programming the data */
/* re-enable interrupts if necessary */
if (flag)
enable_interrupts ();
start = get_timer (0);
while (res == 0 && (*dest & (FPW) 0x00800080) != (FPW) 0x00800080) {
if (get_timer (start) > CFG_FLASH_WRITE_TOUT) {
*dest = (FPW) 0x00B000B0; /* Suspend program */
res = 1;
}
}
if (res == 0 && (*dest & (FPW) 0x00100010))
res = 1; /* write failed, time out error is close enough */
*dest = (FPW) 0x00500050; /* clear status register */
*dest = (FPW) 0x00FF00FF; /* make sure in read mode */
return (res);
}
#ifdef CFG_FLASH_PROTECTION
/*-----------------------------------------------------------------------
*/
int flash_real_protect (flash_info_t * info, long sector, int prot)
{
int rcode = 0; /* assume success */
FPWV *addr; /* address of sector */
FPW value;
addr = (FPWV *) (info->start[sector]);
switch (info->flash_id & FLASH_TYPEMASK) {
case FLASH_28F800C3B:
case FLASH_28F800C3T:
case FLASH_28F160C3B:
case FLASH_28F160C3T:
case FLASH_28F320C3B:
case FLASH_28F320C3T:
case FLASH_28F640C3B:
case FLASH_28F640C3T:
flash_reset (info); /* make sure in read mode */
*addr = (FPW) 0x00600060L; /* lock command setup */
if (prot)
*addr = (FPW) 0x00010001L; /* lock sector */
else
*addr = (FPW) 0x00D000D0L; /* unlock sector */
flash_reset (info); /* reset to read mode */
/* now see if it really is locked/unlocked as requested */
*addr = (FPW) 0x00900090;
/* read sector protection at sector address, (A7 .. A0) = 0x02.
* D0 = 1 for each device if protected.
* If at least one device is protected the sector is marked
* protected, but return failure. Mixed protected and
* unprotected devices within a sector should never happen.
*/
value = addr[2] & (FPW) 0x00010001;
if (value == 0)
info->protect[sector] = 0;
else if (value == (FPW) 0x00010001)
info->protect[sector] = 1;
else {
/* error, mixed protected and unprotected */
rcode = 1;
info->protect[sector] = 1;
}
if (info->protect[sector] != prot)
rcode = 1; /* failed to protect/unprotect as requested */
/* reload all protection bits from hardware for now */
flash_sync_real_protect (info);
break;
case FLASH_AM640U:
default:
/* no hardware protect that we support */
info->protect[sector] = prot;
break;
}
return rcode;
}
#endif

123
board/logodl/logodl.c Normal file
View File

@@ -0,0 +1,123 @@
/*
* (C) 2002 Kyle Harris <kharris@nexus-tech.net>, Nexus Technologies, Inc.
* (C) 2002 Marius Groeger <mgroeger@sysgo.de>, Sysgo GmbH
* (C) 2003 Robert Schwebel <r.schwebel@pengutronix.de>, Pengutronix
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#include <common.h>
#include <asm/arch/pxa-regs.h>
/**
* board_init: - setup some data structures
*
* @return: 0 in case of success
*/
int board_init (void)
{
DECLARE_GLOBAL_DATA_PTR;
/* memory and cpu-speed are setup before relocation */
/* so we do _nothing_ here */
gd->bd->bi_arch_number = MACH_TYPE_LOGODL;
gd->bd->bi_boot_params = 0x08000100;
gd->bd->bi_baudrate = CONFIG_BAUDRATE;
(*((volatile short*)0x14800000)) = 0xff; /* power on eth0 */
(*((volatile short*)0x14000000)) = 0xff; /* power on uart */
return 0;
}
/**
* dram_init: - setup dynamic RAM
*
* @return: 0 in case of success
*/
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;
}
/**
* logodl_set_led: - switch LEDs on or off
*
* @param led: LED to switch (0,1)
* @param state: switch on (1) or off (0)
*/
void logodl_set_led(int led, int state)
{
switch(led) {
case 0:
if (state==1) {
CFG_LED_A_CR = CFG_LED_A_BIT;
} else if (state==0) {
CFG_LED_A_SR = CFG_LED_A_BIT;
}
break;
case 1:
if (state==1) {
CFG_LED_B_CR = CFG_LED_B_BIT;
} else if (state==0) {
CFG_LED_B_SR = CFG_LED_B_BIT;
}
break;
}
return;
}
/**
* show_boot_progress: - indicate state of the boot process
*
* @param status: Status number - see README for details.
*
* The LOGOTRONIC does only have 2 LEDs, so we switch them on at the most
* important states (1, 5, 15).
*/
void show_boot_progress (int status)
{
/*
switch(status) {
case 1: logodl_set_led(0,1); break;
case 5: logodl_set_led(1,1); break;
case 15: logodl_set_led(2,1); break;
}
*/
logodl_set_led(0, (status & 1)==1);
logodl_set_led(1, (status & 2)==2);
return;
}

438
board/logodl/memsetup.S Normal file
View File

@@ -0,0 +1,438 @@
/*
* Most of this taken from Redboot hal_platform_setup.h with cleanup
*
* NOTE: I haven't clean this up considerably, just enough to get it
* running. See hal_platform_setup.h for the source. See
* board/cradle/memsetup.S for another PXA250 setup that is
* much cleaner.
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#include <config.h>
#include <version.h>
#include <asm/arch/pxa-regs.h>
DRAM_SIZE: .long CFG_DRAM_SIZE
/* wait for coprocessor write complete */
.macro CPWAIT reg
mrc p15,0,\reg,c2,c0,0
mov \reg,\reg
sub pc,pc,#4
.endm
_TEXT_BASE:
.word TEXT_BASE
/*
* Memory setup
*/
.globl memsetup
memsetup:
mov r10, lr
/* Set up GPIO pins first ----------------------------------------- */
ldr r0, =GPSR0
ldr r1, =CFG_GPSR0_VAL
str r1, [r0]
ldr r0, =GPSR1
ldr r1, =CFG_GPSR1_VAL
str r1, [r0]
ldr r0, =GPSR2
ldr r1, =CFG_GPSR2_VAL
str r1, [r0]
ldr r0, =GPCR0
ldr r1, =CFG_GPCR0_VAL
str r1, [r0]
ldr r0, =GPCR1
ldr r1, =CFG_GPCR1_VAL
str r1, [r0]
ldr r0, =GPCR2
ldr r1, =CFG_GPCR2_VAL
str r1, [r0]
ldr r0, =GPDR0
ldr r1, =CFG_GPDR0_VAL
str r1, [r0]
ldr r0, =GPDR1
ldr r1, =CFG_GPDR1_VAL
str r1, [r0]
ldr r0, =GPDR2
ldr r1, =CFG_GPDR2_VAL
str r1, [r0]
ldr r0, =GAFR0_L
ldr r1, =CFG_GAFR0_L_VAL
str r1, [r0]
ldr r0, =GAFR0_U
ldr r1, =CFG_GAFR0_U_VAL
str r1, [r0]
ldr r0, =GAFR1_L
ldr r1, =CFG_GAFR1_L_VAL
str r1, [r0]
ldr r0, =GAFR1_U
ldr r1, =CFG_GAFR1_U_VAL
str r1, [r0]
ldr r0, =GAFR2_L
ldr r1, =CFG_GAFR2_L_VAL
str r1, [r0]
ldr r0, =GAFR2_U
ldr r1, =CFG_GAFR2_U_VAL
str r1, [r0]
ldr r0, =PSSR /* enable GPIO pins */
ldr r1, =CFG_PSSR_VAL
str r1, [r0]
/* ldr r3, =MSC1 / low - bank 2 Lubbock Registers / SRAM */
/* ldr r2, =CFG_MSC1_VAL / high - bank 3 Ethernet Controller */
/* str r2, [r3] / need to set MSC1 before trying to write to the HEX LEDs */
/* ldr r2, [r3] / need to read it back to make sure the value latches (see MSC section of manual) */
/* */
/* ldr r1, =LED_BLANK */
/* mov r0, #0xFF */
/* str r0, [r1] / turn on hex leds */
/* */
/*loop: */
/* */
/* ldr r0, =0xB0070001 */
/* ldr r1, =_LED */
/* str r0, [r1] / hex display */
/* ---------------------------------------------------------------- */
/* Enable memory interface */
/* */
/* The sequence below is based on the recommended init steps */
/* detailed in the Intel PXA250 Operating Systems Developers Guide, */
/* Chapter 10. */
/* ---------------------------------------------------------------- */
/* ---------------------------------------------------------------- */
/* Step 1: Wait for at least 200 microsedonds to allow internal */
/* clocks to settle. Only necessary after hard reset... */
/* FIXME: can be optimized later */
/* ---------------------------------------------------------------- */
ldr r3, =OSCR /* reset the OS Timer Count to zero */
mov r2, #0
str r2, [r3]
ldr r4, =0x300 /* really 0x2E1 is about 200usec, */
/* so 0x300 should be plenty */
1:
ldr r2, [r3]
cmp r4, r2
bgt 1b
mem_init:
ldr r1, =MEMC_BASE /* get memory controller base addr. */
/* ---------------------------------------------------------------- */
/* Step 2a: Initialize Asynchronous static memory controller */
/* ---------------------------------------------------------------- */
/* MSC registers: timing, bus width, mem type */
/* MSC0: nCS(0,1) */
ldr r2, =CFG_MSC0_VAL
str r2, [r1, #MSC0_OFFSET]
ldr r2, [r1, #MSC0_OFFSET] /* read back to ensure */
/* that data latches */
/* MSC1: nCS(2,3) */
ldr r2, =CFG_MSC1_VAL
str r2, [r1, #MSC1_OFFSET]
ldr r2, [r1, #MSC1_OFFSET]
/* MSC2: nCS(4,5) */
ldr r2, =CFG_MSC2_VAL
str r2, [r1, #MSC2_OFFSET]
ldr r2, [r1, #MSC2_OFFSET]
/* ---------------------------------------------------------------- */
/* Step 2b: Initialize Card Interface */
/* ---------------------------------------------------------------- */
/* MECR: Memory Expansion Card Register */
ldr r2, =CFG_MECR_VAL
str r2, [r1, #MECR_OFFSET]
ldr r2, [r1, #MECR_OFFSET]
/* MCMEM0: Card Interface slot 0 timing */
ldr r2, =CFG_MCMEM0_VAL
str r2, [r1, #MCMEM0_OFFSET]
ldr r2, [r1, #MCMEM0_OFFSET]
/* MCMEM1: Card Interface slot 1 timing */
ldr r2, =CFG_MCMEM1_VAL
str r2, [r1, #MCMEM1_OFFSET]
ldr r2, [r1, #MCMEM1_OFFSET]
/* MCATT0: Card Interface Attribute Space Timing, slot 0 */
ldr r2, =CFG_MCATT0_VAL
str r2, [r1, #MCATT0_OFFSET]
ldr r2, [r1, #MCATT0_OFFSET]
/* MCATT1: Card Interface Attribute Space Timing, slot 1 */
ldr r2, =CFG_MCATT1_VAL
str r2, [r1, #MCATT1_OFFSET]
ldr r2, [r1, #MCATT1_OFFSET]
/* MCIO0: Card Interface I/O Space Timing, slot 0 */
ldr r2, =CFG_MCIO0_VAL
str r2, [r1, #MCIO0_OFFSET]
ldr r2, [r1, #MCIO0_OFFSET]
/* MCIO1: Card Interface I/O Space Timing, slot 1 */
ldr r2, =CFG_MCIO1_VAL
str r2, [r1, #MCIO1_OFFSET]
ldr r2, [r1, #MCIO1_OFFSET]
/* ---------------------------------------------------------------- */
/* Step 2c: Write FLYCNFG FIXME: what's that??? */
/* ---------------------------------------------------------------- */
/* test if we run from flash or RAM - RAM/BDI: don't setup RAM */
adr r3, mem_init /* r0 <- current position of code */
ldr r2, =mem_init
cmp r3, r2 /* skip init if in place */
beq initirqs
/* ---------------------------------------------------------------- */
/* Step 2d: Initialize Timing for Sync Memory (SDCLK0) */
/* ---------------------------------------------------------------- */
/* Before accessing MDREFR we need a valid DRI field, so we set */
/* this to power on defaults + DRI field. */
ldr r3, =CFG_MDREFR_VAL
ldr r2, =0xFFF
and r3, r3, r2
ldr r4, =0x03ca4000
orr r4, r4, r3
str r4, [r1, #MDREFR_OFFSET] /* write back MDREFR */
ldr r4, [r1, #MDREFR_OFFSET]
/* ---------------------------------------------------------------- */
/* Step 3: Initialize Synchronous Static Memory (Flash/Peripherals) */
/* ---------------------------------------------------------------- */
/* Initialize SXCNFG register. Assert the enable bits */
/* Write SXMRS to cause an MRS command to all enabled banks of */
/* synchronous static memory. Note that SXLCR need not be written */
/* at this time. */
/* FIXME: we use async mode for now */
/* ---------------------------------------------------------------- */
/* Step 4: Initialize SDRAM */
/* ---------------------------------------------------------------- */
/* Step 4a: assert MDREFR:K?RUN and configure */
/* MDREFR:K1DB2 and MDREFR:K2DB2 as desired. */
ldr r4, =CFG_MDREFR_VAL
str r4, [r1, #MDREFR_OFFSET] /* write back MDREFR */
ldr r4, [r1, #MDREFR_OFFSET]
/* Step 4b: de-assert MDREFR:SLFRSH. */
bic r4, r4, #(MDREFR_SLFRSH)
str r4, [r1, #MDREFR_OFFSET] /* write back MDREFR */
ldr r4, [r1, #MDREFR_OFFSET]
/* Step 4c: assert MDREFR:E1PIN and E0PIO */
orr r4, r4, #(MDREFR_E1PIN|MDREFR_E0PIN)
str r4, [r1, #MDREFR_OFFSET] /* write back MDREFR */
ldr r4, [r1, #MDREFR_OFFSET]
/* Step 4d: write MDCNFG with MDCNFG:DEx deasserted (set to 0), to */
/* configure but not enable each SDRAM partition pair. */
ldr r4, =CFG_MDCNFG_VAL
bic r4, r4, #(MDCNFG_DE0|MDCNFG_DE1)
str r4, [r1, #MDCNFG_OFFSET] /* write back MDCNFG */
ldr r4, [r1, #MDCNFG_OFFSET]
/* Step 4e: Wait for the clock to the SDRAMs to stabilize, */
/* 100..200 µsec. */
ldr r3, =OSCR /* reset the OS Timer Count to zero */
mov r2, #0
str r2, [r3]
ldr r4, =0x300 /* really 0x2E1 is about 200usec, */
/* so 0x300 should be plenty */
1:
ldr r2, [r3]
cmp r4, r2
bgt 1b
/* Step 4f: Trigger a number (usually 8) refresh cycles by */
/* attempting non-burst read or write accesses to disabled */
/* SDRAM, as commonly specified in the power up sequence */
/* documented in SDRAM data sheets. The address(es) used */
/* for this purpose must not be cacheable. */
/* There should 9 writes, since the first write doesn't */
/* trigger a refresh cycle on PXA250. See Intel PXA250 and */
/* PXA210 Processors Specification Update, */
/* Jan 2003, Errata #116, page 30. */
ldr r3, =CFG_DRAM_BASE
str r2, [r3]
str r2, [r3]
str r2, [r3]
str r2, [r3]
str r2, [r3]
str r2, [r3]
str r2, [r3]
str r2, [r3]
str r2, [r3]
/* Step 4g: Write MDCNFG with enable bits asserted */
/* (MDCNFG:DEx set to 1). */
ldr r3, [r1, #MDCNFG_OFFSET]
orr r3, r3, #(MDCNFG_DE0|MDCNFG_DE1)
str r3, [r1, #MDCNFG_OFFSET]
/* Step 4h: Write MDMRS. */
ldr r2, =CFG_MDMRS_VAL
str r2, [r1, #MDMRS_OFFSET]
/* We are finished with Intel's memory controller initialisation */
/* ---------------------------------------------------------------- */
/* Disable (mask) all interrupts at interrupt controller */
/* ---------------------------------------------------------------- */
initirqs:
mov r1, #0 /* clear int. level register (IRQ, not FIQ) */
ldr r2, =ICLR
str r1, [r2]
ldr r2, =ICMR /* mask all interrupts at the controller */
str r1, [r2]
/* ---------------------------------------------------------------- */
/* Clock initialisation */
/* ---------------------------------------------------------------- */
initclks:
/* Disable the peripheral clocks, and set the core clock frequency */
/* (hard-coding at 398.12MHz for now). */
/* Turn Off ALL on-chip peripheral clocks for re-configuration */
/* Note: See label 'ENABLECLKS' for the re-enabling */
ldr r1, =CKEN
mov r2, #0
str r2, [r1]
/* default value in case no valid rotary switch setting is found */
ldr r2, =(CCCR_L27|CCCR_M2|CCCR_N10) /* DEFAULT: {200/200/100} */
/* ... and write the core clock config register */
ldr r1, =CCCR
str r2, [r1]
/* enable the 32Khz oscillator for RTC and PowerManager */
/*
ldr r1, =OSCC
mov r2, #OSCC_OON
str r2, [r1]
*/
/* NOTE: spin here until OSCC.OOK get set, meaning the PLL */
/* has settled. */
60:
ldr r2, [r1]
ands r2, r2, #1
beq 60b
/* ---------------------------------------------------------------- */
/* */
/* ---------------------------------------------------------------- */
/* Save SDRAM size */
ldr r1, =DRAM_SIZE
str r8, [r1]
/* Interrupt init: Mask all interrupts */
ldr r0, =ICMR /* enable no sources */
mov r1, #0
str r1, [r0]
/* FIXME */
#ifndef DEBUG
/*Disable software and data breakpoints */
mov r0,#0
mcr p15,0,r0,c14,c8,0 /* ibcr0 */
mcr p15,0,r0,c14,c9,0 /* ibcr1 */
mcr p15,0,r0,c14,c4,0 /* dbcon */
/*Enable all debug functionality */
mov r0,#0x80000000
mcr p14,0,r0,c10,c0,0 /* dcsr */
#endif
/* ---------------------------------------------------------------- */
/* End memsetup */
/* ---------------------------------------------------------------- */
endmemsetup:
mov pc, lr

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

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

View File

@@ -50,6 +50,14 @@ int board_init (void)
return 0;
}
int board_post_init(void)
{
setenv("stdout", "serial");
setenv("stderr", "serial");
return 0;
}
int dram_init (void)
{
DECLARE_GLOBAL_DATA_PTR;

View File

@@ -9,6 +9,10 @@
* (C) Copyright 2001, Stuart Hughes, Lineo Inc, stuarth@lineo.com
* Added support for the 16M dram simm on the 8260ads boards
*
* (C) Copyright 2003 Arabella Software Ltd.
* Yuli Barcohen <yuli@arabellasw.com>
* Added support for SDRAM DIMMs SPD EEPROM, MII, Ethernet PHY init.
*
* See file CREDITS for list of people who contributed to this
* project.
*

View File

@@ -45,7 +45,11 @@ extern int gunzip (void *, int, unsigned char *, int *);
extern int mem_test(unsigned long start, unsigned long ramsize, int quiet);
#define I2C_BACKUP_ADDR 0x7C00 /* 0x200 bytes for backup */
#if defined(CONFIG_PIP405) || defined(CONFIG_MIP405)
#define IMAGE_SIZE 0x80000
#elif defined(CONFIG_VCMA9)
#define IMAGE_SIZE 0x40000 /* ugly, but it works for now */
#endif
extern flash_info_t flash_info[]; /* info for FLASH chips */

View File

@@ -15,10 +15,10 @@
# Linux-Kernel is expected to be at 3000'8000, entry 3000'8000
# optionally with a ramdisk at 3080'0000
#
# we load ourself to 33F0'0000
# we load ourself to 33F8'0000
#
# download area is 3300'0000
#
TEXT_BASE = 0x33F00000
TEXT_BASE = 0x33F80000

View File

@@ -54,8 +54,10 @@
/* BANK0CON */
#define B0_Tacs 0x0 /* 0clk */
#define B0_Tcos 0x0 /* 0clk */
#define B0_Tacc 0x5 /* 8clk */
#define B0_Tcos 0x1 /* 1clk */
/*#define B0_Tcos 0x0 0clk */
#define B0_Tacc 0x7 /* 14clk */
/*#define B0_Tacc 0x5 8clk */
#define B0_Tcoh 0x0 /* 0clk */
#define B0_Tah 0x0 /* 0clk */
#define B0_Tacp 0x0 /* page mode is not used */
@@ -63,8 +65,10 @@
/* BANK1CON */
#define B1_Tacs 0x0 /* 0clk */
#define B1_Tcos 0x0 /* 0clk */
#define B1_Tacc 0x5 /* 8clk */
#define B1_Tcos 0x1 /* 1clk */
/*#define B1_Tcos 0x0 0clk */
#define B1_Tacc 0x7 /* 14clk */
/*#define B1_Tacc 0x5 8clk */
#define B1_Tcoh 0x0 /* 0clk */
#define B1_Tah 0x0 /* 0clk */
#define B1_Tacp 0x0 /* page mode is not used */

View File

@@ -72,41 +72,46 @@ static inline void delay(unsigned long loops)
int board_init(void)
{
DECLARE_GLOBAL_DATA_PTR;
S3C24X0_CLOCK_POWER * const clk_power = S3C24X0_GetBase_CLOCK_POWER();
S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
/* to reduce PLL lock time, adjust the LOCKTIME register */
rLOCKTIME = 0xFFFFFF;
clk_power->LOCKTIME = 0xFFFFFF;
/* configure MPLL */
rMPLLCON = ((M_MDIV << 12) + (M_PDIV << 4) + M_SDIV);
clk_power->MPLLCON = ((M_MDIV << 12) + (M_PDIV << 4) + M_SDIV);
/* some delay between MPLL and UPLL */
delay (4000);
/* configure UPLL */
rUPLLCON = ((U_M_MDIV << 12) + (U_M_PDIV << 4) + U_M_SDIV);
clk_power->UPLLCON = ((U_M_MDIV << 12) + (U_M_PDIV << 4) + U_M_SDIV);
/* some delay between MPLL and UPLL */
delay (8000);
/* set up the I/O ports */
rGPACON = 0x007FFFFF;
rGPBCON = 0x002AAAAA;
rGPBUP = 0x000002BF;
rGPCCON = 0xAAAAAAAA;
rGPCUP = 0x0000FFFF;
rGPDCON = 0xAAAAAAAA;
rGPDUP = 0x0000FFFF;
rGPECON = 0xAAAAAAAA;
rGPEUP = 0x000037F7;
rGPFCON = 0x00000000;
rGPFUP = 0x00000000;
rGPGCON = 0xFFEAFF5A;
rGPGUP = 0x0000F0DC;
rGPHCON = 0x0028AAAA;
rGPHUP = 0x00000656;
gpio->GPACON = 0x007FFFFF;
gpio->GPBCON = 0x002AAAAA;
gpio->GPBUP = 0x000002BF;
gpio->GPCCON = 0xAAAAAAAA;
gpio->GPCUP = 0x0000FFFF;
gpio->GPDCON = 0xAAAAAAAA;
gpio->GPDUP = 0x0000FFFF;
gpio->GPECON = 0xAAAAAAAA;
gpio->GPEUP = 0x000037F7;
gpio->GPFCON = 0x00000000;
gpio->GPFUP = 0x00000000;
gpio->GPGCON = 0xFFEAFF5A;
gpio->GPGUP = 0x0000F0DC;
gpio->GPHCON = 0x0028AAAA;
gpio->GPHUP = 0x00000656;
/* setup correct IRQ modes for NIC */
rEXTINT2 = (rEXTINT2 & ~(7<<8)) | (4<<8); /* rising edge mode */
gpio->EXTINT2 = (gpio->EXTINT2 & ~(7<<8)) | (4<<8); /* rising edge mode */
/* select USB port 2 to be host or device (fix to host for now) */
gpio->MISCCR |= 0x08;
/* init serial */
gd->baudrate = CONFIG_BAUDRATE;
@@ -135,6 +140,50 @@ int dram_init(void)
return 0;
}
/*
* NAND flash initialization.
*/
#if (CONFIG_COMMANDS & CFG_CMD_NAND)
extern void
nand_probe(ulong physadr);
static inline void NF_Reset(void)
{
int i;
NF_SetCE(NFCE_LOW);
NF_Cmd(0xFF); /* reset command */
for(i = 0; i < 10; i++); /* tWB = 100ns. */
NF_WaitRB(); /* wait 200~500us; */
NF_SetCE(NFCE_HIGH);
}
static inline void NF_Init(void)
{
#define TACLS 0
#define TWRPH0 3
#define TWRPH1 0
NF_Conf((1<<15)|(0<<14)|(0<<13)|(1<<12)|(1<<11)|(TACLS<<8)|(TWRPH0<<4)|(TWRPH1<<0));
//nand->NFCONF = (1<<15)|(1<<14)|(1<<13)|(1<<12)|(1<<11)|(TACLS<<8)|(TWRPH0<<4)|(TWRPH1<<0);
// 1 1 1 1, 1 xxx, r xxx, r xxx
// En 512B 4step ECCR nFCE=H tACLS tWRPH0 tWRPH1
NF_Reset();
}
void
nand_init(void)
{
S3C2410_NAND * const nand = S3C2410_GetBase_NAND();
NF_Init();
printf("NAND flash probing at 0x%.8lX\n", (ulong)nand);
nand_probe((ulong)nand);
}
#endif
/*
* Get some Board/PLD Info
*/
@@ -195,12 +244,12 @@ int checkboard(void)
puts ("### No HW ID - assuming VCMA9");
} else {
b->serial_name[5] = 0;
printf ("%s-%d Rev %c SN: %s", b->serial_name, Get_Board_Config(),
printf ("%s-%d PCB Rev %c SN: %s", b->serial_name, Get_Board_Config(),
Get_Board_PCB(), &b->serial_name[6]);
}
} else {
s[5] = 0;
printf ("%s-%d Rev %c SN: %s", s, Get_Board_Config(), Get_Board_PCB(),
printf ("%s-%d PCB Rev %c SN: %s", s, Get_Board_Config(), Get_Board_PCB(),
&s[6]);
}
printf("\n");
@@ -211,7 +260,7 @@ int checkboard(void)
void print_vcma9_rev(void)
{
printf("Board: VCMA9-%d Rev: %c (PLD Ver: %d, Rev: %d)\n",
printf("Board: VCMA9-%d PCB Rev: %c (PLD Ver: %d, Rev: %d)\n",
Get_Board_Config(), Get_Board_PCB(),
Get_PLD_Version(), Get_PLD_Revision());
}
@@ -245,5 +294,3 @@ void print_vcma9_info(void)
{
print_vcma9_rev();
}

View File

@@ -25,11 +25,97 @@
* Global routines used for VCMA9
*****************************************************************************/
#include <s3c2410.h>
extern int mem_test(unsigned long start, unsigned long ramsize,int mode);
void print_vcma9_info(void);
#if (CONFIG_COMMANDS & CFG_CMD_NAND)
typedef enum {
NFCE_LOW,
NFCE_HIGH
} NFCE_STATE;
static inline void NF_Conf(u16 conf)
{
S3C2410_NAND * const nand = S3C2410_GetBase_NAND();
nand->NFCONF = conf;
}
static inline void NF_Cmd(u8 cmd)
{
S3C2410_NAND * const nand = S3C2410_GetBase_NAND();
nand->NFCMD = cmd;
}
static inline void NF_CmdW(u8 cmd)
{
NF_Cmd(cmd);
udelay(1);
}
static inline void NF_Addr(u8 addr)
{
S3C2410_NAND * const nand = S3C2410_GetBase_NAND();
nand->NFADDR = addr;
}
static inline void NF_SetCE(NFCE_STATE s)
{
S3C2410_NAND * const nand = S3C2410_GetBase_NAND();
switch (s) {
case NFCE_LOW:
nand->NFCONF &= ~(1<<11);
break;
case NFCE_HIGH:
nand->NFCONF |= (1<<11);
break;
}
}
static inline void NF_WaitRB(void)
{
S3C2410_NAND * const nand = S3C2410_GetBase_NAND();
while (!(nand->NFSTAT & (1<<0)));
}
static inline void NF_Write(u8 data)
{
S3C2410_NAND * const nand = S3C2410_GetBase_NAND();
nand->NFDATA = data;
}
static inline u8 NF_Read(void)
{
S3C2410_NAND * const nand = S3C2410_GetBase_NAND();
return(nand->NFDATA);
}
static inline void NF_Init_ECC(void)
{
S3C2410_NAND * const nand = S3C2410_GetBase_NAND();
nand->NFCONF |= (1<<12);
}
static inline u32 NF_Read_ECC(void)
{
S3C2410_NAND * const nand = S3C2410_GetBase_NAND();
return(nand->NFECC);
}
#endif
#define PLD_BASE_ADDRESS 0x2C000100
#define PLD_ID_REG (PLD_BASE_ADDRESS + 0)
@@ -39,5 +125,3 @@ void print_vcma9_info(void);
#define PLD_GPCD_REG (PLD_BASE_ADDRESS + 4)
#define PLD_BOARD_REG (PLD_BASE_ADDRESS + 5)

View File

@@ -46,33 +46,35 @@ extern int do_mdm_init; /* defined in common/main.c */
int board_init (void)
{
DECLARE_GLOBAL_DATA_PTR;
S3C24X0_CLOCK_POWER * const clk_power = S3C24X0_GetBase_CLOCK_POWER();
S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
/* memory and cpu-speed are setup before relocation */
/* change the clock to be 50 MHz 1:1:1 */
rMPLLCON = 0x5c042;
rCLKDIVN = 0;
clk_power->MPLLCON = 0x5c042;
clk_power->CLKDIVN = 0;
/* set up the I/O ports */
rPACON = 0x3ffff;
rPBCON = 0xaaaaaaaa;
rPBUP = 0xffff;
rPECON = 0x0;
rPEUP = 0x0;
gpio->PACON = 0x3ffff;
gpio->PBCON = 0xaaaaaaaa;
gpio->PBUP = 0xffff;
gpio->PECON = 0x0;
gpio->PEUP = 0x0;
#ifdef CONFIG_HWFLOW
/*CTS[0] RTS[0] INPUT INPUT TXD[0] INPUT RXD[0] */
/* 10, 10, 00, 00, 10, 00, 10 */
rPFCON=0xa22;
gpio->PFCON=0xa22;
/* Disable pull-up on Rx, Tx, CTS and RTS pins */
rPFUP=0x35;
gpio->PFUP=0x35;
#else
/*INPUT INPUT INPUT INPUT TXD[0] INPUT RXD[0] */
/* 00, 00, 00, 00, 10, 00, 10 */
rPFCON = 0x22;
gpio->PFCON = 0x22;
/* Disable pull-up on Rx and Tx pins */
rPFUP = 0x5;
gpio->PFUP = 0x5;
#endif /* CONFIG_HWFLOW */
rPGCON = 0x0;
rPGUP = 0x0;
rOPENCR = 0x0;
gpio->PGCON = 0x0;
gpio->PGUP = 0x0;
gpio->OPENCR = 0x0;
/* arch number of SAMSUNG-Board to MACH_TYPE_SMDK2400 */
gd->bd->bi_arch_number = 145;

View File

@@ -16,10 +16,10 @@
# Linux-Kernel is expected to be at 3000'8000, entry 3000'8000
# optionally with a ramdisk at 3080'0000
#
# we load ourself to 33F0'0000
# we load ourself to 33F8'0000
#
# download area is 3300'0000
#
TEXT_BASE = 0x33F00000
TEXT_BASE = 0x33F80000

View File

@@ -68,38 +68,40 @@ static inline void delay (unsigned long loops)
int board_init (void)
{
DECLARE_GLOBAL_DATA_PTR;
S3C24X0_CLOCK_POWER * const clk_power = S3C24X0_GetBase_CLOCK_POWER();
S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
/* to reduce PLL lock time, adjust the LOCKTIME register */
rLOCKTIME = 0xFFFFFF;
clk_power->LOCKTIME = 0xFFFFFF;
/* configure MPLL */
rMPLLCON = ((M_MDIV << 12) + (M_PDIV << 4) + M_SDIV);
clk_power->MPLLCON = ((M_MDIV << 12) + (M_PDIV << 4) + M_SDIV);
/* some delay between MPLL and UPLL */
delay (4000);
/* configure UPLL */
rUPLLCON = ((U_M_MDIV << 12) + (U_M_PDIV << 4) + U_M_SDIV);
clk_power->UPLLCON = ((U_M_MDIV << 12) + (U_M_PDIV << 4) + U_M_SDIV);
/* some delay between MPLL and UPLL */
delay (8000);
/* set up the I/O ports */
rGPACON = 0x007FFFFF;
rGPBCON = 0x00044555;
rGPBUP = 0x000007FF;
rGPCCON = 0xAAAAAAAA;
rGPCUP = 0x0000FFFF;
rGPDCON = 0xAAAAAAAA;
rGPDUP = 0x0000FFFF;
rGPECON = 0xAAAAAAAA;
rGPEUP = 0x0000FFFF;
rGPFCON = 0x000055AA;
rGPFUP = 0x000000FF;
rGPGCON = 0xFF95FFBA;
rGPGUP = 0x0000FFFF;
rGPHCON = 0x002AFAAA;
rGPHUP = 0x000007FF;
gpio->GPACON = 0x007FFFFF;
gpio->GPBCON = 0x00044555;
gpio->GPBUP = 0x000007FF;
gpio->GPCCON = 0xAAAAAAAA;
gpio->GPCUP = 0x0000FFFF;
gpio->GPDCON = 0xAAAAAAAA;
gpio->GPDUP = 0x0000FFFF;
gpio->GPECON = 0xAAAAAAAA;
gpio->GPEUP = 0x0000FFFF;
gpio->GPFCON = 0x000055AA;
gpio->GPFUP = 0x000000FF;
gpio->GPGCON = 0xFF95FFBA;
gpio->GPGUP = 0x0000FFFF;
gpio->GPHCON = 0x002AFAAA;
gpio->GPHUP = 0x000007FF;
/* arch number of SMDK2410-Board */
gd->bd->bi_arch_number = 193;

View File

@@ -25,6 +25,7 @@
#include <common.h>
#include <mpc8xx.h>
#include <environment.h>
#ifndef CFG_ENV_ADDR
#define CFG_ENV_ADDR (CFG_FLASH_BASE + CFG_ENV_OFFSET)
@@ -103,17 +104,41 @@ unsigned long flash_init (void)
#if CFG_MONITOR_BASE >= CFG_FLASH_BASE
/* monitor protection ON by default */
debug ("Protect monitor: %08lx ... %08lx\n",
(ulong)CFG_MONITOR_BASE,
(ulong)CFG_MONITOR_BASE + monitor_flash_len - 1);
flash_protect(FLAG_PROTECT_SET,
CFG_MONITOR_BASE,
CFG_MONITOR_BASE+monitor_flash_len-1,
CFG_MONITOR_BASE + monitor_flash_len - 1,
&flash_info[0]);
#endif
#ifdef CFG_ENV_IS_IN_FLASH
/* ENV protection ON by default */
debug ("Protect %senvironment: %08lx ... %08lx\n",
# ifdef CFG_ENV_ADDR_REDUND
"primary ",
# else
"",
# endif
(ulong)CFG_ENV_ADDR,
(ulong)CFG_ENV_ADDR + CFG_ENV_SECT_SIZE - 1);
flash_protect(FLAG_PROTECT_SET,
CFG_ENV_ADDR,
CFG_ENV_ADDR+CFG_ENV_SIZE-1,
CFG_ENV_ADDR + CFG_ENV_SECT_SIZE - 1,
&flash_info[0]);
#endif
#ifdef CFG_ENV_ADDR_REDUND
debug ("Protect redundand environment: %08lx ... %08lx\n",
(ulong)CFG_ENV_ADDR_REDUND,
(ulong)CFG_ENV_ADDR_REDUND + CFG_ENV_SECT_SIZE - 1);
flash_protect(FLAG_PROTECT_SET,
CFG_ENV_ADDR_REDUND,
CFG_ENV_ADDR_REDUND + CFG_ENV_SECT_SIZE - 1,
&flash_info[0]);
#endif
@@ -181,6 +206,10 @@ void flash_print_info (flash_info_t *info)
}
switch (info->flash_id & FLASH_TYPEMASK) {
#ifdef CONFIG_TQM8xxM /* mirror bit flash */
case FLASH_AMLV128U: printf ("AM29LV128ML (128Mbit, uniform sector size)\n");
break;
# else /* ! TQM8xxM */
case FLASH_AM400B: printf ("AM29LV400B (4 Mbit, bottom boot sect)\n");
break;
case FLASH_AM400T: printf ("AM29LV400T (4 Mbit, top boot sector)\n");
@@ -197,6 +226,7 @@ void flash_print_info (flash_info_t *info)
break;
case FLASH_AM320T: printf ("AM29LV320T (32 Mbit, top boot sector)\n");
break;
#endif /* TQM8xxM */
default: printf ("Unknown Chip Type\n");
break;
}
@@ -262,6 +292,25 @@ static ulong flash_get_size (vu_long *addr, flash_info_t *info)
debug ("Device ID @ 0x%08lx: 0x%08lx\n", (ulong)(&addr[1]), value);
switch (value) {
#ifdef CONFIG_TQM8xxM /* mirror bit flash */
case AMD_ID_MIRROR:
switch(addr[14]) {
case AMD_ID_LV128U_2:
if (addr[15] != AMD_ID_LV128U_3) {
info->flash_id = FLASH_UNKNOWN;
}
else {
info->flash_id += FLASH_AMLV128U;
info->sector_count = 256;
info->size = 0x02000000;
}
break; /* => 32 MB */
default:
info->flash_id = FLASH_UNKNOWN;
break;
}
break;
# else /* ! TQM8xxM */
case AMD_ID_LV400T:
info->flash_id += FLASH_AM400T;
info->sector_count = 11;
@@ -297,6 +346,7 @@ static ulong flash_get_size (vu_long *addr, flash_info_t *info)
info->sector_count = 35;
info->size = 0x00400000;
break; /* => 4 MB */
case AMD_ID_LV320T:
info->flash_id += FLASH_AM320T;
info->sector_count = 71;
@@ -308,12 +358,7 @@ static ulong flash_get_size (vu_long *addr, flash_info_t *info)
info->sector_count = 71;
info->size = 0x00800000;
break; /* => 8 MB */
case AMD_ID_DL640:
debug ("## oops - same ID used for AM29LV128ML/H mirror bit flash ???\n");
info->flash_id += FLASH_AMDL640;
info->sector_count = 142;
info->size = 0x00800000;
break;
#endif /* TQM8xxM */
default:
info->flash_id = FLASH_UNKNOWN;
return (0); /* => no or unknown flash */
@@ -321,6 +366,19 @@ debug ("## oops - same ID used for AM29LV128ML/H mirror bit flash ???\n");
/* set up sector start address table */
switch (value) {
#ifdef CONFIG_TQM8xxM /* mirror bit flash */
case AMD_ID_MIRROR:
switch (info->flash_id & FLASH_TYPEMASK) {
/* only known types here - no default */
case FLASH_AMLV128U:
for (i = 0; i < info->sector_count; i++) {
info->start[i] = base;
base += 0x20000;
}
break;
}
break;
# else /* ! TQM8xxM */
case AMD_ID_LV400B:
case AMD_ID_LV800B:
case AMD_ID_LV160B:
@@ -369,6 +427,7 @@ debug ("## oops - same ID used for AM29LV128ML/H mirror bit flash ???\n");
: 2 * ( 8 << 10);
}
break;
#endif /* TQM8xxM */
default:
return (0);
break;

View File

@@ -66,7 +66,7 @@ SECTIONS
lib_ppc/cache.o (.text)
lib_ppc/time.o (.text)
. = env_offset;
. = DEFINED(env_offset) ? env_offset : .;
common/environment.o (.ppcenv)
*(.text)

View File

@@ -71,37 +71,39 @@ int board_init ()
extern int vfd_init_clocks(void);
#endif
DECLARE_GLOBAL_DATA_PTR;
S3C24X0_CLOCK_POWER * const clk_power = S3C24X0_GetBase_CLOCK_POWER();
S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
/* memory and cpu-speed are setup before relocation */
#ifdef CONFIG_TRAB_50MHZ
/* change the clock to be 50 MHz 1:1:1 */
/* MDIV:0x5c PDIV:4 SDIV:2 */
rMPLLCON = 0x5c042;
rCLKDIVN = 0;
clk_power->MPLLCON = 0x5c042;
clk_power->CLKDIVN = 0;
#else
/* change the clock to be 133 MHz 1:2:4 */
/* MDIV:0x7d PDIV:4 SDIV:1 */
rMPLLCON = 0x7d041;
rCLKDIVN = 3;
clk_power->MPLLCON = 0x7d041;
clk_power->CLKDIVN = 3;
#endif
/* set up the I/O ports */
rPACON = 0x3ffff;
rPBCON = 0xaaaaaaaa;
rPBUP = 0xffff;
gpio->PACON = 0x3ffff;
gpio->PBCON = 0xaaaaaaaa;
gpio->PBUP = 0xffff;
/* INPUT nCTS0 nRTS0 TXD[1] TXD[0] RXD[1] RXD[0] */
/* 00, 10, 10, 10, 10, 10, 10 */
rPFCON = (2<<0) | (2<<2) | (2<<4) | (2<<6) | (2<<8) | (2<<10);
gpio->PFCON = (2<<0) | (2<<2) | (2<<4) | (2<<6) | (2<<8) | (2<<10);
#ifdef CONFIG_HWFLOW
/* do not pull up RXD0, RXD1, TXD0, TXD1, CTS0, RTS0 */
rPFUP = (1<<0) | (1<<1) | (1<<2) | (1<<3) | (1<<4) | (1<<5);
gpio->PFUP = (1<<0) | (1<<1) | (1<<2) | (1<<3) | (1<<4) | (1<<5);
#else
/* do not pull up RXD0, RXD1, TXD0, TXD1 */
rPFUP = (1<<0) | (1<<1) | (1<<2) | (1<<3);
gpio->PFUP = (1<<0) | (1<<1) | (1<<2) | (1<<3);
#endif
rPGCON = 0x0;
rPGUP = 0x0;
rOPENCR= 0x0;
gpio->PGCON = 0x0;
gpio->PGUP = 0x0;
gpio->OPENCR= 0x0;
/* arch number of SAMSUNG-Board */
/* MACH_TYPE_SMDK2400 */
@@ -112,8 +114,8 @@ int board_init ()
gd->bd->bi_boot_params = 0x0c000100;
/* Make sure both buzzers are turned off */
rPDCON |= 0x5400;
rPDDAT &= ~0xE0;
gpio->PDCON |= 0x5400;
gpio->PDDAT &= ~0xE0;
#ifdef CONFIG_VFD
vfd_init_clocks();
@@ -305,57 +307,73 @@ static int key_pressed(void)
#ifdef CFG_BRIGHTNESS
#define SET_CS_TOUCH (rPDDAT &= 0x5FF)
#define CLR_CS_TOUCH (rPDDAT |= 0x200)
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;
}
static void spi_init(void)
{
S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
S3C24X0_SPI * const spi = S3C24X0_GetBase_SPI();
int i;
/* Configure I/O ports. */
rPDCON = (rPDCON & 0xF3FFFF) | 0x040000;
rPGCON = (rPGCON & 0x0F3FFF) | 0x008000;
rPGCON = (rPGCON & 0x0CFFFF) | 0x020000;
rPGCON = (rPGCON & 0x03FFFF) | 0x080000;
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;
CLR_CS_TOUCH();
rSPPRE = 0x1F; /* Baudrate ca. 514kHz */
rSPPIN = 0x01; /* SPI-MOSI holds Level after last bit */
rSPCON = 0x1A; /* Polling, Prescaler, Master, CPOL=0, CPHA=1 */
spi->ch[0].SPPRE = 0x1F; /* Baudrate 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++) {
rSPTDAT = 0xFF;
spi->ch[0].SPTDAT = 0xFF;
}
wait_transmit_done();
}
static void wait_transmit_done(void)
{
while (!(rSPSTA & 0x01)); /* wait until transfer is done */
S3C24X0_SPI * const spi = S3C24X0_GetBase_SPI();
while (!(spi->ch[0].SPSTA & 0x01)); /* wait until transfer is done */
}
static void tsc2000_write(unsigned int page, unsigned int reg,
unsigned int data)
{
S3C24X0_SPI * const spi = S3C24X0_GetBase_SPI();
unsigned int command;
SET_CS_TOUCH;
SET_CS_TOUCH();
command = 0x0000;
command |= (page << 11);
command |= (reg << 5);
rSPTDAT = (command & 0xFF00) >> 8;
spi->ch[0].SPTDAT = (command & 0xFF00) >> 8;
wait_transmit_done();
rSPTDAT = (command & 0x00FF);
spi->ch[0].SPTDAT = (command & 0x00FF);
wait_transmit_done();
rSPTDAT = (data & 0xFF00) >> 8;
spi->ch[0].SPTDAT = (data & 0xFF00) >> 8;
wait_transmit_done();
rSPTDAT = (data & 0x00FF);
spi->ch[0].SPTDAT = (data & 0x00FF);
wait_transmit_done();
CLR_CS_TOUCH;
CLR_CS_TOUCH();
}
static void tsc2000_set_brightness(void)

View File

@@ -359,14 +359,17 @@ void transfer_pic(int display, unsigned char *adr, int height, int width)
*/
int vfd_init_clocks (void)
{
S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
S3C24X0_TIMERS * const timers = S3C24X0_GetBase_TIMERS();
S3C24X0_LCD * const lcd = S3C24X0_GetBase_LCD();
/* try to determine display type from the value
* defined by pull-ups
*/
rPCUP = (rPCUP & 0xFFF0); /* activate GPC0...GPC3 pullups */
rPCCON = (rPCCON & 0xFFFFFF00); /* configure GPC0...GPC3 as inputs */
gpio->PCUP = (gpio->PCUP & 0xFFF0); /* activate GPC0...GPC3 pullups */
gpio->PCCON = (gpio->PCCON & 0xFFFFFF00); /* configure GPC0...GPC3 as inputs */
udelay (10); /* allow signals to settle */
vfd_board_id = (~rPCDAT) & 0x000F; /* read GPC0...GPC3 port pins */
vfd_board_id = (~gpio->PCDAT) & 0x000F; /* read GPC0...GPC3 port pins */
VFD_DISABLE; /* activate blank for the vfd */
@@ -377,39 +380,39 @@ int vfd_init_clocks (void)
/* If new board revision, then use PWM 3 as cpld-clock */
/* Enable 500 Hz timer for fill level sensor to operate properly */
/* Configure TOUT3 as functional pin, disable pull-up */
rPDCON &= ~0x30000;
rPDCON |= 0x20000;
rPDUP |= (1 << 8);
gpio->PDCON &= ~0x30000;
gpio->PDCON |= 0x20000;
gpio->PDUP |= (1 << 8);
/* Configure the prescaler */
rTCFG0 &= ~0xff00;
rTCFG0 |= 0x0f00;
timers->TCFG0 &= ~0xff00;
timers->TCFG0 |= 0x0f00;
/* Select MUX input (divider) for timer3 (1/16) */
rTCFG1 &= ~0xf000;
rTCFG1 |= 0x3000;
timers->TCFG1 &= ~0xf000;
timers->TCFG1 |= 0x3000;
/* Enable autoreload and set the counter and compare
* registers to values for the 500 Hz clock
* (for a given prescaler (15) and divider (16)):
* counter = (66000000 / 500) >> 9;
*/
rTCNTB3 = 0x101;
rTCMPB3 = 0x101 / 2;
timers->ch[3].TCNTB = 0x101;
timers->ch[3].TCMPB = 0x101 / 2;
/* Start timer */
rTCON = (rTCON | UPDATE3 | RELOAD3) & ~INVERT3;
rTCON = (rTCON | START3) & ~UPDATE3;
timers->TCON = (timers->TCON | UPDATE3 | RELOAD3) & ~INVERT3;
timers->TCON = (timers->TCON | START3) & ~UPDATE3;
}
#endif
/* If old board revision, then use vm-signal as cpld-clock */
rLCDCON2 = 0x00FFC000;
rLCDCON3 = 0x0007FF00;
rLCDCON4 = 0x00000000;
rLCDCON5 = 0x00000400;
rLCDCON1 = 0x00000B75;
lcd->LCDCON2 = 0x00FFC000;
lcd->LCDCON3 = 0x0007FF00;
lcd->LCDCON4 = 0x00000000;
lcd->LCDCON5 = 0x00000400;
lcd->LCDCON1 = 0x00000B75;
/* VM (GPD1) is used as clock for the CPLD */
rPDCON = (rPDCON & 0xFFFFFFF3) | 0x00000008;
gpio->PDCON = (gpio->PDCON & 0xFFFFFFF3) | 0x00000008;
return 0;
}
@@ -425,6 +428,8 @@ int vfd_init_clocks (void)
*/
int drv_vfd_init(void)
{
S3C24X0_LCD * const lcd = S3C24X0_GetBase_LCD();
S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
char *tmp;
ulong palette;
static int vfd_init_done = 0;
@@ -481,40 +486,40 @@ int drv_vfd_init(void)
* see manual S3C2400
*/
/* Stopp LCD-Controller */
rLCDCON1 = 0x00000000;
lcd->LCDCON1 = 0x00000000;
/* frame buffer startadr */
rLCDSADDR1 = gd->fb_base >> 1;
lcd->LCDSADDR1 = gd->fb_base >> 1;
/* frame buffer endadr */
rLCDSADDR2 = (gd->fb_base + FRAME_BUF_SIZE) >> 1;
rLCDSADDR3 = ((256/4));
rLCDCON2 = 0x000DC000;
lcd->LCDSADDR2 = (gd->fb_base + FRAME_BUF_SIZE) >> 1;
lcd->LCDSADDR3 = ((256/4));
lcd->LCDCON2 = 0x000DC000;
if(gd->vfd_type == VFD_TYPE_MN11236)
rLCDCON2 = 37 << 14; /* MN11236: 38 lines */
lcd->LCDCON2 = 37 << 14; /* MN11236: 38 lines */
else
rLCDCON2 = 55 << 14; /* T119C: 56 lines */
rLCDCON3 = 0x0051000A;
rLCDCON4 = 0x00000001;
lcd->LCDCON2 = 55 << 14; /* T119C: 56 lines */
lcd->LCDCON3 = 0x0051000A;
lcd->LCDCON4 = 0x00000001;
if (gd->vfd_type && vfd_inv_data)
rLCDCON5 = 0x000004C0;
lcd->LCDCON5 = 0x000004C0;
else
rLCDCON5 = 0x00000440;
lcd->LCDCON5 = 0x00000440;
/* Port pins as LCD output */
rPCCON = (rPCCON & 0xFFFFFF00)| 0x000000AA;
rPDCON = (rPDCON & 0xFFFFFF03)| 0x000000A8;
gpio->PCCON = (gpio->PCCON & 0xFFFFFF00)| 0x000000AA;
gpio->PDCON = (gpio->PDCON & 0xFFFFFF03)| 0x000000A8;
/* Synchronize VFD enable with LCD controller to avoid flicker */
rLCDCON1 = 0x00000B75; /* Start LCD-Controller */
while((rLCDCON5 & 0x180000)!=0x100000); /* Wait for end of VSYNC */
while((rLCDCON5 & 0x060000)!=0x040000); /* Wait for next HSYNC */
while((rLCDCON5 & 0x060000)==0x040000);
while((rLCDCON5 & 0x060000)!=0x000000);
lcd->LCDCON1 = 0x00000B75; /* Start LCD-Controller */
while((lcd->LCDCON5 & 0x180000)!=0x100000); /* Wait for end of VSYNC */
while((lcd->LCDCON5 & 0x060000)!=0x040000); /* Wait for next HSYNC */
while((lcd->LCDCON5 & 0x060000)==0x040000);
while((lcd->LCDCON5 & 0x060000)!=0x000000);
if(gd->vfd_type)
VFD_ENABLE;
debug ("LCDSADDR1: %lX\n", rLCDSADDR1);
debug ("LCDSADDR2: %lX\n", rLCDSADDR2);
debug ("LCDSADDR3: %lX\n", rLCDSADDR3);
debug ("LCDSADDR1: %lX\n", lcd->LCDSADDR1);
debug ("LCDSADDR2: %lX\n", lcd->LCDSADDR2);
debug ("LCDSADDR3: %lX\n", lcd->LCDSADDR3);
return 0;
}
@@ -525,9 +530,11 @@ rLCDCON2 = 0x000DC000;
*/
void disable_vfd (void)
{
S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
VFD_DISABLE;
rPDCON &= ~0xC;
rPDUP &= ~0x2;
gpio->PDCON &= ~0xC;
gpio->PDUP &= ~0x2;
}
/************************************************************************/

View File

@@ -31,10 +31,11 @@ COBJS = main.o altera.o bedbug.o \
cmd_autoscript.o cmd_bedbug.o cmd_bmp.o cmd_boot.o \
cmd_bootm.o cmd_cache.o cmd_console.o cmd_date.o \
cmd_dcr.o cmd_diag.o cmd_doc.o cmd_nand.o cmd_dtt.o \
cmd_eeprom.o cmd_elf.o cmd_fdc.o cmd_fdos.o cmd_flash.o \
cmd_eeprom.o cmd_elf.o \
cmd_fat.o cmd_fdc.o cmd_fdos.o cmd_flash.o \
cmd_fpga.o cmd_i2c.o cmd_ide.o cmd_immap.o \
cmd_jffs2.o cmd_log.o cmd_mem.o cmd_mii.o cmd_misc.o \
cmd_net.o cmd_nvedit.o env_common.o \
cmd_mmc.o cmd_net.o cmd_nvedit.o env_common.o \
env_flash.o env_eeprom.o env_nvram.o env_nowhere.o \
cmd_pci.o cmd_pcmcia.o cmd_portio.o \
cmd_reginfo.o cmd_scsi.o cmd_vfd.o cmd_usb.o \

View File

@@ -406,12 +406,13 @@ read_record (char *buf, ulong len)
}
/* Check for the console hangup (if any different from serial) */
#ifdef CONFIG_PPC /* we don't have syscall_tbl anywhere else */
if (syscall_tbl[SYSCALL_GETC] != serial_getc) {
if (ctrlc()) {
return (-1);
}
}
#endif
}
/* line too long - truncate */
@@ -691,11 +692,24 @@ int do_load_serial_bin (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
static ulong load_serial_bin (ulong offset)
{
int size;
int size, i;
char buf[32];
set_kerm_bin_mode ((ulong *) offset);
size = k_recv ();
/*
* Gather any trailing characters (for instance, the ^D which
* is sent by 'cu' after sending a file), and give the
* box some time (100 * 1 ms)
*/
for (i=0; i<100; ++i) {
if (serial_tstc()) {
(void) serial_getc();
}
udelay(1000);
}
flush_cache (offset, size);
printf("## Total Size = 0x%08x = %d Bytes\n", size, size);

View File

@@ -56,6 +56,10 @@
#include <logbuff.h>
#endif
#ifdef CONFIG_HAS_DATAFLASH
#include <dataflash.h>
#endif
/*
* Some systems (for example LWMON) have very short watchdog periods;
* we must make sure to split long operations like memmove() or
@@ -138,6 +142,11 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
printf ("## Booting image at %08lx ...\n", addr);
/* Copy header so we can blank CRC field for re-calculation */
#ifdef CONFIG_HAS_DATAFLASH
if (addr_dataflash(addr)){
read_dataflash(addr, sizeof(image_header_t), (char *)&header);
} else
#endif
memmove (&header, (char *)addr, sizeof(image_header_t));
if (ntohl(hdr->ih_magic) != IH_MAGIC) {
@@ -178,6 +187,13 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
data = addr + sizeof(image_header_t);
len = ntohl(hdr->ih_size);
#ifdef CONFIG_HAS_DATAFLASH
if (addr_dataflash(addr)){
read_dataflash(data, len, (char *)CFG_LOAD_ADDR);
data = CFG_LOAD_ADDR;
}
#endif
if (verify) {
printf (" Verifying Checksum ... ");
if (crc32 (0, (char *)data, len) != ntohl(hdr->ih_dcrc)) {

View File

@@ -327,6 +327,26 @@ int eeprom_write (unsigned dev_addr, unsigned offset, uchar *buffer, unsigned cn
return rcode;
}
#ifndef CONFIG_SPI
int
eeprom_probe (unsigned dev_addr, unsigned offset)
{
unsigned char chip;
/* Probe the chip address
*/
#if CFG_I2C_EEPROM_ADDR_LEN == 1 && !defined(CONFIG_SPI_X)
chip = offset >> 8; /* block number */
#else
chip = offset >> 16; /* block number */
#endif /* CFG_I2C_EEPROM_ADDR_LEN, CONFIG_SPI_X */
chip |= dev_addr; /* insert device address */
return (i2c_probe (chip));
}
#endif
/*-----------------------------------------------------------------------
* Set default values
*/

231
common/cmd_fat.c Normal file
View File

@@ -0,0 +1,231 @@
/*
* (C) Copyright 2002
* Richard Jones, rjones@nexus-tech.net
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
/*
* Boot support
*/
#include <common.h>
#include <command.h>
#include <cmd_boot.h>
#include <cmd_autoscript.h>
#include <s_record.h>
#include <net.h>
#include <ata.h>
#if (CONFIG_COMMANDS & CFG_CMD_FAT)
#undef DEBUG
#include <fat.h>
extern block_dev_desc_t *ide_get_dev (int dev);
int do_fat_fsload (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
long size;
unsigned long offset;
unsigned long count;
if (argc < 3) {
printf ("usage:fatload <filename> <addr> [bytes]\n");
return (0);
}
offset = simple_strtoul (argv[2], NULL, 16);
if (argc == 4)
count = simple_strtoul (argv[3], NULL, 16);
else
count = 0;
size = file_fat_read (argv[1], (unsigned char *) offset, count);
printf ("%ld bytes read\n", size);
return size;
}
int do_fat_ls (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
char *filename = "/";
int ret;
if (argc == 2)
ret = file_fat_ls (argv[1]);
else
ret = file_fat_ls (filename);
return (ret);
}
int do_fat_fsinfo (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
int ret;
ret = 0;
printf ("FAT info: %d\n", file_fat_detectfs ());
return (ret);
}
#ifdef NOT_IMPLEMENTED_YET
/* find first device whose first partition is a DOS filesystem */
int find_fat_partition (void)
{
int i, j;
block_dev_desc_t *dev_desc;
unsigned char *part_table;
unsigned char buffer[ATA_BLOCKSIZE];
for (i = 0; i < CFG_IDE_MAXDEVICE; i++) {
dev_desc = ide_get_dev (i);
if (!dev_desc) {
debug ("couldn't get ide device!\n");
return (-1);
}
if (dev_desc->part_type == PART_TYPE_DOS) {
if (dev_desc->
block_read (dev_desc->dev, 0, 1, (ulong *) buffer) != 1) {
debug ("can't perform block_read!\n");
return (-1);
}
part_table = &buffer[0x1be]; /* start with partition #4 */
for (j = 0; j < 4; j++) {
if ((part_table[4] == 1 || /* 12-bit FAT */
part_table[4] == 4 || /* 16-bit FAT */
part_table[4] == 6) && /* > 32Meg part */
part_table[0] == 0x80) { /* bootable? */
curr_dev = i;
part_offset = part_table[11];
part_offset <<= 8;
part_offset |= part_table[10];
part_offset <<= 8;
part_offset |= part_table[9];
part_offset <<= 8;
part_offset |= part_table[8];
debug ("found partition start at %ld\n", part_offset);
return (0);
}
part_table += 16;
}
}
}
debug ("no valid devices found!\n");
return (-1);
}
int
do_fat_dump (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[])
{
__u8 block[1024];
int ret;
int bknum;
ret = 0;
if (argc != 2) {
printf ("needs an argument!\n");
return (0);
}
bknum = simple_strtoul (argv[1], NULL, 10);
if (disk_read (0, bknum, block) != 0) {
printf ("Error: reading block\n");
return -1;
}
printf ("FAT dump: %d\n", bknum);
hexdump (512, block);
return (ret);
}
int disk_read (__u32 startblock, __u32 getsize, __u8 *bufptr)
{
ulong tot;
block_dev_desc_t *dev_desc;
if (curr_dev < 0) {
if (find_fat_partition () != 0)
return (-1);
}
dev_desc = ide_get_dev (curr_dev);
if (!dev_desc) {
debug ("couldn't get ide device\n");
return (-1);
}
tot = dev_desc->block_read (0, startblock + part_offset,
getsize, (ulong *) bufptr);
/* should we do this here?
flush_cache ((ulong)buf, cnt*ide_dev_desc[device].blksz);
*/
if (tot == getsize)
return (0);
debug ("unable to read from device!\n");
return (-1);
}
static int isprint (unsigned char ch)
{
if (ch >= 32 && ch < 127)
return (1);
return (0);
}
void hexdump (int cnt, unsigned char *data)
{
int i;
int run;
int offset;
offset = 0;
while (cnt) {
printf ("%04X : ", offset);
if (cnt >= 16)
run = 16;
else
run = cnt;
cnt -= run;
for (i = 0; i < run; i++)
printf ("%02X ", (unsigned int) data[i]);
printf (": ");
for (i = 0; i < run; i++)
printf ("%c", isprint (data[i]) ? data[i] : '.');
printf ("\n");
data = &data[16];
offset += run;
}
}
#endif /* NOT_IMPLEMENTED_YET */
#endif /* CFG_CMD_FAT */

View File

@@ -29,6 +29,10 @@
#include <cmd_boot.h>
#include <flash.h>
#ifdef CONFIG_HAS_DATAFLASH
#include <dataflash.h>
#endif
#if (CONFIG_COMMANDS & CFG_CMD_FLASH)
extern flash_info_t flash_info[]; /* info for FLASH chips */
@@ -96,6 +100,10 @@ int do_flinfo ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
ulong bank;
#ifdef CONFIG_HAS_DATAFLASH
dataflash_print_info();
#endif
if (argc == 1) { /* print info for all FLASH banks */
for (bank=0; bank <CFG_MAX_FLASH_BANKS; ++bank) {
printf ("\nBank # %ld: ", bank+1);

View File

@@ -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
@@ -150,7 +150,24 @@ do_icinfo (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
int
do_carinfo (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
unimplemented (cmdtp, flag, argc, argv);
volatile immap_t *immap = (immap_t *) CFG_IMMR;
#if defined(CONFIG_8xx)
volatile car8xx_t *car = &immap->im_clkrst;
#elif defined(CONFIG_8260)
volatile car8260_t *car = &immap->im_clkrst;
#endif
#if defined(CONFIG_8xx)
printf ("SCCR = %08x\n", car->car_sccr);
printf ("PLPRCR= %08x\n", car->car_plprcr);
printf ("RSR = %08x\n", car->car_rsr);
#elif defined(CONFIG_8260)
printf ("SCCR = %08x\n", car->car_sccr);
printf ("SCMR = %08x\n", car->car_scmr);
printf ("RSR = %08x\n", car->car_rsr);
printf ("RMR = %08x\n", car->car_rmr);
#endif
return 0;
}
@@ -168,7 +185,7 @@ header(void)
int i;
if (counter % 2)
putc('\n');
putc('\n');
counter = 0;
for (i = 0; i < 4; i++, data += 79)

View File

@@ -30,6 +30,12 @@
#include <common.h>
#include <command.h>
#include <cmd_mem.h>
#if (CONFIG_COMMANDS & CFG_CMD_MMC)
#include <mmc.h>
#endif
#ifdef CONFIG_HAS_DATAFLASH
#include <dataflash.h>
#endif
#if (CONFIG_COMMANDS & (CFG_CMD_MEMORY | CFG_CMD_PCI | CFG_CMD_I2C\
| CMD_CMD_PORTIO))
@@ -128,6 +134,23 @@ int do_mem_md ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
printf("%08lx:", addr);
linebytes = (nbytes>DISP_LINE_LEN)?DISP_LINE_LEN:nbytes;
#ifdef CONFIG_HAS_DATAFLASH
if (read_dataflash(addr, (linebytes/size)*size, linebuf) != -1){
for (i=0; i<linebytes; i+= size) {
if (size == 4) {
printf(" %08x", *uip++);
} else if (size == 2) {
printf(" %04x", *usp++);
} else {
printf(" %02x", *ucp++);
}
addr += size;
}
} else { /* addr does not correspond to DataFlash */
#endif
for (i=0; i<linebytes; i+= size) {
if (size == 4) {
printf(" %08x", (*uip++ = *((uint *)addr)));
@@ -138,6 +161,9 @@ int do_mem_md ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
}
addr += size;
}
#ifdef CONFIG_HAS_DATAFLASH
}
#endif
printf(" ");
cp = linebuf;
for (i=0; i<linebytes; i++) {
@@ -233,6 +259,13 @@ int do_mem_cmp (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
count = simple_strtoul(argv[3], NULL, 16);
#ifdef CONFIG_HAS_DATAFLASH
if (addr_dataflash(addr1) | addr_dataflash(addr2)){
printf("Comparison with DataFlash space not supported.\n\r");
return 0;
}
#endif
ngood = 0;
while (count-- > 0) {
@@ -308,7 +341,11 @@ int do_mem_cp ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
#ifndef CFG_NO_FLASH
/* check if we are copying to Flash */
if (addr2info(dest) != NULL) {
if ( (addr2info(dest) != NULL)
#ifdef CONFIG_HAS_DATAFLASH
&& (!addr_dataflash(addr))
#endif
) {
int rc;
printf ("Copy to Flash... ");
@@ -323,6 +360,75 @@ int do_mem_cp ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
}
#endif
#if (CONFIG_COMMANDS & CFG_CMD_MMC)
if (mmc2info(dest)) {
int rc;
printf ("Copy to MMC... ");
switch (rc = mmc_write ((uchar *)addr, dest, count*size)) {
case 0:
printf ("\n");
return 1;
case -1:
printf("failed\n");
return 1;
default:
printf ("%s[%d] FIXME: rc=%d\n",__FILE__,__LINE__,rc);
return 1;
}
puts ("done\n");
return 0;
}
if (mmc2info(addr)) {
int rc;
printf ("Copy from MMC... ");
switch (rc = mmc_read (addr, (uchar *)dest, count*size)) {
case 0:
printf ("\n");
return 1;
case -1:
printf("failed\n");
return 1;
default:
printf ("%s[%d] FIXME: rc=%d\n",__FILE__,__LINE__,rc);
return 1;
}
puts ("done\n");
return 0;
}
#endif
#ifdef CONFIG_HAS_DATAFLASH
/* Check if we are copying from RAM or Flash to DataFlash */
if (addr_dataflash(dest) && !addr_dataflash(addr)){
int rc;
printf ("Copy to DataFlash... ");
rc = write_dataflash (dest, addr, count*size);
if (rc != 1) {
dataflash_perror (rc);
return (1);
}
puts ("done\n");
return 0;
}
/* Check if we are copying from DataFlash to RAM */
if (addr_dataflash(addr) && !addr_dataflash(dest) && (addr2info(dest)==NULL) ){
read_dataflash(addr, count * size, (char *) dest);
return 0;
}
if (addr_dataflash(addr) && addr_dataflash(dest)){
printf("Unsupported combination of source/destination.\n\r");
return 1;
}
#endif
while (count-- > 0) {
if (size == 4)
*((ulong *)dest) = *((ulong *)addr);
@@ -762,6 +868,13 @@ mod_mem(cmd_tbl_t *cmdtp, int incrflag, int flag, int argc, char *argv[])
addr += base_address;
}
#ifdef CONFIG_HAS_DATAFLASH
if (addr_dataflash(addr)){
printf("Can't modify DataFlash in place. Use cp instead.\n\r");
return 0;
}
#endif
/* Print the address, followed by value. Then accept input for
* the next value. A non-converted value exits.
*/
@@ -820,30 +933,29 @@ mod_mem(cmd_tbl_t *cmdtp, int incrflag, int flag, int argc, char *argv[])
int do_mem_crc (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
ulong addr, length;
ulong crc;
ulong *ptr;
ulong addr, length;
ulong crc;
ulong *ptr;
if (argc < 3) {
printf ("Usage:\n%s\n", cmdtp->usage);
return 1;
}
addr = simple_strtoul(argv[1], NULL, 16);
addr = simple_strtoul (argv[1], NULL, 16);
addr += base_address;
length = simple_strtoul(argv[2], NULL, 16);
length = simple_strtoul (argv[2], NULL, 16);
crc = crc32 (0, (const uchar *)addr, length);
crc = crc32 (0, (const uchar *) addr, length);
printf ("CRC32 for %08lx ... %08lx ==> %08lx\n",
addr, addr + length -1, crc);
addr, addr + length - 1, crc);
if (argc > 3)
{
ptr = (ulong *)simple_strtoul(argv[3], NULL, 16);
*ptr = crc;
}
if (argc > 3) {
ptr = (ulong *) simple_strtoul (argv[3], NULL, 16);
*ptr = crc;
}
return 0;
}

40
common/cmd_mmc.c Normal file
View File

@@ -0,0 +1,40 @@
/*
* (C) Copyright 2003
* Kyle Harris, kharris@nexus-tech.net
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#include <common.h>
#include <command.h>
#if (CONFIG_COMMANDS & CFG_CMD_MMC)
#include <mmc.h>
int do_mmc (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
if (mmc_init (1) != 0) {
printf ("No MMC card found\n");
return 1;
}
return 0;
}
#endif /* CFG_CMD_MMC */

View File

@@ -74,6 +74,8 @@
#include <cmd_fdos.h>
#include <cmd_bmp.h>
#include <cmd_portio.h>
#include <cmd_mmc.h>
#include <cmd_fat.h>
#ifdef CONFIG_AMIGAONEG3SE
#include <cmd_menu.h>
@@ -131,13 +133,14 @@ do_echo (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
if (i > 1)
putc(' ');
while ((c = *p++) != '\0')
while ((c = *p++) != '\0') {
if (c == '\\' && *p == 'c') {
putnl = 0;
p++;
}
else
} else {
putc(c);
}
}
}
if (putnl)
@@ -190,8 +193,7 @@ do_help (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
if (cmdtp->usage)
puts (cmdtp->usage);
#endif /* CFG_LONGHELP */
}
else {
} else {
printf ("Unknown command '%s' - try 'help'"
" without arguments for list of all"
" known commands\n\n",
@@ -263,6 +265,7 @@ cmd_tbl_t cmd_tbl[] = {
CMD_TBL_DTT
CMD_TBL_ECHO
CMD_TBL_EEPROM
CMD_TBL_FAT
CMD_TBL_FCCINFO
CMD_TBL_FLERASE
CMD_TBL_FDC
@@ -302,6 +305,7 @@ cmd_tbl_t cmd_tbl[] = {
CMD_TBL_LOOP
CMD_TBL_JFFS2_LS
CMD_TBL_MCCINFO
CMD_TBL_MMC
CMD_TBL_MD
CMD_TBL_MEMCINFO
#ifdef CONFIG_AMIGAONEG3SE

View File

@@ -232,6 +232,20 @@ void printf (const char *fmt, ...)
puts (printbuffer);
}
void vprintf (const char *fmt, va_list args)
{
uint i;
char printbuffer[CFG_PBSIZE];
/* For this to work, printbuffer must be larger than
* anything we ever want to print.
*/
i = vsprintf (printbuffer, fmt, args);
/* Print the string */
puts (printbuffer);
}
/* test if ctrl-c was pressed */
static int ctrlc_disabled = 0; /* see disable_ctrl() */
static int ctrlc_was_pressed = 0;

View File

@@ -319,13 +319,7 @@ void main_loop (void)
debug ("### main_loop entered: bootdelay=%d\n\n", bootdelay);
# ifdef CONFIG_BOOT_RETRY_TIME
s = getenv ("bootretry");
if (s != NULL)
retry_time = (int)simple_strtoul(s, NULL, 10);
else
retry_time = CONFIG_BOOT_RETRY_TIME;
if (retry_time >= 0 && retry_time < CONFIG_BOOT_RETRY_MIN)
retry_time = CONFIG_BOOT_RETRY_MIN;
init_cmd_timeout ();
# endif /* CONFIG_BOOT_RETRY_TIME */
s = getenv ("bootcmd");
@@ -422,10 +416,26 @@ void main_loop (void)
#endif /*CFG_HUSH_PARSER*/
}
#ifdef CONFIG_BOOT_RETRY_TIME
/***************************************************************************
* initialise command line timeout
*/
void init_cmd_timeout(void)
{
char *s = getenv ("bootretry");
if (s != NULL)
retry_time = (int)simple_strtoul(s, NULL, 10);
else
retry_time = CONFIG_BOOT_RETRY_TIME;
if (retry_time >= 0 && retry_time < CONFIG_BOOT_RETRY_MIN)
retry_time = CONFIG_BOOT_RETRY_MIN;
}
/***************************************************************************
* reset command line timeout to retry_time seconds
*/
#ifdef CONFIG_BOOT_RETRY_TIME
void reset_cmd_timeout(void)
{
endtime = endtick(retry_time);

View File

@@ -23,6 +23,11 @@
#########################################################################
# clean the slate ...
PLATFORM_RELFLAGS =
PLATFORM_CPPFLAGS =
PLATFORM_LDFLAGS =
#
# When cross-compiling on NetBSD, we have to define __PPC__ or else we
# will pick up a va_list declaration that is incompatible with the
@@ -96,9 +101,11 @@ RANLIB = $(CROSS_COMPILE)RANLIB
RELFLAGS= $(PLATFORM_RELFLAGS)
DBGFLAGS= -g #-DDEBUG
OPTFLAGS= -Os #-fomit-frame-pointer
ifndef LDSCRIPT
#LDSCRIPT := board/$(BOARDDIR)/u-boot.lds.debug
LDSCRIPT := $(TOPDIR)/board/$(BOARDDIR)/u-boot.lds
OBJCFLAGS := --gap-fill=0xff
endif
OBJCFLAGS += --gap-fill=0xff
CPPFLAGS := $(DBGFLAGS) $(OPTFLAGS) $(RELFLAGS) \
-D__KERNEL__ -DTEXT_BASE=$(TEXT_BASE) \

View File

@@ -64,7 +64,7 @@ get_cpu_type(void)
case 0x0008:
type = CPU_750;
if (((pvr >> 8) & 0xff) == 0x01) {
if (((pvr >> 8) & 0xff) == 0x01) {
type = CPU_750CX; /* old CX (80100 and 8010x?)*/
} else if (((pvr >> 8) & 0xff) == 0x22) {
type = CPU_750CX; /* CX (82201,82202) and CXe (82214) */
@@ -72,14 +72,18 @@ get_cpu_type(void)
type = CPU_750CX; /* CXe (83311) */
} else if (((pvr >> 12) & 0xF) == 0x3) {
type = CPU_755;
}
}
break;
case 0x7000:
type = CPU_750FX;
break;
case 0x800C:
type = CPU_7410;
break;
case 0x8000:
case 0x8000:
type = CPU_7450;
break;
@@ -116,6 +120,10 @@ int checkcpu (void)
str = "750";
break;
case CPU_750FX:
str = "750FX";
break;
case CPU_755:
str = "755";
break;
@@ -124,16 +132,16 @@ int checkcpu (void)
str = "MPC7400";
break;
case CPU_7410:
str = "MPC7410";
case CPU_7410:
str = "MPC7410";
break;
case CPU_7450:
str = "MPC7450";
case CPU_7450:
str = "MPC7450";
break;
default:
printf("Unknown CPU -- PVR: 0x%08x\n", pvr);
printf("Unknown CPU -- PVR: 0x%08x\n", pvr);
return -1;
}
@@ -146,8 +154,8 @@ PR_CLK:
#endif
/* these two functions are unimplemented currently [josh] */
/* ------------------------------------------------------------------------- */
/* L1 i-cache */
/* -------------------------------------------------------------------- */
/* L1 i-cache */
int
checkicache(void)
@@ -155,8 +163,8 @@ checkicache(void)
return 0; /* XXX */
}
/* ------------------------------------------------------------------------- */
/* L1 d-cache */
/* -------------------------------------------------------------------- */
/* L1 d-cache */
int
checkdcache(void)
@@ -164,7 +172,7 @@ checkdcache(void)
return 0; /* XXX */
}
/* ------------------------------------------------------------------------- */
/* -------------------------------------------------------------------- */
static inline void
soft_restart(unsigned long addr)

View File

@@ -48,6 +48,33 @@ static const int hid1_multipliers_x_10[] = {
0 /* 1111 - off */
};
static const int hid1_fx_multipliers_x_10[] = {
00, /* 0000 - off */
00, /* 0001 - off */
10, /* 0010 - bypass */
10, /* 0011 - bypass */
20, /* 0100 - 2x */
25, /* 0101 - 2.5x */
30, /* 0110 - 3x */
35, /* 0111 - 3.5x */
40, /* 1000 - 4x */
45, /* 1001 - 4.5x */
50, /* 1010 - 5x */
55, /* 1011 - 5.5x */
60, /* 1100 - 6x */
65, /* 1101 - 6.5x */
70, /* 1110 - 7x */
75, /* 1111 - 7.5 */
80, /* 10000 - 8x */
85, /* 10001 - 8.5x */
90, /* 10010 - 9x */
95, /* 10011 - 9.5x */
100, /* 10100 - 10x */
110, /* 10101 - 11x */
120, /* 10110 - 12x */
};
/* ------------------------------------------------------------------------- */
/*
@@ -59,9 +86,13 @@ static const int hid1_multipliers_x_10[] = {
int get_clocks (void)
{
DECLARE_GLOBAL_DATA_PTR;
#ifdef CONFIG_750FX
ulong clock = CFG_BUS_CLK * \
hid1_fx_multipliers_x_10[get_hid1 () >> 27] / 10;
#else
ulong clock = CFG_BUS_CLK * \
hid1_multipliers_x_10[get_hid1 () >> 28] / 10;
#endif
gd->cpu_clk = clock;
gd->bus_clk = CFG_BUS_CLK;

View File

@@ -379,11 +379,23 @@ invalidate_bats:
mtspr IBAT1U, r0
mtspr IBAT2U, r0
mtspr IBAT3U, r0
#ifdef CONFIG_750FX
mtspr IBAT4U, r0
mtspr IBAT5U, r0
mtspr IBAT6U, r0
mtspr IBAT7U, r0
#endif
isync
mtspr DBAT0U, r0
mtspr DBAT1U, r0
mtspr DBAT2U, r0
mtspr DBAT3U, r0
#ifdef CONFIG_750FX
mtspr DBAT4U, r0
mtspr DBAT5U, r0
mtspr DBAT6U, r0
mtspr DBAT7U, r0
#endif
isync
sync
blr
@@ -465,6 +477,80 @@ setup_bats:
mtspr DBAT3U, r3
isync
#ifdef CONFIG_750FX
/* IBAT 4 */
addis r4, r0, CFG_IBAT4L@h
ori r4, r4, CFG_IBAT4L@l
addis r3, r0, CFG_IBAT4U@h
ori r3, r3, CFG_IBAT4U@l
mtspr IBAT4L, r4
mtspr IBAT4U, r3
isync
/* DBAT 4 */
addis r4, r0, CFG_DBAT4L@h
ori r4, r4, CFG_DBAT4L@l
addis r3, r0, CFG_DBAT4U@h
ori r3, r3, CFG_DBAT4U@l
mtspr DBAT4L, r4
mtspr DBAT4U, r3
isync
/* IBAT 5 */
addis r4, r0, CFG_IBAT5L@h
ori r4, r4, CFG_IBAT5L@l
addis r3, r0, CFG_IBAT5U@h
ori r3, r3, CFG_IBAT5U@l
mtspr IBAT5L, r4
mtspr IBAT5U, r3
isync
/* DBAT 5 */
addis r4, r0, CFG_DBAT5L@h
ori r4, r4, CFG_DBAT5L@l
addis r3, r0, CFG_DBAT5U@h
ori r3, r3, CFG_DBAT5U@l
mtspr DBAT5L, r4
mtspr DBAT5U, r3
isync
/* IBAT 6 */
addis r4, r0, CFG_IBAT6L@h
ori r4, r4, CFG_IBAT6L@l
addis r3, r0, CFG_IBAT6U@h
ori r3, r3, CFG_IBAT6U@l
mtspr IBAT6L, r4
mtspr IBAT6U, r3
isync
/* DBAT 6 */
addis r4, r0, CFG_DBAT6L@h
ori r4, r4, CFG_DBAT6L@l
addis r3, r0, CFG_DBAT6U@h
ori r3, r3, CFG_DBAT6U@l
mtspr DBAT6L, r4
mtspr DBAT6U, r3
isync
/* IBAT 7 */
addis r4, r0, CFG_IBAT7L@h
ori r4, r4, CFG_IBAT7L@l
addis r3, r0, CFG_IBAT7U@h
ori r3, r3, CFG_IBAT7U@l
mtspr IBAT7L, r4
mtspr IBAT7U, r3
isync
/* DBAT 7 */
addis r4, r0, CFG_DBAT7L@h
ori r4, r4, CFG_DBAT7L@l
addis r3, r0, CFG_DBAT7U@h
ori r3, r3, CFG_DBAT7U@l
mtspr DBAT7L, r4
mtspr DBAT7U, r3
isync
#endif
/* bats are done, now invalidate the TLBs */
addis r3, 0, 0x0000

View File

@@ -43,7 +43,12 @@ extern void reset_cpu(ulong addr);
int timer_load_val = 0;
/* macro to read the 16 bit timer */
#define READ_TIMER (rTCNTO4 & 0xffff)
static inline ulong READ_TIMER(void)
{
S3C24X0_TIMERS * const timers = S3C24X0_GetBase_TIMERS();
return (timers->TCNTO4 & 0xffff);
}
#ifdef CONFIG_USE_IRQ
/* enable IRQ interrupts */
@@ -184,9 +189,11 @@ static ulong lastdec;
int interrupt_init (void)
{
S3C24X0_TIMERS * const timers = S3C24X0_GetBase_TIMERS();
/* use PWM Timer 4 because it has no output */
/* prescaler for Timer 4 is 16 */
rTCFG0 = 0x0f00;
timers->TCFG0 = 0x0f00;
if (timer_load_val == 0)
{
/*
@@ -197,11 +204,11 @@ int interrupt_init (void)
timer_load_val = get_PCLK()/(2 * 16 * 100);
}
/* load value for 10 ms timeout */
lastdec = rTCNTB4 = timer_load_val;
lastdec = timers->TCNTB4 = timer_load_val;
/* auto load, manual update of Timer 4 */
rTCON = (rTCON & ~0x0700000) | 0x600000;
timers->TCON = (timers->TCON & ~0x0700000) | 0x600000;
/* auto load, start Timer 4 */
rTCON = (rTCON & ~0x0700000) | 0x500000;
timers->TCON = (timers->TCON & ~0x0700000) | 0x500000;
timestamp = 0;
return (0);
@@ -243,13 +250,13 @@ void udelay (unsigned long usec)
void reset_timer_masked (void)
{
/* reset time */
lastdec = READ_TIMER;
lastdec = READ_TIMER();
timestamp = 0;
}
ulong get_timer_masked (void)
{
ulong now = READ_TIMER;
ulong now = READ_TIMER();
if (lastdec >= now) {
/* normal mode */

View File

@@ -25,57 +25,51 @@
#include <s3c2410.h>
#endif
#ifdef CONFIG_SERIAL1
#define UART_NR S3C24X0_UART0
#elif CONFIG_SERIAL2
# if defined(CONFIG_TRAB)
# #error "TRAB supports only CONFIG_SERIAL1"
# endif
#define UART_NR S3C24X0_UART1
#elif CONFIG_SERIAL3
# if defined(CONFIG_TRAB)
# #error "TRAB supports only CONFIG_SERIAL1"
# endif
#define UART_NR S3C24X0_UART2
#else
#error "Bad: you didn't configure serial ..."
#endif
void serial_setbrg (void)
{
DECLARE_GLOBAL_DATA_PTR;
S3C24X0_UART * const uart = S3C24X0_GetBase_UART(UART_NR);
int i;
unsigned int reg = 0;
/* value is calculated so : (int)(PCLK/16./baudrate) -1 */
reg = get_PCLK() / (16 * gd->baudrate) - 1;
#ifdef CONFIG_SERIAL1
/* FIFO enable, Tx/Rx FIFO clear */
rUFCON0 = 0x07;
rUMCON0 = 0x0;
uart->UFCON = 0x07;
uart->UMCON = 0x0;
/* Normal,No parity,1 stop,8 bit */
rULCON0 = 0x3;
uart->ULCON = 0x3;
/*
* tx=level,rx=edge,disable timeout int.,enable rx error int.,
* normal,interrupt or polling
*/
rUCON0 = 0x245;
rUBRDIV0 = reg;
uart->UCON = 0x245;
uart->UBRDIV = reg;
#ifdef CONFIG_HWFLOW
rUMCON0 = 0x1; /* RTS up */
uart->UMCON = 0x1; /* RTS up */
#endif
for (i = 0; i < 100; i++);
#elif CONFIG_SERIAL2
# if defined(CONFIG_TRAB)
# #error "TRAB supports only CONFIG_SERIAL1"
# endif
/* FIFO enable, Tx/Rx FIFO clear */
rUFCON1 = 0x06;
rUMCON1 = 0x0;
/* Normal,No parity,1 stop,8 bit */
rULCON1 = 0x3;
/*
* tx=level,rx=edge,disable timeout int.,enable rx error int.,
* normal,interrupt or polling
*/
rUCON1 = 0x245;
rUBRDIV1 = reg;
#ifdef CONFIG_HWFLOW
rUMCON1 = 0x1; /* RTS up */
#endif
for (i = 0; i < 100; i++);
#else
#error "Bad: you didn't configure serial ..."
#endif
}
/*
@@ -97,15 +91,12 @@ int serial_init (void)
*/
int serial_getc (void)
{
#ifdef CONFIG_SERIAL1
while (!(rUTRSTAT0 & 0x1));
S3C24X0_UART * const uart = S3C24X0_GetBase_UART(UART_NR);
/* wait for character to arrive */
while (!(uart->UTRSTAT & 0x1));
return rURXH0 & 0xff;
#elif CONFIG_SERIAL2
while (!(rUTRSTAT1 & 0x1));
return rURXH1 & 0xff;
#endif
return uart->URXH & 0xff;
}
#ifdef CONFIG_HWFLOW
@@ -146,33 +137,22 @@ void enable_putc(void)
*/
void serial_putc (const char c)
{
S3C24X0_UART * const uart = S3C24X0_GetBase_UART(UART_NR);
#ifdef CONFIG_MODEM_SUPPORT
if (be_quiet)
return;
#endif
#ifdef CONFIG_SERIAL1
/* wait for room in the tx FIFO on SERIAL1 */
while (!(rUTRSTAT0 & 0x2));
/* wait for room in the tx FIFO */
while (!(uart->UTRSTAT & 0x2));
#ifdef CONFIG_HWFLOW
/* Wait for CTS up */
while(hwflow && !(rUMSTAT0 & 0x1))
while(hwflow && !(uart->UMSTAT & 0x1))
;
#endif
rUTXH0 = c;
#elif CONFIG_SERIAL2
/* wait for room in the tx FIFO on SERIAL2 */
while (!(rUTRSTAT1 & 0x2));
#ifdef CONFIG_HWFLOW
/* Wait for CTS up */
while(hwflow && !(rUMSTAT1 & 0x1))
;
#endif
rUTXH1 = c;
#endif
uart->UTXH = c;
/* If \n, also do \r */
if (c == '\n')
@@ -184,11 +164,9 @@ void serial_putc (const char c)
*/
int serial_tstc (void)
{
#ifdef CONFIG_SERIAL1
return rUTRSTAT0 & 0x1;
#elif CONFIG_SERIAL2
return rUTRSTAT1 & 0x1;
#endif
S3C24X0_UART * const uart = S3C24X0_GetBase_UART(UART_NR);
return uart->UTRSTAT & 0x1;
}
void

View File

@@ -51,12 +51,13 @@
static ulong get_PLLCLK(int pllreg)
{
S3C24X0_CLOCK_POWER * const clk_power = S3C24X0_GetBase_CLOCK_POWER();
ulong r, m, p, s;
if (pllreg == MPLL)
r = rMPLLCON;
r = clk_power->MPLLCON;
else if (pllreg == UPLL)
r = rUPLLCON;
r = clk_power->UPLLCON;
else
hang();
@@ -76,17 +77,17 @@ ulong get_FCLK(void)
/* return HCLK frequency */
ulong get_HCLK(void)
{
ulong clkdiv = rCLKDIVN;
S3C24X0_CLOCK_POWER * const clk_power = S3C24X0_GetBase_CLOCK_POWER();
return((clkdiv & 0x2) ? get_FCLK()/2 : get_FCLK());
return((clk_power->CLKDIVN & 0x2) ? get_FCLK()/2 : get_FCLK());
}
/* return PCLK frequency */
ulong get_PCLK(void)
{
ulong clkdiv = rCLKDIVN;
S3C24X0_CLOCK_POWER * const clk_power = S3C24X0_GetBase_CLOCK_POWER();
return((clkdiv & 0x1) ? get_HCLK()/2 : get_HCLK());
return((clk_power->CLKDIVN & 0x1) ? get_HCLK()/2 : get_HCLK());
}
/* return UCLK frequency */

View File

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

521
cpu/at91rm9200/at45.c Normal file
View File

@@ -0,0 +1,521 @@
/* Driver for ATMEL DataFlash support
* Author : Hamid Ikdoumi (Atmel)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*
*/
#include <config.h>
#include <common.h>
#include <asm/hardware.h>
#ifdef CONFIG_HAS_DATAFLASH
#include <dataflash.h>
#define SPI_CLK 5000000
#define AT91C_SPI_PCS0_SERIAL_DATAFLASH 0xE /* Chip Select 0 : NPCS0 %1110 */
#define AT91C_SPI_PCS3_DATAFLASH_CARD 0x7 /* Chip Select 3 : NPCS3 %0111 */
void AT91F_SpiInit(void) {
/*-------------------------------------------------------------------*/
/* SPI DataFlash Init */
/*-------------------------------------------------------------------*/
/* Configure PIOs */
AT91C_BASE_PIOA->PIO_ASR = AT91C_PA3_NPCS0 | AT91C_PA4_NPCS1 | AT91C_PA1_MOSI | AT91C_PA5_NPCS2 |
AT91C_PA6_NPCS3 | AT91C_PA0_MISO | AT91C_PA2_SPCK;
AT91C_BASE_PIOA->PIO_PDR = AT91C_PA3_NPCS0 | AT91C_PA4_NPCS1 | AT91C_PA1_MOSI | AT91C_PA5_NPCS2 |
AT91C_PA6_NPCS3 | AT91C_PA0_MISO | AT91C_PA2_SPCK;
/* Enable CLock */
AT91C_BASE_PMC->PMC_PCER = 1 << AT91C_ID_SPI;
/* Reset the SPI */
AT91C_BASE_SPI->SPI_CR = AT91C_SPI_SWRST;
/* Configure SPI in Master Mode with No CS selected !!! */
AT91C_BASE_SPI->SPI_MR = AT91C_SPI_MSTR | AT91C_SPI_MODFDIS | AT91C_SPI_PCS;
/* Configure CS0 and CS3 */
*(AT91C_SPI_CSR + 0) = AT91C_SPI_CPOL | (AT91C_SPI_DLYBS & 0x100000) | ((AT91C_MASTER_CLOCK / (2*SPI_CLK)) << 8);
*(AT91C_SPI_CSR + 3) = AT91C_SPI_CPOL | (AT91C_SPI_DLYBS & 0x100000) | ((AT91C_MASTER_CLOCK / (2*SPI_CLK)) << 8);
}
void AT91F_SpiEnable(int cs) {
switch(cs) {
case 0: /* Configure SPI CS0 for Serial DataFlash AT45DBxx */
AT91C_BASE_SPI->SPI_MR &= 0xFFF0FFFF;
AT91C_BASE_SPI->SPI_MR |= ((AT91C_SPI_PCS0_SERIAL_DATAFLASH<<16) & AT91C_SPI_PCS);
break;
case 3: /* Configure SPI CS3 for Serial DataFlash Card */
/* Set up PIO SDC_TYPE to switch on DataFlash Card and not MMC/SDCard */
AT91C_BASE_PIOB->PIO_PER = AT91C_PIO_PB7; /* Set in PIO mode */
AT91C_BASE_PIOB->PIO_OER = AT91C_PIO_PB7; /* Configure in output */
/* Clear Output */
AT91C_BASE_PIOB->PIO_CODR = AT91C_PIO_PB7;
/* Configure PCS */
AT91C_BASE_SPI->SPI_MR &= 0xFFF0FFFF;
AT91C_BASE_SPI->SPI_MR |= ((AT91C_SPI_PCS3_DATAFLASH_CARD<<16) & AT91C_SPI_PCS);
break;
}
/* SPI_Enable */
AT91C_BASE_SPI->SPI_CR = AT91C_SPI_SPIEN;
}
/*----------------------------------------------------------------------------*/
/* \fn AT91F_SpiWrite */
/* \brief Set the PDC registers for a transfert */
/*----------------------------------------------------------------------------*/
unsigned int AT91F_SpiWrite ( AT91PS_DataflashDesc pDesc )
{
unsigned int timeout;
pDesc->state = BUSY;
AT91C_BASE_SPI->SPI_PTCR = AT91C_PDC_TXTDIS + AT91C_PDC_RXTDIS;
/* Initialize the Transmit and Receive Pointer */
AT91C_BASE_SPI->SPI_RPR = (unsigned int)pDesc->rx_cmd_pt ;
AT91C_BASE_SPI->SPI_TPR = (unsigned int)pDesc->tx_cmd_pt ;
/* Intialize the Transmit and Receive Counters */
AT91C_BASE_SPI->SPI_RCR = pDesc->rx_cmd_size;
AT91C_BASE_SPI->SPI_TCR = pDesc->tx_cmd_size;
if ( pDesc->tx_data_size != 0 ) {
/* Initialize the Next Transmit and Next Receive Pointer */
AT91C_BASE_SPI->SPI_RNPR = (unsigned int)pDesc->rx_data_pt ;
AT91C_BASE_SPI->SPI_TNPR = (unsigned int)pDesc->tx_data_pt ;
/* Intialize the Next Transmit and Next Receive Counters */
AT91C_BASE_SPI->SPI_RNCR = pDesc->rx_data_size ;
AT91C_BASE_SPI->SPI_TNCR = pDesc->tx_data_size ;
}
/* arm simple, non interrupt dependent timer */
reset_timer_masked();
timeout = 0;
AT91C_BASE_SPI->SPI_PTCR = AT91C_PDC_TXTEN + AT91C_PDC_RXTEN;
while(!(AT91C_BASE_SPI->SPI_SR & AT91C_SPI_RXBUFF) && ((timeout = get_timer_masked() ) < CFG_SPI_WRITE_TOUT));
AT91C_BASE_SPI->SPI_PTCR = AT91C_PDC_TXTDIS + AT91C_PDC_RXTDIS;
pDesc->state = IDLE;
if (timeout >= CFG_SPI_WRITE_TOUT){
printf("Error Timeout\n\r");
return DATAFLASH_ERROR;
}
return DATAFLASH_OK;
}
/*----------------------------------------------------------------------*/
/* \fn AT91F_DataFlashSendCommand */
/* \brief Generic function to send a command to the dataflash */
/*----------------------------------------------------------------------*/
AT91S_DataFlashStatus AT91F_DataFlashSendCommand(
AT91PS_DataFlash pDataFlash,
unsigned char OpCode,
unsigned int CmdSize,
unsigned int DataflashAddress)
{
unsigned int adr;
if ( (pDataFlash->pDataFlashDesc->state) != IDLE)
return DATAFLASH_BUSY;
/* process the address to obtain page address and byte address */
adr = ((DataflashAddress / (pDataFlash->pDevice->pages_size)) << pDataFlash->pDevice->page_offset) + (DataflashAddress % (pDataFlash->pDevice->pages_size));
/* fill the command buffer */
pDataFlash->pDataFlashDesc->command[0] = OpCode;
pDataFlash->pDataFlashDesc->command[1] = (unsigned char)((adr & 0x00FF0000) >> 16);
pDataFlash->pDataFlashDesc->command[2] = (unsigned char)((adr & 0x0000FF00) >> 8);
pDataFlash->pDataFlashDesc->command[3] = (unsigned char)(adr & 0x000000FF) ;
pDataFlash->pDataFlashDesc->command[4] = 0;
pDataFlash->pDataFlashDesc->command[5] = 0;
pDataFlash->pDataFlashDesc->command[6] = 0;
pDataFlash->pDataFlashDesc->command[7] = 0;
/* Initialize the SpiData structure for the spi write fuction */
pDataFlash->pDataFlashDesc->tx_cmd_pt = pDataFlash->pDataFlashDesc->command ;
pDataFlash->pDataFlashDesc->tx_cmd_size = CmdSize ;
pDataFlash->pDataFlashDesc->rx_cmd_pt = pDataFlash->pDataFlashDesc->command ;
pDataFlash->pDataFlashDesc->rx_cmd_size = CmdSize ;
/* send the command and read the data */
return AT91F_SpiWrite (pDataFlash->pDataFlashDesc);
}
/*----------------------------------------------------------------------*/
/* \fn AT91F_DataFlashGetStatus */
/* \brief Read the status register of the dataflash */
/*----------------------------------------------------------------------*/
AT91S_DataFlashStatus AT91F_DataFlashGetStatus(AT91PS_DataflashDesc pDesc)
{
AT91S_DataFlashStatus status;
/* if a transfert is in progress ==> return 0 */
if( (pDesc->state) != IDLE)
return DATAFLASH_BUSY;
/* first send the read status command (D7H) */
pDesc->command[0] = DB_STATUS;
pDesc->command[1] = 0;
pDesc->DataFlash_state = GET_STATUS;
pDesc->tx_data_size = 0 ; /* Transmit the command and receive response */
pDesc->tx_cmd_pt = pDesc->command ;
pDesc->rx_cmd_pt = pDesc->command ;
pDesc->rx_cmd_size = 2 ;
pDesc->tx_cmd_size = 2 ;
status = AT91F_SpiWrite (pDesc);
pDesc->DataFlash_state = *( (unsigned char *) (pDesc->rx_cmd_pt) +1);
return status;
}
/*----------------------------------------------------------------------*/
/* \fn AT91F_DataFlashWaitReady */
/* \brief wait for dataflash ready (bit7 of the status register == 1) */
/*----------------------------------------------------------------------*/
AT91S_DataFlashStatus AT91F_DataFlashWaitReady(AT91PS_DataflashDesc pDataFlashDesc, unsigned int timeout)
{
pDataFlashDesc->DataFlash_state = IDLE;
do {
AT91F_DataFlashGetStatus(pDataFlashDesc);
timeout--;
}
while( ((pDataFlashDesc->DataFlash_state & 0x80) != 0x80) && (timeout > 0) );
if((pDataFlashDesc->DataFlash_state & 0x80) != 0x80)
return DATAFLASH_ERROR;
return DATAFLASH_OK;
}
/*------------------------------------------------------------------------------*/
/* Function Name : AT91F_DataFlashContinuousRead */
/* Object : Continuous stream Read */
/* Input Parameters : DataFlash Service */
/* : <src> = dataflash address */
/* : <*dataBuffer> = data buffer pointer */
/* : <sizeToRead> = data buffer size */
/* Return value : State of the dataflash */
/*------------------------------------------------------------------------------*/
AT91S_DataFlashStatus AT91F_DataFlashContinuousRead (
AT91PS_DataFlash pDataFlash,
int src,
unsigned char *dataBuffer,
int sizeToRead )
{
/* Test the size to read in the device */
if ( (src + sizeToRead) > (pDataFlash->pDevice->pages_size * (pDataFlash->pDevice->pages_number)))
return DATAFLASH_MEMORY_OVERFLOW;
pDataFlash->pDataFlashDesc->rx_data_pt = dataBuffer;
pDataFlash->pDataFlashDesc->rx_data_size = sizeToRead;
pDataFlash->pDataFlashDesc->tx_data_pt = dataBuffer;
pDataFlash->pDataFlashDesc->tx_data_size = sizeToRead;
/* Send the command to the dataflash */
return(AT91F_DataFlashSendCommand (pDataFlash, DB_CONTINUOUS_ARRAY_READ, 8, src));
}
/*------------------------------------------------------------------------------*/
/* Function Name : AT91F_DataFlashPagePgmBuf */
/* Object : Main memory page program through buffer 1 or buffer 2 */
/* Input Parameters : DataFlash Service */
/* : <*src> = Source buffer */
/* : <dest> = dataflash destination address */
/* : <SizeToWrite> = data buffer size */
/* Return value : State of the dataflash */
/*------------------------------------------------------------------------------*/
AT91S_DataFlashStatus AT91F_DataFlashPagePgmBuf(
AT91PS_DataFlash pDataFlash,
unsigned char *src,
unsigned int dest,
unsigned int SizeToWrite)
{
pDataFlash->pDataFlashDesc->tx_data_pt = src ;
pDataFlash->pDataFlashDesc->tx_data_size = SizeToWrite ;
pDataFlash->pDataFlashDesc->rx_data_pt = src;
pDataFlash->pDataFlashDesc->rx_data_size = SizeToWrite;
/* Send the command to the dataflash */
return(AT91F_DataFlashSendCommand (pDataFlash, DB_PAGE_PGM_BUF1, 4, dest));
}
/*------------------------------------------------------------------------------*/
/* Function Name : AT91F_MainMemoryToBufferTransfert */
/* Object : Read a page in the SRAM Buffer 1 or 2 */
/* Input Parameters : DataFlash Service */
/* : Page concerned */
/* : */
/* Return value : State of the dataflash */
/*------------------------------------------------------------------------------*/
AT91S_DataFlashStatus AT91F_MainMemoryToBufferTransfert(
AT91PS_DataFlash pDataFlash,
unsigned char BufferCommand,
unsigned int page)
{
/* Test if the buffer command is legal */
if ((BufferCommand != DB_PAGE_2_BUF1_TRF) && (BufferCommand != DB_PAGE_2_BUF2_TRF))
return DATAFLASH_BAD_COMMAND;
/* no data to transmit or receive */
pDataFlash->pDataFlashDesc->tx_data_size = 0;
return(AT91F_DataFlashSendCommand (pDataFlash, BufferCommand, 4, page*pDataFlash->pDevice->pages_size));
}
/*----------------------------------------------------------------------------- */
/* Function Name : AT91F_DataFlashWriteBuffer */
/* Object : Write data to the internal sram buffer 1 or 2 */
/* Input Parameters : DataFlash Service */
/* : <BufferCommand> = command to write buffer1 or buffer2 */
/* : <*dataBuffer> = data buffer to write */
/* : <bufferAddress> = address in the internal buffer */
/* : <SizeToWrite> = data buffer size */
/* Return value : State of the dataflash */
/*------------------------------------------------------------------------------*/
AT91S_DataFlashStatus AT91F_DataFlashWriteBuffer (
AT91PS_DataFlash pDataFlash,
unsigned char BufferCommand,
unsigned char *dataBuffer,
unsigned int bufferAddress,
int SizeToWrite )
{
/* Test if the buffer command is legal */
if ((BufferCommand != DB_BUF1_WRITE) && (BufferCommand != DB_BUF2_WRITE))
return DATAFLASH_BAD_COMMAND;
/* buffer address must be lower than page size */
if (bufferAddress > pDataFlash->pDevice->pages_size)
return DATAFLASH_BAD_ADDRESS;
if ( (pDataFlash->pDataFlashDesc->state) != IDLE)
return DATAFLASH_BUSY;
/* Send first Write Command */
pDataFlash->pDataFlashDesc->command[0] = BufferCommand;
pDataFlash->pDataFlashDesc->command[1] = 0;
pDataFlash->pDataFlashDesc->command[2] = (unsigned char)(((unsigned int)(bufferAddress & pDataFlash->pDevice->byte_mask)) >> 8) ;
pDataFlash->pDataFlashDesc->command[3] = (unsigned char)((unsigned int)bufferAddress & 0x00FF) ;
pDataFlash->pDataFlashDesc->tx_cmd_pt = pDataFlash->pDataFlashDesc->command ;
pDataFlash->pDataFlashDesc->tx_cmd_size = 4 ;
pDataFlash->pDataFlashDesc->rx_cmd_pt = pDataFlash->pDataFlashDesc->command ;
pDataFlash->pDataFlashDesc->rx_cmd_size = 4 ;
pDataFlash->pDataFlashDesc->rx_data_pt = dataBuffer ;
pDataFlash->pDataFlashDesc->tx_data_pt = dataBuffer ;
pDataFlash->pDataFlashDesc->rx_data_size = SizeToWrite ;
pDataFlash->pDataFlashDesc->tx_data_size = SizeToWrite ;
return AT91F_SpiWrite(pDataFlash->pDataFlashDesc);
}
/*------------------------------------------------------------------------------*/
/* Function Name : AT91F_WriteBufferToMain */
/* Object : Write buffer to the main memory */
/* Input Parameters : DataFlash Service */
/* : <BufferCommand> = command to send to buffer1 or buffer2 */
/* : <dest> = main memory address */
/* Return value : State of the dataflash */
/*------------------------------------------------------------------------------*/
AT91S_DataFlashStatus AT91F_WriteBufferToMain (
AT91PS_DataFlash pDataFlash,
unsigned char BufferCommand,
unsigned int dest )
{
/* Test if the buffer command is correct */
if ((BufferCommand != DB_BUF1_PAGE_PGM) &&
(BufferCommand != DB_BUF1_PAGE_ERASE_PGM) &&
(BufferCommand != DB_BUF2_PAGE_PGM) &&
(BufferCommand != DB_BUF2_PAGE_ERASE_PGM) )
return DATAFLASH_BAD_COMMAND;
/* no data to transmit or receive */
pDataFlash->pDataFlashDesc->tx_data_size = 0;
/* Send the command to the dataflash */
return(AT91F_DataFlashSendCommand (pDataFlash, BufferCommand, 4, dest));
}
/*------------------------------------------------------------------------------*/
/* Function Name : AT91F_PartialPageWrite */
/* Object : Erase partielly a page */
/* Input Parameters : <page> = page number */
/* : <AdrInpage> = adr to begin the fading */
/* : <length> = Number of bytes to erase */
/*------------------------------------------------------------------------------*/
AT91S_DataFlashStatus AT91F_PartialPageWrite (
AT91PS_DataFlash pDataFlash,
unsigned char *src,
unsigned int dest,
unsigned int size)
{
unsigned int page;
unsigned int AdrInPage;
page = dest / (pDataFlash->pDevice->pages_size);
AdrInPage = dest % (pDataFlash->pDevice->pages_size);
/* Read the contents of the page in the Sram Buffer */
AT91F_MainMemoryToBufferTransfert(pDataFlash, DB_PAGE_2_BUF1_TRF, page);
AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, 1000);
/*Update the SRAM buffer */
AT91F_DataFlashWriteBuffer(pDataFlash, DB_BUF1_WRITE, src, AdrInPage, size);
AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, 1000);
/* Rewrite the modified Sram Buffer in the main memory */
return(AT91F_WriteBufferToMain(pDataFlash, DB_BUF1_PAGE_ERASE_PGM, (page*pDataFlash->pDevice->pages_size)));
}
/*------------------------------------------------------------------------------*/
/* Function Name : AT91F_DataFlashWrite_Overloaded */
/* Object : */
/* Input Parameters : <*src> = Source buffer */
/* : <dest> = dataflash adress */
/* : <size> = data buffer size */
/*------------------------------------------------------------------------------*/
AT91S_DataFlashStatus AT91F_DataFlashWrite(
AT91PS_DataFlash pDataFlash,
unsigned char *src,
int dest,
int size )
{
unsigned int length;
AT91F_SpiEnable(pDataFlash->pDevice->cs);
if ( (dest + size) > (pDataFlash->pDevice->pages_size * (pDataFlash->pDevice->pages_number)))
return DATAFLASH_MEMORY_OVERFLOW;
/* If destination does not fit a page start address */
if ((dest % ((unsigned int)(pDataFlash->pDevice->pages_size))) != 0 ) {
length = pDataFlash->pDevice->pages_size - (dest % ((unsigned int)(pDataFlash->pDevice->pages_size)));
if (size < length)
length = size;
if(!AT91F_PartialPageWrite(pDataFlash,src, dest, length))
return DATAFLASH_ERROR;
AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, 1000);
/* Update size, source and destination pointers */
size -= length;
dest += length;
src += length;
}
while (( size - pDataFlash->pDevice->pages_size ) >= 0 ) {
/* program dataflash page */
if(!AT91F_DataFlashPagePgmBuf(pDataFlash, src, dest, pDataFlash->pDevice->pages_size ))
return DATAFLASH_ERROR;
AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, 1000);
/* Update size, source and destination pointers */
size -= pDataFlash->pDevice->pages_size ;
dest += pDataFlash->pDevice->pages_size ;
src += pDataFlash->pDevice->pages_size ;
}
/* If still some bytes to read */
if ( size > 0 ) {
/* program dataflash page */
if(!AT91F_PartialPageWrite(pDataFlash, src, dest, size) )
return DATAFLASH_ERROR;
AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, 1000);
}
return DATAFLASH_OK;
}
/*------------------------------------------------------------------------------*/
/* Function Name : AT91F_DataFlashRead */
/* Object : Read a block in dataflash */
/* Input Parameters : */
/* Return value : */
/*------------------------------------------------------------------------------*/
int AT91F_DataFlashRead(
AT91PS_DataFlash pDataFlash,
unsigned long addr,
unsigned long size,
char *buffer)
{
unsigned long SizeToRead;
AT91F_SpiEnable(pDataFlash->pDevice->cs);
if(AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, 1000) != DATAFLASH_OK)
return -1;
while (size) {
SizeToRead = (size < 0x8000)? size:0x8000;
if (AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, 1000) != DATAFLASH_OK)
return -1;
if (AT91F_DataFlashContinuousRead (pDataFlash, addr, buffer, SizeToRead) != DATAFLASH_OK)
return -1;
size -= SizeToRead;
addr += SizeToRead;
buffer += SizeToRead;
}
return DATAFLASH_OK;
}
/*------------------------------------------------------------------------------*/
/* Function Name : AT91F_DataflashProbe */
/* Object : */
/* Input Parameters : */
/* Return value : Dataflash status register */
/*------------------------------------------------------------------------------*/
int AT91F_DataflashProbe(int cs, AT91PS_DataflashDesc pDesc)
{
AT91F_SpiEnable(cs);
AT91F_DataFlashGetStatus(pDesc);
return((pDesc->command[1] == 0xFF)? 0: pDesc->command[1] & 0x3C);
}
#endif

View File

@@ -0,0 +1,468 @@
/*
* (C) Copyright 2003
* Author : Hamid Ikdoumi (Atmel)
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public 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 <at91rm9200_net.h>
#include <net.h>
/* ----- Ethernet Buffer definitions ----- */
typedef struct {
unsigned long addr, size;
} rbf_t;
#define RBF_ADDR 0xfffffffc
#define RBF_OWNER (1<<0)
#define RBF_WRAP (1<<1)
#define RBF_BROADCAST (1<<31)
#define RBF_MULTICAST (1<<30)
#define RBF_UNICAST (1<<29)
#define RBF_EXTERNAL (1<<28)
#define RBF_UNKOWN (1<<27)
#define RBF_SIZE 0x07ff
#define RBF_LOCAL4 (1<<26)
#define RBF_LOCAL3 (1<<25)
#define RBF_LOCAL2 (1<<24)
#define RBF_LOCAL1 (1<<23)
/* Emac Buffers in last 512KBytes of SDRAM*/
/* Be careful, buffer size is limited to 512KBytes !!! */
#define RBF_FRAMEMAX 100
/*#define RBF_FRAMEMEM 0x200000 */
#define RBF_FRAMEMEM 0x21F80000
#define RBF_FRAMELEN 0x600
#define RBF_FRAMEBTD RBF_FRAMEMEM
#define RBF_FRAMEBUF (RBF_FRAMEMEM + RBF_FRAMEMAX*sizeof(rbf_t))
#ifdef CONFIG_DRIVER_ETHER
#if (CONFIG_COMMANDS & CFG_CMD_NET)
/* structure to interface the PHY */
AT91S_PhyOps AT91S_Dm9161Ops;
AT91PS_PhyOps pPhyOps;
AT91PS_EMAC p_mac;
/*************************** Phy layer functions ************************/
/** functions to interface the DAVICOM 10/100Mbps ethernet phy **********/
/*
* Name:
* dm9161_IsPhyConnected
* Description:
* Reads the 2 PHY ID registers
* Arguments:
* p_mac - pointer to AT91S_EMAC struct
* Return value:
* TRUE - if id read successfully
* FALSE- if error
*/
static unsigned int dm9161_IsPhyConnected (AT91PS_EMAC p_mac)
{
unsigned short Id1, Id2;
at91rm9200_EmacEnableMDIO (p_mac);
at91rm9200_EmacReadPhy (p_mac, DM9161_PHYID1, &Id1);
at91rm9200_EmacReadPhy (p_mac, DM9161_PHYID2, &Id2);
at91rm9200_EmacDisableMDIO (p_mac);
if ((Id1 == (DM9161_PHYID1_OUI >> 6)) &&
((Id2 >> 10) == (DM9161_PHYID1_OUI & DM9161_LSB_MASK)))
return TRUE;
return FALSE;
}
/*
* Name:
* dm9161_GetLinkSpeed
* Description:
* Link parallel detection status of MAC is checked and set in the
* MAC configuration registers
* Arguments:
* p_mac - pointer to MAC
* Return value:
* TRUE - if link status set succesfully
* FALSE - if link status not set
*/
static UCHAR dm9161_GetLinkSpeed (AT91PS_EMAC p_mac)
{
unsigned short stat1, stat2;
if (!at91rm9200_EmacReadPhy (p_mac, DM9161_BMSR, &stat1))
return FALSE;
if (!(stat1 & DM9161_LINK_STATUS)) /* link status up? */
return FALSE;
if (!at91rm9200_EmacReadPhy (p_mac, DM9161_DSCSR, &stat2))
return FALSE;
if ((stat1 & DM9161_100BASE_TX_FD) && (stat2 & DM9161_100FDX)) {
/*set Emac for 100BaseTX and Full Duplex */
p_mac->EMAC_CFG |= AT91C_EMAC_SPD | AT91C_EMAC_FD;
return TRUE;
}
if ((stat1 & DM9161_10BASE_T_FD) && (stat2 & DM9161_10FDX)) {
/*set MII for 10BaseT and Full Duplex */
p_mac->EMAC_CFG = (p_mac->EMAC_CFG &
~(AT91C_EMAC_SPD | AT91C_EMAC_FD))
| AT91C_EMAC_FD;
return TRUE;
}
if ((stat1 & DM9161_100BASE_T4_HD) && (stat2 & DM9161_100HDX)) {
/*set MII for 100BaseTX and Half Duplex */
p_mac->EMAC_CFG = (p_mac->EMAC_CFG &
~(AT91C_EMAC_SPD | AT91C_EMAC_FD))
| AT91C_EMAC_SPD;
return TRUE;
}
if ((stat1 & DM9161_10BASE_T_HD) && (stat2 & DM9161_10HDX)) {
/*set MII for 10BaseT and Half Duplex */
p_mac->EMAC_CFG &= ~(AT91C_EMAC_SPD | AT91C_EMAC_FD);
return TRUE;
}
return FALSE;
}
/*
* Name:
* dm9161_InitPhy
* Description:
* MAC starts checking its link by using parallel detection and
* Autonegotiation and the same is set in the MAC configuration registers
* Arguments:
* p_mac - pointer to struct AT91S_EMAC
* Return value:
* TRUE - if link status set succesfully
* FALSE - if link status not set
*/
static UCHAR dm9161_InitPhy (AT91PS_EMAC p_mac)
{
UCHAR ret = TRUE;
unsigned short IntValue;
at91rm9200_EmacEnableMDIO (p_mac);
if (!dm9161_GetLinkSpeed (p_mac)) {
/* Try another time */
ret = dm9161_GetLinkSpeed (p_mac);
}
/* Disable PHY Interrupts */
at91rm9200_EmacReadPhy (p_mac, DM9161_MDINTR, &IntValue);
/* clear FDX, SPD, Link, INTR masks */
IntValue &= ~(DM9161_FDX_MASK | DM9161_SPD_MASK |
DM9161_LINK_MASK | DM9161_INTR_MASK);
at91rm9200_EmacWritePhy (p_mac, DM9161_MDINTR, &IntValue);
at91rm9200_EmacDisableMDIO (p_mac);
return (ret);
}
/*
* Name:
* dm9161_AutoNegotiate
* Description:
* MAC Autonegotiates with the partner status of same is set in the
* MAC configuration registers
* Arguments:
* dev - pointer to struct net_device
* Return value:
* TRUE - if link status set successfully
* FALSE - if link status not set
*/
static UCHAR dm9161_AutoNegotiate (AT91PS_EMAC p_mac, int *status)
{
unsigned short value;
unsigned short PhyAnar;
unsigned short PhyAnalpar;
/* Set dm9161 control register */
if (!at91rm9200_EmacReadPhy (p_mac, DM9161_BMCR, &value))
return FALSE;
value &= ~DM9161_AUTONEG; /* remove autonegotiation enable */
value |= DM9161_ISOLATE; /* Electrically isolate PHY */
if (!at91rm9200_EmacWritePhy (p_mac, DM9161_BMCR, &value))
return FALSE;
/* Set the Auto_negotiation Advertisement Register */
/* MII advertising for Next page, 100BaseTxFD and HD, 10BaseTFD and HD, IEEE 802.3 */
PhyAnar = DM9161_NP | DM9161_TX_FDX | DM9161_TX_HDX |
DM9161_10_FDX | DM9161_10_HDX | DM9161_AN_IEEE_802_3;
if (!at91rm9200_EmacWritePhy (p_mac, DM9161_ANAR, &PhyAnar))
return FALSE;
/* Read the Control Register */
if (!at91rm9200_EmacReadPhy (p_mac, DM9161_BMCR, &value))
return FALSE;
value |= DM9161_SPEED_SELECT | DM9161_AUTONEG | DM9161_DUPLEX_MODE;
if (!at91rm9200_EmacWritePhy (p_mac, DM9161_BMCR, &value))
return FALSE;
/* Restart Auto_negotiation */
value |= DM9161_RESTART_AUTONEG;
if (!at91rm9200_EmacWritePhy (p_mac, DM9161_BMCR, &value))
return FALSE;
/*check AutoNegotiate complete */
udelay (10000);
at91rm9200_EmacReadPhy (p_mac, DM9161_BMSR, &value);
if (!(value & DM9161_AUTONEG_COMP))
return FALSE;
/* Get the AutoNeg Link partner base page */
if (!at91rm9200_EmacReadPhy (p_mac, DM9161_ANLPAR, &PhyAnalpar))
return FALSE;
if ((PhyAnar & DM9161_TX_FDX) && (PhyAnalpar & DM9161_TX_FDX)) {
/*set MII for 100BaseTX and Full Duplex */
p_mac->EMAC_CFG |= AT91C_EMAC_SPD | AT91C_EMAC_FD;
return TRUE;
}
if ((PhyAnar & DM9161_10_FDX) && (PhyAnalpar & DM9161_10_FDX)) {
/*set MII for 10BaseT and Full Duplex */
p_mac->EMAC_CFG = (p_mac->EMAC_CFG &
~(AT91C_EMAC_SPD | AT91C_EMAC_FD))
| AT91C_EMAC_FD;
return TRUE;
}
return FALSE;
}
/*********** EMAC Phy layer Management functions *************************/
/*
* Name:
* at91rm9200_EmacEnableMDIO
* Description:
* Enables the MDIO bit in MAC control register
* Arguments:
* p_mac - pointer to struct AT91S_EMAC
* Return value:
* none
*/
static void at91rm9200_EmacEnableMDIO (AT91PS_EMAC p_mac)
{
/* Mac CTRL reg set for MDIO enable */
p_mac->EMAC_CTL |= AT91C_EMAC_MPE; /* Management port enable */
}
/*
* Name:
* at91rm9200_EmacDisableMDIO
* Description:
* Disables the MDIO bit in MAC control register
* Arguments:
* p_mac - pointer to struct AT91S_EMAC
* Return value:
* none
*/
static void at91rm9200_EmacDisableMDIO (AT91PS_EMAC p_mac)
{
/* Mac CTRL reg set for MDIO disable */
p_mac->EMAC_CTL &= ~AT91C_EMAC_MPE; /* Management port disable */
}
/*
* Name:
* at91rm9200_EmacReadPhy
* Description:
* Reads data from the PHY register
* Arguments:
* dev - pointer to struct net_device
* RegisterAddress - unsigned char
* pInput - pointer to value read from register
* Return value:
* TRUE - if data read successfully
*/
static UCHAR at91rm9200_EmacReadPhy (AT91PS_EMAC p_mac,
unsigned char RegisterAddress,
unsigned short *pInput)
{
p_mac->EMAC_MAN = (AT91C_EMAC_HIGH & ~AT91C_EMAC_LOW) |
(AT91C_EMAC_CODE_802_3) | (AT91C_EMAC_RW_R) |
(RegisterAddress << 18);
udelay (10000);
*pInput = (unsigned short) p_mac->EMAC_MAN;
return TRUE;
}
/*
* Name:
* at91rm9200_EmacWritePhy
* Description:
* Writes data to the PHY register
* Arguments:
* dev - pointer to struct net_device
* RegisterAddress - unsigned char
* pOutput - pointer to value to be written in the register
* Return value:
* TRUE - if data read successfully
*/
static UCHAR at91rm9200_EmacWritePhy (AT91PS_EMAC p_mac,
unsigned char RegisterAddress,
unsigned short *pOutput)
{
p_mac->EMAC_MAN = (AT91C_EMAC_HIGH & ~AT91C_EMAC_LOW) |
AT91C_EMAC_CODE_802_3 | AT91C_EMAC_RW_W |
(RegisterAddress << 18);
udelay (10000);
return TRUE;
}
/*
* Name:
* at91rm92000_GetPhyInterface
* Description:
* Initialise the interface functions to the PHY
* Arguments:
* None
* Return value:
* None
*/
void at91rm92000_GetPhyInterface (void)
{
AT91S_Dm9161Ops.Init = dm9161_InitPhy;
AT91S_Dm9161Ops.IsPhyConnected = dm9161_IsPhyConnected;
AT91S_Dm9161Ops.GetLinkSpeed = dm9161_GetLinkSpeed;
AT91S_Dm9161Ops.AutoNegotiate = dm9161_AutoNegotiate;
pPhyOps = (AT91PS_PhyOps) & AT91S_Dm9161Ops;
}
rbf_t *rbfdt;
rbf_t *rbfp;
int eth_init (bd_t * bd)
{
int ret;
int i;
p_mac = AT91C_BASE_EMAC;
*AT91C_PIOA_PDR = AT91C_PA16_EMDIO | AT91C_PA15_EMDC | AT91C_PA14_ERXER | AT91C_PA13_ERX1 | AT91C_PA12_ERX0 | AT91C_PA11_ECRS_ECRSDV | AT91C_PA10_ETX1 | AT91C_PA9_ETX0 | AT91C_PA8_ETXEN | AT91C_PA7_ETXCK_EREFCK; /* PIO Disable Register */
*AT91C_PIOB_PDR = AT91C_PB25_EF100 |
AT91C_PB19_ERXCK | AT91C_PB18_ECOL | AT91C_PB17_ERXDV |
AT91C_PB16_ERX3 | AT91C_PB15_ERX2 | AT91C_PB14_ETXER |
AT91C_PB13_ETX3 | AT91C_PB12_ETX2;
*AT91C_PIOB_BSR = AT91C_PB25_EF100 | AT91C_PB19_ERXCK | AT91C_PB18_ECOL | AT91C_PB17_ERXDV | AT91C_PB16_ERX3 | AT91C_PB15_ERX2 | AT91C_PB14_ETXER | AT91C_PB13_ETX3 | AT91C_PB12_ETX2; /* Select B Register */
*AT91C_PMC_PCER = 1 << AT91C_ID_EMAC; /* Peripheral Clock Enable Register */
p_mac->EMAC_CFG |= AT91C_EMAC_CSR; /* Clear statistics */
/* Init Ehternet buffers */
rbfdt = (rbf_t *) RBF_FRAMEBTD;
for (i = 0; i < RBF_FRAMEMAX; i++) {
rbfdt[i].addr = RBF_FRAMEBUF + RBF_FRAMELEN * i;
rbfdt[i].size = 0;
}
rbfdt[RBF_FRAMEMAX - 1].addr |= RBF_WRAP;
rbfp = &rbfdt[0];
at91rm92000_GetPhyInterface ();
if (!pPhyOps->IsPhyConnected (p_mac))
printf ("PHY not connected!!\n\r");
/* MII management start from here */
if (!(p_mac->EMAC_SR & AT91C_EMAC_LINK)) {
if (!(ret = pPhyOps->Init (p_mac))) {
printf ("MAC: error during MII initialization\n");
return 0;
}
} else {
printf ("No link\n\r");
return 0;
}
p_mac->EMAC_SA2L = (bd->bi_enetaddr[3] << 24) | (bd->bi_enetaddr[2] << 16)
| (bd->bi_enetaddr[1] << 8) | (bd->bi_enetaddr[0]);
p_mac->EMAC_SA2H = (bd->bi_enetaddr[5] << 8) | (bd->bi_enetaddr[4]);
p_mac->EMAC_RBQP = (long) (&rbfdt[0]);
p_mac->EMAC_RSR &= ~(AT91C_EMAC_RSR_OVR | AT91C_EMAC_REC | AT91C_EMAC_BNA);
p_mac->EMAC_CFG = (p_mac->EMAC_CFG | AT91C_EMAC_CAF | AT91C_EMAC_NBC | AT91C_EMAC_RMII)
& ~AT91C_EMAC_CLK;
p_mac->EMAC_CTL |= AT91C_EMAC_TE | AT91C_EMAC_RE;
return 0;
}
int eth_send (volatile void *packet, int length)
{
while (!(p_mac->EMAC_TSR & AT91C_EMAC_BNQ));
p_mac->EMAC_TAR = (long) packet;
p_mac->EMAC_TCR = length;
while (p_mac->EMAC_TCR & 0x7ff);
p_mac->EMAC_TSR |= AT91C_EMAC_COMP;
return 0;
}
int eth_rx (void)
{
int size;
if (!(rbfp->addr & RBF_OWNER))
return 0;
size = rbfp->size & RBF_SIZE;
NetReceive ((volatile uchar *) (rbfp->addr & RBF_ADDR), size);
rbfp->addr &= ~RBF_OWNER;
if (rbfp->addr & RBF_WRAP)
rbfp = &rbfdt[0];
else
rbfp++;
p_mac->EMAC_RSR |= AT91C_EMAC_REC;
return size;
}
void eth_halt (void)
{
};
#endif /* CONFIG_COMMANDS & CFG_CMD_NET */
#endif /* CONFIG_DRIVER_ETHER */

View File

@@ -35,7 +35,7 @@ include $(TOPDIR)/config.mk
LIB = lib$(CPU).a
START = start.S
OBJS = serial.o cpu.o cpu_init.o interrupts.o traps.o speed.o status_led.o
OBJS = serial.o cpu.o cpu_init.o interrupts.o traps.o speed.o
all: .depend $(START) $(LIB)

View File

@@ -1,161 +0,0 @@
/*
* (C) Copyright 2000-2002 Wolfgang Denk, DENX Software Engineering, wd@denx.de
* (C) Copyright 2003 Martin Winistoerfer, martinwinistoerfer@gmx.ch.
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
/*
* File: status_led.c
*
* Discription: Blink a board led to show boot progress. Led's
* are connected via the MIOS module.
*/
#include <common.h>
#include <mpc5xx.h>
#include <status_led.h>
#ifdef CONFIG_STATUS_LED
typedef struct {
ulong mask;
int state;
int period;
int cnt;
} led_dev_t;
led_dev_t led_dev[] = {
{ STATUS_LED_BIT,
STATUS_LED_STATE,
STATUS_LED_PERIOD,
0,
},
#if defined(STATUS_LED_BIT1)
{ STATUS_LED_BIT1,
STATUS_LED_STATE1,
STATUS_LED_PERIOD1,
0,
},
#endif
#if defined(STATUS_LED_BIT2)
{ STATUS_LED_BIT2,
STATUS_LED_STATE2,
STATUS_LED_PERIOD2,
0,
},
#endif
#if defined(STATUS_LED_BIT3)
{ STATUS_LED_BIT3,
STATUS_LED_STATE3,
STATUS_LED_PERIOD3,
0,
},
#endif
};
#define MAX_LED_DEV (sizeof(led_dev)/sizeof(led_dev_t))
static int status_led_init_done = 0;
static void status_led_init (void)
{
volatile immap_t *immr = (immap_t *)CFG_IMMR;
int i;
for (i=0; i<MAX_LED_DEV; ++i) {
led_dev_t *ld = &led_dev[i];
immr->STATUS_LED_DIR = STATUS_LED_BIT;
#if (STATUS_LED_ACTIVE == 0)
if (ld->state == STATUS_LED_ON)
immr->STATUS_LED_DAT &= ~(ld->mask);
else
immr->STATUS_LED_DAT |= ld->mask ;
#else
if (ld->state == STATUS_LED_ON)
immr->STATUS_LED_DAT |= ld->mask ;
else
immr->STATUS_LED_DAT &= ~(ld->mask);
#endif
}
status_led_init_done = 1;
}
void status_led_tick (ulong timestamp)
{
volatile immap_t *immr = (immap_t *)CFG_IMMR;
int i;
if (!status_led_init_done)
status_led_init();
for (i=0; i<MAX_LED_DEV; ++i) {
led_dev_t *ld = &led_dev[i];
if (ld->state != STATUS_LED_BLINKING)
continue;
if (++(ld->cnt) >= ld->period) {
immr->STATUS_LED_DAT ^= ld->mask;
ld->cnt -= ld->period;
}
}
}
void status_led_set (int led, int state)
{
volatile immap_t *immr = (immap_t *)CFG_IMMR;
led_dev_t *ld;
if (led < 0 || led >= MAX_LED_DEV)
return;
if (!status_led_init_done)
status_led_init();
ld = &led_dev[led];
switch (state) {
default:
return;
case STATUS_LED_BLINKING:
ld->cnt = 0; /* always start with full period */
/* fall through */ /* always start with LED _ON_ */
case STATUS_LED_ON:
#if (STATUS_LED_ACTIVE == 0)
immr->STATUS_LED_DAT &= ~(ld->mask);
#else
immr->STATUS_LED_DAT |= ld->mask ;
#endif
break;
case STATUS_LED_OFF:
#if (STATUS_LED_ACTIVE == 0)
immr->STATUS_LED_DAT |= ld->mask ;
#else
immr->STATUS_LED_DAT &= ~(ld->mask);
#endif
break;
}
ld->state = state;
}
#endif /* CONFIG_STATUS_LED */

View File

@@ -28,7 +28,7 @@ LIB = lib$(CPU).a
START = start.o kgdb.o
OBJS = traps.o serial_smc.o serial_scc.o cpu.o cpu_init.o speed.o \
interrupts.o ether_scc.o ether_fcc.o i2c.o commproc.o \
bedbug_603e.o status_led.o pci.o spi.o
bedbug_603e.o pci.o spi.o
all: .depend $(START) $(LIB)

View File

@@ -23,5 +23,5 @@
PLATFORM_RELFLAGS += -mrelocatable -ffixed-r14 -meabi
PLATFORM_CPPFLAGS += -DCONFIG_8260 -ffixed-r2 -ffixed-r29 -mstring
##PLATFORM_CPPFLAGS += -DCONFIG_8260 -ffixed-r2 -mstring
PLATFORM_CPPFLAGS += -DCONFIG_8260 -ffixed-r2 -ffixed-r29 \
-mstring -mcpu=603e -mmultiple

View File

@@ -80,9 +80,9 @@ static void config_8260_ioports (volatile immap_t * immr)
*/
iop->ppar &= tpmsk;
iop->psor = (iop->psor & tpmsk) | psor;
iop->podr = (iop->podr & tpmsk) | podr;
iop->pdat = (iop->pdat & tpmsk) | pdat;
iop->pdir = (iop->pdir & tpmsk) | pdir;
iop->podr = (iop->podr & tpmsk) | podr;
iop->ppar |= ppar;
}
}

View File

@@ -391,4 +391,761 @@ int fec_initialize(bd_t *bis)
return 1;
}
#ifdef CONFIG_ETHER_LOOPBACK_TEST
#define ELBT_BUFSZ 1024 /* must be multiple of 32 */
#define ELBT_CRCSZ 4
#define ELBT_NRXBD 4 /* must be at least 2 */
#define ELBT_NTXBD 4
#define ELBT_MAXRXERR 32
#define ELBT_MAXTXERR 32
#define ELBT_CLSWAIT 1000 /* msec to wait for further input frames */
typedef
struct {
uint off;
char *lab;
}
elbt_prdesc;
typedef
struct {
uint _l, _f, m, bc, mc, lg, no, sh, cr, ov, cl;
uint badsrc, badtyp, badlen, badbit;
}
elbt_rxeacc;
static elbt_prdesc rxeacc_descs[] = {
{ offsetof(elbt_rxeacc, _l), "Not Last in Frame" },
{ offsetof(elbt_rxeacc, _f), "Not First in Frame" },
{ offsetof(elbt_rxeacc, m), "Address Miss" },
{ offsetof(elbt_rxeacc, bc), "Broadcast Address" },
{ offsetof(elbt_rxeacc, mc), "Multicast Address" },
{ offsetof(elbt_rxeacc, lg), "Frame Length Violation"},
{ offsetof(elbt_rxeacc, no), "Non-Octet Alignment" },
{ offsetof(elbt_rxeacc, sh), "Short Frame" },
{ offsetof(elbt_rxeacc, cr), "CRC Error" },
{ offsetof(elbt_rxeacc, ov), "Overrun" },
{ offsetof(elbt_rxeacc, cl), "Collision" },
{ offsetof(elbt_rxeacc, badsrc), "Bad Src Address" },
{ offsetof(elbt_rxeacc, badtyp), "Bad Frame Type" },
{ offsetof(elbt_rxeacc, badlen), "Bad Frame Length" },
{ offsetof(elbt_rxeacc, badbit), "Data Compare Errors" },
};
static int rxeacc_ndesc = sizeof (rxeacc_descs) / sizeof (rxeacc_descs[0]);
typedef
struct {
uint def, hb, lc, rl, rc, un, csl;
}
elbt_txeacc;
static elbt_prdesc txeacc_descs[] = {
{ offsetof(elbt_txeacc, def), "Defer Indication" },
{ offsetof(elbt_txeacc, hb), "Heartbeat" },
{ offsetof(elbt_txeacc, lc), "Late Collision" },
{ offsetof(elbt_txeacc, rl), "Retransmission Limit" },
{ offsetof(elbt_txeacc, rc), "Retry Count" },
{ offsetof(elbt_txeacc, un), "Underrun" },
{ offsetof(elbt_txeacc, csl), "Carrier Sense Lost" },
};
static int txeacc_ndesc = sizeof (txeacc_descs) / sizeof (txeacc_descs[0]);
typedef
struct {
uchar rxbufs[ELBT_NRXBD][ELBT_BUFSZ];
uchar txbufs[ELBT_NTXBD][ELBT_BUFSZ];
cbd_t rxbd[ELBT_NRXBD];
cbd_t txbd[ELBT_NTXBD];
enum { Idle, Running, Closing, Closed } state;
int proff, page, sblock;
uint clstime, nsent, ntxerr, nrcvd, nrxerr;
ushort rxerrs[ELBT_MAXRXERR], txerrs[ELBT_MAXTXERR];
elbt_rxeacc rxeacc;
elbt_txeacc txeacc;
} __attribute__ ((aligned(8)))
elbt_chan;
static uchar patbytes[ELBT_NTXBD] = {
0xff, 0xaa, 0x55, 0x00
};
static uint patwords[ELBT_NTXBD] = {
0xffffffff, 0xaaaaaaaa, 0x55555555, 0x00000000
};
#ifdef __GNUC__
static elbt_chan elbt_chans[3] __attribute__ ((aligned(8)));
#else
#error "elbt_chans must be 64-bit aligned"
#endif
#define CPM_CR_GRACEFUL_STOP_TX ((ushort)0x0005)
static elbt_prdesc epram_descs[] = {
{ offsetof(fcc_enet_t, fen_crcec), "CRC Errors" },
{ offsetof(fcc_enet_t, fen_alec), "Alignment Errors" },
{ offsetof(fcc_enet_t, fen_disfc), "Discarded Frames" },
{ offsetof(fcc_enet_t, fen_octc), "Octets" },
{ offsetof(fcc_enet_t, fen_colc), "Collisions" },
{ offsetof(fcc_enet_t, fen_broc), "Broadcast Frames" },
{ offsetof(fcc_enet_t, fen_mulc), "Multicast Frames" },
{ offsetof(fcc_enet_t, fen_uspc), "Undersize Frames" },
{ offsetof(fcc_enet_t, fen_frgc), "Fragments" },
{ offsetof(fcc_enet_t, fen_ospc), "Oversize Frames" },
{ offsetof(fcc_enet_t, fen_jbrc), "Jabbers" },
{ offsetof(fcc_enet_t, fen_p64c), "64 Octet Frames" },
{ offsetof(fcc_enet_t, fen_p65c), "65-127 Octet Frames" },
{ offsetof(fcc_enet_t, fen_p128c), "128-255 Octet Frames" },
{ offsetof(fcc_enet_t, fen_p256c), "256-511 Octet Frames" },
{ offsetof(fcc_enet_t, fen_p512c), "512-1023 Octet Frames" },
{ offsetof(fcc_enet_t, fen_p1024c), "1024-1518 Octet Frames"},
};
static int epram_ndesc = sizeof (epram_descs) / sizeof (epram_descs[0]);
/*
* given an elbt_prdesc array and an array of base addresses, print
* each prdesc down the screen with the values fetched from each
* base address across the screen
*/
static void
print_desc (elbt_prdesc descs[], int ndesc, uchar *bases[], int nbase)
{
elbt_prdesc *dp = descs, *edp = dp + ndesc;
int i;
printf ("%32s", "");
for (i = 0; i < nbase; i++)
printf (" Channel %d", i);
puts ("\n");
while (dp < edp) {
printf ("%-32s", dp->lab);
for (i = 0; i < nbase; i++) {
uint val = *(uint *)(bases[i] + dp->off);
printf (" %10u", val);
}
puts ("\n");
dp++;
}
}
/*
* return number of bits that are set in a value; value contains
* nbits (right-justified) bits.
*/
static uint __inline__
nbs (uint value, uint nbits)
{
uint cnt = 0;
#if 1
uint pos = sizeof (uint) * 8;
__asm__ __volatile__ ("\
mtctr %2\n\
1: rlwnm. %2,%1,%4,31,31\n\
beq 2f\n\
addi %0,%0,1\n\
2: subi %4,%4,1\n\
bdnz 1b"
: "=r"(cnt)
: "r"(value), "r"(nbits), "r"(cnt), "r"(pos)
: "ctr", "cc" );
#else
uint mask = 1;
do {
if (value & mask)
cnt++;
mask <<= 1;
} while (--nbits);
#endif
return (cnt);
}
static ulong
badbits (uchar *bp, int n, ulong pat)
{
ulong *lp, cnt = 0;
int nl;
while (n > 0 && ((ulong)bp & (sizeof (ulong) - 1)) != 0) {
uchar diff;
diff = *bp++ ^ (uchar)pat;
if (diff)
cnt += nbs ((ulong)diff, 8);
n--;
}
lp = (ulong *)bp;
nl = n / sizeof (ulong);
n -= nl * sizeof (ulong);
while (nl > 0) {
ulong diff;
diff = *lp++ ^ pat;
if (diff)
cnt += nbs (diff, 32);
nl--;
}
bp = (uchar *)lp;
while (n > 0) {
uchar diff;
diff = *bp++ ^ (uchar)pat;
if (diff)
cnt += nbs ((ulong)diff, 8);
n--;
}
return (cnt);
}
static inline unsigned short
swap16 (unsigned short x)
{
return (((x & 0xff) << 8) | ((x & 0xff00) >> 8));
}
void
eth_loopback_test (void)
{
DECLARE_GLOBAL_DATA_PTR;
volatile immap_t *immr = (immap_t *)CFG_IMMR;
volatile cpm8260_t *cp = &(immr->im_cpm);
int c, nclosed;
ulong runtime, nmsec;
uchar *bases[3];
puts ("FCC Ethernet External loopback test\n");
memcpy (NetOurEther, gd->bd->bi_enetaddr, 6);
/*
* global initialisations for all FCC channels
*/
/* 28.9 - (1-2): ioports have been set up already */
#if defined(CONFIG_HYMOD)
/*
* Attention: this is board-specific
* - FCC1 Rx-CLK is CLK10
* - FCC1 Tx-CLK is CLK11
* - FCC2 Rx-CLK is CLK13
* - FCC2 Tx-CLK is CLK14
* - FCC3 Rx-CLK is CLK15
* - FCC3 Tx-CLK is CLK16
*/
/* 28.9 - (3): connect FCC's tx and rx clocks */
immr->im_cpmux.cmx_uar = 0;
immr->im_cpmux.cmx_fcr = CMXFCR_RF1CS_CLK10|CMXFCR_TF1CS_CLK11|\
CMXFCR_RF2CS_CLK13|CMXFCR_TF2CS_CLK14|\
CMXFCR_RF3CS_CLK15|CMXFCR_TF3CS_CLK16;
#else
#error "eth_loopback_test not supported on your board"
#endif
puts ("Initialise FCC channels:");
for (c = 0; c < 3; c++) {
elbt_chan *ecp = &elbt_chans[c];
volatile fcc_t *fcp = &immr->im_fcc[c];
volatile fcc_enet_t *fpp;
int i;
ulong addr;
/*
* initialise channel data
*/
printf (" %d", c);
memset ((void *)ecp, 0, sizeof (*ecp));
ecp->state = Idle;
switch (c) {
case 0: /* FCC1 */
ecp->proff = PROFF_FCC1;
ecp->page = CPM_CR_FCC1_PAGE;
ecp->sblock = CPM_CR_FCC1_SBLOCK;
break;
case 1: /* FCC2 */
ecp->proff = PROFF_FCC2;
ecp->page = CPM_CR_FCC2_PAGE;
ecp->sblock = CPM_CR_FCC2_SBLOCK;
break;
case 2: /* FCC3 */
ecp->proff = PROFF_FCC3;
ecp->page = CPM_CR_FCC3_PAGE;
ecp->sblock = CPM_CR_FCC3_SBLOCK;
break;
}
/*
* set up tx buffers and bds
*/
for (i = 0; i < ELBT_NTXBD; i++) {
cbd_t *bdp = &ecp->txbd[i];
uchar *bp = &ecp->txbufs[i][0];
bdp->cbd_bufaddr = (uint)bp;
/* room for crc */
bdp->cbd_datlen = ELBT_BUFSZ - ELBT_CRCSZ;
bdp->cbd_sc = BD_ENET_TX_READY | BD_ENET_TX_PAD | \
BD_ENET_TX_LAST | BD_ENET_TX_TC;
memset ((void *)bp, patbytes[i], ELBT_BUFSZ);
NetSetEther (bp, NetBcastAddr, 0x8000);
}
ecp->txbd[ELBT_NTXBD - 1].cbd_sc |= BD_ENET_TX_WRAP;
/*
* set up rx buffers and bds
*/
for (i = 0; i < ELBT_NRXBD; i++) {
cbd_t *bdp = &ecp->rxbd[i];
uchar *bp = &ecp->rxbufs[i][0];
bdp->cbd_bufaddr = (uint)bp;
bdp->cbd_datlen = 0;
bdp->cbd_sc = BD_ENET_RX_EMPTY;
memset ((void *)bp, 0, ELBT_BUFSZ);
}
ecp->rxbd[ELBT_NRXBD - 1].cbd_sc |= BD_ENET_RX_WRAP;
/*
* set up the FCC channel hardware
*/
/* 28.9 - (4): GFMR: disable tx/rx, CCITT CRC, Mode Ethernet */
fcp->fcc_gfmr = FCC_GFMR_MODE_ENET | FCC_GFMR_TCRC_32;
/* 28.9 - (5): FPSMR: fd, enet CRC, Promis, RMON, Rx SHort */
fcp->fcc_fpsmr = FCC_PSMR_FDE | FCC_PSMR_LPB | \
FCC_PSMR_ENCRC | FCC_PSMR_PRO | \
FCC_PSMR_MON | FCC_PSMR_RSH;
/* 28.9 - (6): FDSR: Ethernet Syn */
fcp->fcc_fdsr = 0xD555;
/* 29.9 - (7): initialise parameter ram */
fpp = (fcc_enet_t *)&(immr->im_dprambase[ecp->proff]);
/* clear whole struct to make sure all resv fields are zero */
memset ((void *)fpp, 0, sizeof (fcc_enet_t));
/*
* common Parameter RAM area
*
* Allocate space in the reserved FCC area of DPRAM for the
* internal buffers. No one uses this space (yet), so we
* can do this. Later, we will add resource management for
* this area.
*/
addr = CPM_FCC_SPECIAL_BASE + (c * 64);
fpp->fen_genfcc.fcc_riptr = addr;
fpp->fen_genfcc.fcc_tiptr = addr + 32;
/*
* Set maximum bytes per receive buffer.
* It must be a multiple of 32.
* buffers are in 60x bus memory.
*/
fpp->fen_genfcc.fcc_mrblr = PKT_MAXBLR_SIZE;
fpp->fen_genfcc.fcc_rstate = (CPMFCR_GBL | CPMFCR_EB) << 24;
fpp->fen_genfcc.fcc_rbase = (unsigned int)(&ecp->rxbd[0]);
fpp->fen_genfcc.fcc_tstate = (CPMFCR_GBL | CPMFCR_EB) << 24;
fpp->fen_genfcc.fcc_tbase = (unsigned int)(&ecp->txbd[0]);
/* protocol-specific area */
fpp->fen_cmask = 0xdebb20e3; /* CRC mask */
fpp->fen_cpres = 0xffffffff; /* CRC preset */
fpp->fen_retlim = 15; /* Retry limit threshold */
fpp->fen_mflr = PKT_MAXBUF_SIZE;/* max frame length register */
/*
* Set Ethernet station address.
*
* This is supplied in the board information structure, so we
* copy that into the controller.
* So, far we have only been given one Ethernet address. We use
* the same address for all channels
*/
#define ea gd->bd->bi_enetaddr
fpp->fen_paddrh = (ea[5] << 8) + ea[4];
fpp->fen_paddrm = (ea[3] << 8) + ea[2];
fpp->fen_paddrl = (ea[1] << 8) + ea[0];
#undef ea
fpp->fen_minflr = PKT_MINBUF_SIZE; /* min frame len register */
/*
* pad pointer. use tiptr since we don't need
* a specific padding char
*/
fpp->fen_padptr = fpp->fen_genfcc.fcc_tiptr;
fpp->fen_maxd1 = PKT_MAXDMA_SIZE; /* max DMA1 length */
fpp->fen_maxd2 = PKT_MAXDMA_SIZE; /* max DMA2 length */
fpp->fen_rfthr = 1;
fpp->fen_rfcnt = 1;
/* 28.9 - (8): clear out events in FCCE */
fcp->fcc_fcce = ~0x0;
/* 28.9 - (9): FCCM: mask all events */
fcp->fcc_fccm = 0;
/* 28.9 - (10-12): we don't use ethernet interrupts */
/* 28.9 - (13)
*
* Let's re-initialize the channel now. We have to do it later
* than the manual describes because we have just now finished
* the BD initialization.
*/
cp->cp_cpcr = mk_cr_cmd (ecp->page, ecp->sblock, \
0x0c, CPM_CR_INIT_TRX) | CPM_CR_FLG;
do {
__asm__ __volatile__ ("eieio");
} while (cp->cp_cpcr & CPM_CR_FLG);
}
puts (" done\nStarting test... (Ctrl-C to Finish)\n");
/*
* Note: don't want serial output from here until the end of the
* test - the delays would probably stuff things up.
*/
clear_ctrlc ();
runtime = get_timer (0);
do {
nclosed = 0;
for (c = 0; c < 3; c++) {
volatile fcc_t *fcp = &immr->im_fcc[c];
elbt_chan *ecp = &elbt_chans[c];
int i;
switch (ecp->state) {
case Idle:
/*
* set the channel Running ...
*/
/* 28.9 - (14): enable tx/rx in gfmr */
fcp->fcc_gfmr |= FCC_GFMR_ENT | FCC_GFMR_ENR;
ecp->state = Running;
break;
case Running:
/*
* (while Running only) check for
* termination of the test
*/
(void)ctrlc ();
if (had_ctrlc ()) {
/*
* initiate a "graceful stop transmit"
* on the channel
*/
cp->cp_cpcr = mk_cr_cmd (ecp->page, \
ecp->sblock, 0x0c, \
CPM_CR_GRACEFUL_STOP_TX) | \
CPM_CR_FLG;
do {
__asm__ __volatile__ ("eieio");
} while (cp->cp_cpcr & CPM_CR_FLG);
ecp->clstime = get_timer (0);
ecp->state = Closing;
}
/* fall through ... */
case Closing:
/*
* (while Running or Closing) poll the channel:
* - check for any non-READY tx buffers and
* make them ready
* - check for any non-EMPTY rx buffers and
* check that they were received correctly,
* adjust counters etc, then make empty
*/
for (i = 0; i < ELBT_NTXBD; i++) {
cbd_t *bdp = &ecp->txbd[i];
ushort sc = bdp->cbd_sc;
if ((sc & BD_ENET_TX_READY) != 0)
continue;
/*
* this frame has finished
* transmitting
*/
ecp->nsent++;
if (sc & BD_ENET_TX_STATS) {
ulong n;
/*
* we had an error on
* the transmission
*/
n = ecp->ntxerr++;
if (n < ELBT_MAXTXERR)
ecp->txerrs[n] = sc;
if (sc & BD_ENET_TX_DEF)
ecp->txeacc.def++;
if (sc & BD_ENET_TX_HB)
ecp->txeacc.hb++;
if (sc & BD_ENET_TX_LC)
ecp->txeacc.lc++;
if (sc & BD_ENET_TX_RL)
ecp->txeacc.rl++;
if (sc & BD_ENET_TX_RCMASK)
ecp->txeacc.rc++;
if (sc & BD_ENET_TX_UN)
ecp->txeacc.un++;
if (sc & BD_ENET_TX_CSL)
ecp->txeacc.csl++;
bdp->cbd_sc &= \
~BD_ENET_TX_STATS;
}
if (ecp->state == Closing)
ecp->clstime = get_timer (0);
/* make it ready again */
bdp->cbd_sc |= BD_ENET_TX_READY;
}
for (i = 0; i < ELBT_NRXBD; i++) {
cbd_t *bdp = &ecp->rxbd[i];
ushort sc = bdp->cbd_sc, mask;
if ((sc & BD_ENET_RX_EMPTY) != 0)
continue;
/* we have a new frame in this buffer */
ecp->nrcvd++;
mask = BD_ENET_RX_LAST|BD_ENET_RX_FIRST;
if ((sc & mask) != mask) {
/* somethings wrong here ... */
if (!(sc & BD_ENET_RX_LAST))
ecp->rxeacc._l++;
if (!(sc & BD_ENET_RX_FIRST))
ecp->rxeacc._f++;
}
if (sc & BD_ENET_RX_STATS) {
ulong n;
/*
* we had some sort of error
* on the frame
*/
n = ecp->nrxerr++;
if (n < ELBT_MAXRXERR)
ecp->rxerrs[n] = sc;
if (sc & BD_ENET_RX_MISS)
ecp->rxeacc.m++;
if (sc & BD_ENET_RX_BC)
ecp->rxeacc.bc++;
if (sc & BD_ENET_RX_MC)
ecp->rxeacc.mc++;
if (sc & BD_ENET_RX_LG)
ecp->rxeacc.lg++;
if (sc & BD_ENET_RX_NO)
ecp->rxeacc.no++;
if (sc & BD_ENET_RX_SH)
ecp->rxeacc.sh++;
if (sc & BD_ENET_RX_CR)
ecp->rxeacc.cr++;
if (sc & BD_ENET_RX_OV)
ecp->rxeacc.ov++;
if (sc & BD_ENET_RX_CL)
ecp->rxeacc.cl++;
bdp->cbd_sc &= \
~BD_ENET_RX_STATS;
}
else {
ushort datlen = bdp->cbd_datlen;
Ethernet_t *ehp;
ushort prot;
int ours, tb, n, nbytes;
ehp = (Ethernet_t *) \
&ecp->rxbufs[i][0];
ours = memcmp (ehp->et_src, \
NetOurEther, 6);
prot = swap16 (ehp->et_protlen);
tb = prot & 0x8000;
n = prot & 0x7fff;
nbytes = ELBT_BUFSZ - \
offsetof (Ethernet_t, \
et_dsap) - \
ELBT_CRCSZ;
/* check the frame is correct */
if (datlen != ELBT_BUFSZ)
ecp->rxeacc.badlen++;
else if (!ours)
ecp->rxeacc.badsrc++;
else if (!tb || n >= ELBT_NTXBD)
ecp->rxeacc.badtyp++;
else {
ulong patword = \
patwords[n];
uint nbb;
nbb = badbits ( \
&ehp->et_dsap, \
nbytes, \
patword);
ecp->rxeacc.badbit += \
nbb;
}
}
if (ecp->state == Closing)
ecp->clstime = get_timer (0);
/* make it empty again */
bdp->cbd_sc |= BD_ENET_RX_EMPTY;
}
if (ecp->state != Closing)
break;
/*
* (while Closing) check to see if
* waited long enough
*/
if (get_timer (ecp->clstime) >= ELBT_CLSWAIT) {
/* write GFMR: disable tx/rx */
fcp->fcc_gfmr &= \
~(FCC_GFMR_ENT | FCC_GFMR_ENR);
ecp->state = Closed;
}
break;
case Closed:
nclosed++;
break;
}
}
} while (nclosed < 3);
runtime = get_timer (runtime);
if (runtime <= ELBT_CLSWAIT) {
printf ("Whoops! somehow elapsed time (%ld) is wrong (<= %d)\n",
runtime, ELBT_CLSWAIT);
return;
}
nmsec = runtime - ELBT_CLSWAIT;
printf ("Test Finished in %ldms (plus %dms close wait period)!\n\n",
nmsec, ELBT_CLSWAIT);
/*
* now print stats
*/
for (c = 0; c < 3; c++) {
elbt_chan *ecp = &elbt_chans[c];
uint rxpps, txpps, nerr;
rxpps = (ecp->nrcvd * 1000) / nmsec;
txpps = (ecp->nsent * 1000) / nmsec;
printf ("Channel %d: %d rcvd (%d pps, %d rxerrs), "
"%d sent (%d pps, %d txerrs)\n\n", c,
ecp->nrcvd, rxpps, ecp->nrxerr,
ecp->nsent, txpps, ecp->ntxerr);
if ((nerr = ecp->nrxerr) > 0) {
ulong i;
printf ("\tFirst %d rx errs:", nerr);
for (i = 0; i < nerr; i++)
printf (" %04x", ecp->rxerrs[i]);
puts ("\n");
}
if ((nerr = ecp->ntxerr) > 0) {
ulong i;
printf ("\tFirst %d tx errs:", nerr);
for (i = 0; i < nerr; i++)
printf (" %04x", ecp->txerrs[i]);
puts ("\n");
}
}
puts ("Receive Error Counts:\n");
for (c = 0; c < 3; c++)
bases[c] = (uchar *)&elbt_chans[c].rxeacc;
print_desc (rxeacc_descs, rxeacc_ndesc, bases, 3);
puts ("\nTransmit Error Counts:\n");
for (c = 0; c < 3; c++)
bases[c] = (uchar *)&elbt_chans[c].txeacc;
print_desc (txeacc_descs, txeacc_ndesc, bases, 3);
puts ("\nRMON(-like) Counters:\n");
for (c = 0; c < 3; c++)
bases[c] = (uchar *)&immr->im_dprambase[elbt_chans[c].proff];
print_desc (epram_descs, epram_ndesc, bases, 3);
}
#endif /* CONFIG_ETHER_LOOPBACK_TEST */
#endif /* CONFIG_ETHER_ON_FCC && CFG_CMD_NET && CONFIG_NET_MULTI */

View File

@@ -333,7 +333,7 @@ int eth_init(bd_t *bis)
immr->im_scc[CONFIG_ETHER_INDEX-1].scc_gsmrl |= (SCC_GSMRL_ENR |
SCC_GSMRL_ENT);
return 1;
return 0;
}

View File

@@ -58,7 +58,7 @@
/*-----------------------------------------------------------------------
*/
typedef void (*i2c_ecb_t)(int, int); /* error callback function */
typedef void (*i2c_ecb_t)(int, int, void *); /* error callback function */
/* This structure keeps track of the bd and buffer space usage. */
typedef struct i2c_state {
@@ -69,6 +69,7 @@ typedef struct i2c_state {
int tx_space; /* number of Tx bytes left */
unsigned char *tx_buf; /* pointer to free Tx area */
i2c_ecb_t err_cb; /* error callback function */
void *cb_data; /* private data to be passed */
} i2c_state_t;
/* flags for i2c_send() and i2c_receive() */
@@ -77,14 +78,15 @@ typedef struct i2c_state {
#define I2CF_STOP_COND 0x04 /* tx: generate stop condition */
/* return codes */
#define I2CERR_NO_BUFFERS 0x01 /* no more BDs or buffer space */
#define I2CERR_MSG_TOO_LONG 0x02 /* tried to send/receive to much data */
#define I2CERR_TIMEOUT 0x03 /* timeout in i2c_doio() */
#define I2CERR_QUEUE_EMPTY 0x04 /* i2c_doio called without send/receive */
#define I2CERR_NO_BUFFERS 1 /* no more BDs or buffer space */
#define I2CERR_MSG_TOO_LONG 2 /* tried to send/receive to much data */
#define I2CERR_TIMEOUT 3 /* timeout in i2c_doio() */
#define I2CERR_QUEUE_EMPTY 4 /* i2c_doio called without send/receive */
#define I2CERR_IO_ERROR 5 /* had an error during comms */
/* error callback flags */
#define I2CECB_RX_ERR 0x10 /* this is a receive error */
#define I2CECB_RX_ERR_OV 0x02 /* receive overrun error */
#define I2CECB_RX_OV 0x02 /* receive overrun error */
#define I2CECB_RX_MASK 0x0f /* mask for error bits */
#define I2CECB_TX_ERR 0x20 /* this is a transmit error */
#define I2CECB_TX_CL 0x01 /* transmit collision error */
@@ -318,6 +320,7 @@ void i2c_newio(i2c_state_t *state)
state->tx_space = MAX_TX_SPACE;
state->tx_buf = (uchar*)state->txbd + NUM_TX_BDS * sizeof(I2C_BD);
state->err_cb = NULL;
state->cb_data = NULL;
PRINTD(("[I2C] rxbd = %08x\n", (int)state->rxbd));
PRINTD(("[I2C] txbd = %08x\n", (int)state->txbd));
@@ -491,14 +494,11 @@ int i2c_doio(i2c_state_t *state)
volatile iic_t *iip;
volatile i2c8260_t *i2c = (i2c8260_t *)&immap->im_i2c;
volatile I2C_BD *txbd, *rxbd;
int j;
int timeout;
int n, i, b, rxcnt = 0, rxtimeo = 0, txcnt = 0, txtimeo = 0, rc = 0;
uint dpaddr;
PRINTD(("[I2C] i2c_doio\n"));
timeout = TOUT_LOOP * 256; /* arbitrarily long */
if (state->tx_idx <= 0 && state->rx_idx <= 0) {
PRINTD(("[I2C] No I/O is queued\n"));
return I2CERR_QUEUE_EMPTY;
@@ -518,14 +518,20 @@ int i2c_doio(i2c_state_t *state)
/* Loop until transmit & receive completed */
txbd = ((I2C_BD*)state->txbd) - 1;
j = 0;
if (state->tx_idx > 0) {
timeout = TOUT_LOOP * txbd->length;
if ((n = state->tx_idx) > 0) {
txbd = ((I2C_BD*)state->txbd) - n;
for (i = 0; i < n; i++) {
txtimeo += TOUT_LOOP * txbd->length;
txbd++;
}
txbd--; /* wait until last in list is done */
PRINTD(("[I2C] Transmitting...(txbd=0x%08lx)\n", (ulong)txbd));
udelay(START_DELAY_US); /* give it time to start */
while((txbd->status & BD_SC_READY) && (j++ < timeout)) {
while((txbd->status & BD_SC_READY) && (++txcnt < txtimeo)) {
udelay(DELAY_US);
if (ctrlc())
return (-1);
@@ -533,13 +539,20 @@ int i2c_doio(i2c_state_t *state)
}
}
rxbd = ((I2C_BD*)state->rxbd) - 1;
j = 0;
if ((state->rx_idx > 0) && (j < timeout)) {
timeout = TOUT_LOOP * rxbd->length;
if (txcnt < txtimeo && (n = state->rx_idx) > 0) {
rxbd = ((I2C_BD*)state->rxbd) - n;
for (i = 0; i < n; i++) {
rxtimeo += TOUT_LOOP * rxbd->length;
rxbd++;
}
rxbd--; /* wait until last in list is done */
PRINTD(("[I2C] Receiving...(rxbd=0x%08lx)\n", (ulong)rxbd));
udelay(START_DELAY_US); /* give it time to start */
while((rxbd->status & BD_SC_EMPTY) && (j++ < timeout)) {
while((rxbd->status & BD_SC_EMPTY) && (++rxcnt < rxtimeo)) {
udelay(DELAY_US);
if (ctrlc())
return (-1);
@@ -550,76 +563,91 @@ int i2c_doio(i2c_state_t *state)
/* Turn off I2C */
i2c->i2c_i2mod &= ~0x01;
if (state->err_cb != NULL) {
int n, i, b;
/*
* if we have an error callback function, look at the
* error bits in the bd status and pass them back
*/
if ((n = state->tx_idx) > 0) {
for (i = 0; i < n; i++) {
txbd = ((I2C_BD*)state->txbd) - (n - i);
if ((b = txbd->status & BD_I2C_TX_ERR) != 0)
(*state->err_cb)(I2CECB_TX_ERR|b, i);
if ((n = state->tx_idx) > 0) {
for (i = 0; i < n; i++) {
txbd = ((I2C_BD*)state->txbd) - (n - i);
if ((b = txbd->status & BD_I2C_TX_ERR) != 0) {
if (state->err_cb != NULL)
(*state->err_cb)(I2CECB_TX_ERR|b, i,
state->cb_data);
if (rc == 0)
rc = I2CERR_IO_ERROR;
}
}
if ((n = state->rx_idx) > 0) {
for (i = 0; i < n; i++) {
rxbd = ((I2C_BD*)state->rxbd) - (n - i);
if ((b = rxbd->status & BD_I2C_RX_ERR) != 0)
(*state->err_cb)(I2CECB_RX_ERR|b, i);
}
}
if (j >= timeout)
(*state->err_cb)(I2CECB_TIMEOUT, 0);
}
/* sort out errors and return appropriate good/error status */
if(j >= timeout)
return(I2CERR_TIMEOUT);
if((txbd->status & BD_I2C_TX_ERR) != 0)
return(I2CECB_TX_ERR | (txbd->status & I2CECB_TX_MASK));
if((rxbd->status & BD_I2C_RX_ERR) != 0)
return(I2CECB_RX_ERR | (rxbd->status & I2CECB_RX_MASK));
if ((n = state->rx_idx) > 0) {
for (i = 0; i < n; i++) {
rxbd = ((I2C_BD*)state->rxbd) - (n - i);
if ((b = rxbd->status & BD_I2C_RX_ERR) != 0) {
if (state->err_cb != NULL)
(*state->err_cb)(I2CECB_RX_ERR|b, i,
state->cb_data);
if (rc == 0)
rc = I2CERR_IO_ERROR;
}
}
}
return(0);
if ((txtimeo > 0 && txcnt >= txtimeo) || \
(rxtimeo > 0 && rxcnt >= rxtimeo)) {
if (state->err_cb != NULL)
(*state->err_cb)(I2CECB_TIMEOUT, -1, state->cb_data);
if (rc == 0)
rc = I2CERR_TIMEOUT;
}
return (rc);
}
static int had_tx_nak;
static void
i2c_test_callback(int flags, int xnum)
i2c_probe_callback(int flags, int xnum, void *data)
{
if ((flags & I2CECB_TX_ERR) && (flags & I2CECB_TX_NAK))
had_tx_nak = 1;
/*
* the only acceptable errors are a transmit NAK or a receive
* overrun - tx NAK means the device does not exist, rx OV
* means the device must have responded to the slave address
* even though the transfer failed
*/
if (flags == (I2CECB_TX_ERR|I2CECB_TX_NAK))
*(int *)data |= 1;
if (flags == (I2CECB_RX_ERR|I2CECB_RX_OV))
*(int *)data |= 2;
}
int i2c_probe(uchar chip)
int
i2c_probe(uchar chip)
{
i2c_state_t state;
int rc;
int rc, err_flag;
uchar buf[1];
i2c_newio(&state);
state.err_cb = i2c_test_callback;
had_tx_nak = 0;
state.err_cb = i2c_probe_callback;
state.cb_data = (void *) &err_flag;
err_flag = 0;
rc = i2c_receive(&state, chip, 0, I2CF_START_COND|I2CF_STOP_COND, 1, buf);
if (rc != 0)
return (rc);
return (rc); /* probe failed */
rc = i2c_doio(&state);
if ((rc != 0) && (rc != I2CERR_TIMEOUT))
return (rc);
if (rc == 0)
return (0); /* device exists - read succeeded */
return (had_tx_nak);
if (rc == I2CERR_TIMEOUT)
return (-1); /* device does not exist - timeout */
if (rc != I2CERR_IO_ERROR || err_flag == 0)
return (rc); /* probe failed */
if (err_flag & 1)
return (-1); /* device does not exist - had transmit NAK */
return (0); /* device exists - had receive overrun */
}

View File

@@ -155,7 +155,7 @@ static __inline__ unsigned long get_msr (void)
static __inline__ void set_msr (unsigned long msr)
{
__asm__ __volatile__ ("mtmsr %0"::"r" (msr));
__asm__ __volatile__ ("mtmsr %0;sync;isync"::"r" (msr));
}
static __inline__ unsigned long get_dec (void)
@@ -208,6 +208,14 @@ int interrupt_init (void)
immr->im_intctl.ic_sipnrh = 0xffffffff;
immr->im_intctl.ic_sipnrl = 0xffffffff;
#ifdef CONFIG_HYMOD
/*
* ensure all external interrupt sources default to trigger on
* high-to-low transition (i.e. edge triggered active low)
*/
immr->im_intctl.ic_siexr = -1;
#endif
set_dec (decrementer_count);
set_msr (get_msr () | MSR_EE);

View File

@@ -252,7 +252,13 @@ void pci_mpc8250_init(struct pci_controller *hose)
* Setting required to enable IRQ1-IRQ7 (SIUMCR [DPPC]),
* and local bus for PCI (SIUMCR [LBPC]).
*/
immap->im_siu_conf.sc_siumcr = 0x00640000;
immap->im_siu_conf.sc_siumcr = (immap->im_siu_conf.sc_siumcr &
~SIUMCR_LBPC11 &
~SIUMCR_CS10PC11 &
~SIUMCR_LBPC11) |
SIUMCR_LBPC01 |
SIUMCR_CS10PC01 |
SIUMCR_LBPC01;
#endif
/* Make PCI lowest priority */

View File

@@ -161,6 +161,7 @@ _hrcw_table:
.globl _start
_start:
li r21, BOOTFLAG_COLD /* Normal Power-On: Boot from FLASH*/
nop
b boot_cold
. = EXC_OFF_SYS_RESET + 0x10
@@ -171,6 +172,18 @@ _start_warm:
b boot_warm
boot_cold:
#if defined(CONFIG_MPC8260ADS)
lis r3, CFG_DEFAULT_IMMR@h
nop
lwz r4, 0(r3)
nop
rlwinm r4, r4, 0, 8, 5
nop
oris r4, r4, 0x0200
nop
stw r4, 0(r3)
nop
#endif /* CONFIG_MPC8260ADS */
boot_warm:
mfmsr r5 /* save msr contents */

View File

@@ -1,160 +0,0 @@
/*
* (C) Copyright 2000
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#include <common.h>
#include <status_led.h>
/*
* The purpose of this code is to signal the operational status of a
* target which usually boots over the network; while running in
* PCBoot, a status LED is blinking. As soon as a valid BOOTP reply
* message has been received, the LED is turned off. The Linux
* kernel, once it is running, will start blinking the LED again,
* with another frequency.
*/
/* ------------------------------------------------------------------------- */
#ifdef CONFIG_STATUS_LED
typedef struct {
ulong mask;
int state;
int period;
int cnt;
} led_dev_t;
led_dev_t led_dev[] = {
{ STATUS_LED_BIT,
STATUS_LED_STATE,
STATUS_LED_PERIOD,
0,
},
#if defined(STATUS_LED_BIT1)
{ STATUS_LED_BIT1,
STATUS_LED_STATE1,
STATUS_LED_PERIOD1,
0,
},
#endif
#if defined(STATUS_LED_BIT2)
{ STATUS_LED_BIT2,
STATUS_LED_STATE2,
STATUS_LED_PERIOD2,
0,
},
#endif
};
#define MAX_LED_DEV (sizeof(led_dev)/sizeof(led_dev_t))
static int status_led_init_done = 0;
static void status_led_init (void)
{
volatile immap_t *immr = (immap_t *)CFG_IMMR;
int i;
for (i=0; i<MAX_LED_DEV; ++i) {
led_dev_t *ld = &led_dev[i];
immr->STATUS_LED_PAR &= ~(ld->mask);
#ifdef STATUS_LED_ODR
immr->STATUS_LED_ODR &= ~(ld->mask);
#endif
#if (STATUS_LED_ACTIVE == 0)
if (ld->state == STATUS_LED_ON)
immr->STATUS_LED_DAT &= ~(ld->mask);
else
immr->STATUS_LED_DAT |= ld->mask ;
#else
if (ld->state == STATUS_LED_ON)
immr->STATUS_LED_DAT |= ld->mask ;
else
immr->STATUS_LED_DAT &= ~(ld->mask);
#endif
immr->STATUS_LED_DIR |= ld->mask ;
}
status_led_init_done = 1;
}
void status_led_tick (ulong timestamp)
{
volatile immap_t *immr = (immap_t *)CFG_IMMR;
int i;
if (!status_led_init_done)
status_led_init();
for (i=0; i<MAX_LED_DEV; ++i) {
led_dev_t *ld = &led_dev[i];
if (ld->state != STATUS_LED_BLINKING)
continue;
if (++(ld->cnt) >= ld->period) {
immr->STATUS_LED_DAT ^= ld->mask;
ld->cnt -= ld->period;
}
}
}
void status_led_set (int led, int state)
{
volatile immap_t *immr = (immap_t *)CFG_IMMR;
led_dev_t *ld;
if (led < 0 || led >= MAX_LED_DEV)
return;
if (!status_led_init_done)
status_led_init();
ld = &led_dev[led];
switch (state) {
default:
return;
case STATUS_LED_BLINKING:
ld->cnt = 0; /* always start with full period */
/* fall through */ /* always start with LED _ON_ */
case STATUS_LED_ON:
#if (STATUS_LED_ACTIVE == 0)
immr->STATUS_LED_DAT &= ~(ld->mask);
#else
immr->STATUS_LED_DAT |= ld->mask ;
#endif
break;
case STATUS_LED_OFF:
#if (STATUS_LED_ACTIVE == 0)
immr->STATUS_LED_DAT |= ld->mask ;
#else
immr->STATUS_LED_DAT &= ~(ld->mask);
#endif
break;
}
ld->state = state;
}
#endif /* CONFIG_STATUS_LED */

View File

@@ -30,7 +30,7 @@ LIB = lib$(CPU).a
START = start.o kgdb.o
OBJS = bedbug_860.o commproc.o cpu.o cpu_init.o \
fec.o i2c.o interrupts.o lcd.o scc.o \
serial.o speed.o spi.o status_led.o\
serial.o speed.o spi.o \
traps.o upatch.o video.o
all: .depend $(START) $(LIB)

View File

@@ -716,7 +716,7 @@ _start_of_vectors:
#endif
/* Machine check */
STD_EXCEPTION(0x200, MachineCheck, MachineCheckException)
CRIT_EXCEPTION(0x200, MachineCheck, MachineCheckException)
/* Data Storage exception. */
STD_EXCEPTION(0x300, DataStorage, UnknownException)

View File

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

View File

@@ -32,6 +32,7 @@
#include <common.h>
#include <command.h>
#include <asm/arch/pxa-regs.h>
int cpu_init (void)
{
@@ -150,3 +151,21 @@ int dcache_status (void)
{
return 0; /* always off */
}
void set_GPIO_mode(int gpio_mode)
{
int gpio = gpio_mode & GPIO_MD_MASK_NR;
int fn = (gpio_mode & GPIO_MD_MASK_FN) >> 8;
int gafr;
if (gpio_mode & GPIO_MD_MASK_DIR)
{
GPDR(gpio) |= GPIO_bit(gpio);
}
else
{
GPDR(gpio) &= ~GPIO_bit(gpio);
}
gafr = GAFR(gpio) & ~(0x3 << (((gpio) & 0xf)*2));
GAFR(gpio) = gafr | (fn << (((gpio) & 0xf)*2));
}

483
cpu/pxa/mmc.c Normal file
View File

@@ -0,0 +1,483 @@
/*
* (C) Copyright 2003
* Kyle Harris, Nexus Technologies, Inc. kharris@nexus-tech.net
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#include <config.h>
#include <common.h>
#include <mmc.h>
#include <asm/errno.h>
#include <asm/arch/hardware.h>
#ifdef CONFIG_MMC
extern int
fat_register_read(int(*block_read)(int device, ulong blknr, ulong blkcnt, uchar *buffer));
/*
* FIXME needs to read cid and csd info to determine block size
* and other parameters
*/
static uchar mmc_buf[MMC_BLOCK_SIZE];
static mmc_csd_t mmc_csd;
static int mmc_ready = 0;
static uchar *
/****************************************************/
mmc_cmd(ushort cmd, ushort argh, ushort argl, ushort cmdat)
/****************************************************/
{
static uchar resp[20];
ulong status;
int words, i;
debug("mmc_cmd %x %x %x %x\n", cmd, argh, argl, cmdat);
MMC_STRPCL = MMC_STRPCL_STOP_CLK;
MMC_I_MASK = ~MMC_I_MASK_CLK_IS_OFF;
while (!(MMC_I_REG & MMC_I_REG_CLK_IS_OFF));
MMC_CMD = cmd;
MMC_ARGH = argh;
MMC_ARGL = argl;
MMC_CMDAT = cmdat;
MMC_I_MASK = ~MMC_I_MASK_END_CMD_RES;
MMC_STRPCL = MMC_STRPCL_START_CLK;
while (!(MMC_I_REG & MMC_I_REG_END_CMD_RES));
status = MMC_STAT;
debug("MMC status %x\n", status);
if (status & MMC_STAT_TIME_OUT_RESPONSE)
{
return 0;
}
switch (cmdat & 0x3)
{
case MMC_CMDAT_R1:
case MMC_CMDAT_R3:
words = 3;
break;
case MMC_CMDAT_R2:
words = 8;
break;
default:
return 0;
}
for (i = words-1; i >= 0; i--)
{
ulong res_fifo = MMC_RES;
int offset = i << 1;
resp[offset] = ((uchar *)&res_fifo)[0];
resp[offset+1] = ((uchar *)&res_fifo)[1];
}
#ifdef MMC_DEBUG
for (i=0; i<words*2; i += 2)
{
printf("MMC resp[%d] = %02x\n", i, resp[i]);
printf("MMC resp[%d] = %02x\n", i+1, resp[i+1]);
}
#endif
return resp;
}
int
/****************************************************/
mmc_block_read(uchar *dst, ulong src, ulong len)
/****************************************************/
{
uchar *resp;
ushort argh, argl;
ulong status;
if (len == 0)
{
return 0;
}
debug("mmc_block_rd dst %lx src %lx len %d\n", (ulong)dst, src, len);
argh = len >> 16;
argl = len & 0xffff;
/* set block len */
resp = mmc_cmd(MMC_CMD_SET_BLOCKLEN, argh, argl, MMC_CMDAT_R1);
/* send read command */
argh = src >> 16;
argl = src & 0xffff;
MMC_STRPCL = MMC_STRPCL_STOP_CLK;
MMC_RDTO = 0xffff;
MMC_NOB = 1;
MMC_BLKLEN = len;
resp = mmc_cmd(MMC_CMD_READ_BLOCK, argh, argl,
MMC_CMDAT_R1|MMC_CMDAT_READ|MMC_CMDAT_BLOCK|MMC_CMDAT_DATA_EN);
MMC_I_MASK = ~MMC_I_MASK_RXFIFO_RD_REQ;
while (len)
{
if (MMC_I_REG & MMC_I_REG_RXFIFO_RD_REQ)
{
*dst++ = MMC_RXFIFO;
len--;
}
status = MMC_STAT;
if (status & MMC_STAT_ERRORS)
{
printf("MMC_STAT error %lx\n", status);
return -1;
}
}
MMC_I_MASK = ~MMC_I_MASK_DATA_TRAN_DONE;
while (!(MMC_I_REG & MMC_I_REG_DATA_TRAN_DONE));
status = MMC_STAT;
if (status & MMC_STAT_ERRORS)
{
printf("MMC_STAT error %lx\n", status);
return -1;
}
return 0;
}
int
/****************************************************/
mmc_block_write(ulong dst, uchar *src, int len)
/****************************************************/
{
uchar *resp;
ushort argh, argl;
ulong status;
if (len == 0)
{
return 0;
}
debug("mmc_block_wr dst %lx src %lx len %d\n", dst, (ulong)src, len);
argh = len >> 16;
argl = len & 0xffff;
/* set block len */
resp = mmc_cmd(MMC_CMD_SET_BLOCKLEN, argh, argl, MMC_CMDAT_R1);
/* send write command */
argh = dst >> 16;
argl = dst & 0xffff;
MMC_STRPCL = MMC_STRPCL_STOP_CLK;
MMC_NOB = 1;
MMC_BLKLEN = len;
resp = mmc_cmd(MMC_CMD_WRITE_BLOCK, argh, argl,
MMC_CMDAT_R1|MMC_CMDAT_WRITE|MMC_CMDAT_BLOCK|MMC_CMDAT_DATA_EN);
MMC_I_MASK = ~MMC_I_MASK_TXFIFO_WR_REQ;
while (len)
{
if (MMC_I_REG & MMC_I_REG_TXFIFO_WR_REQ)
{
int i, bytes = min(32,len);
for (i=0; i<bytes; i++)
{
MMC_TXFIFO = *src++;
}
if (bytes < 32)
{
MMC_PRTBUF = MMC_PRTBUF_BUF_PART_FULL;
}
len -= bytes;
}
status = MMC_STAT;
if (status & MMC_STAT_ERRORS)
{
printf("MMC_STAT error %lx\n", status);
return -1;
}
}
MMC_I_MASK = ~MMC_I_MASK_DATA_TRAN_DONE;
while (!(MMC_I_REG & MMC_I_REG_DATA_TRAN_DONE));
MMC_I_MASK = ~MMC_I_MASK_PRG_DONE;
while (!(MMC_I_REG & MMC_I_REG_PRG_DONE));
status = MMC_STAT;
if (status & MMC_STAT_ERRORS)
{
printf("MMC_STAT error %lx\n", status);
return -1;
}
return 0;
}
int
/****************************************************/
mmc_read(ulong src, uchar *dst, int size)
/****************************************************/
{
ulong end, part_start, part_end, part_len, aligned_start, aligned_end;
ulong mmc_block_size, mmc_block_address;
if (size == 0)
{
return 0;
}
if (!mmc_ready)
{
printf("Please initial the MMC first\n");
return -1;
}
mmc_block_size = MMC_BLOCK_SIZE;
mmc_block_address = ~(mmc_block_size - 1);
src -= CFG_MMC_BASE;
end = src + size;
part_start = ~mmc_block_address & src;
part_end = ~mmc_block_address & end;
aligned_start = mmc_block_address & src;
aligned_end = mmc_block_address & end;
/* all block aligned accesses */
debug("src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
src, (ulong)dst, end, part_start, part_end, aligned_start, aligned_end);
if (part_start)
{
part_len = mmc_block_size - part_start;
debug("ps src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
src, (ulong)dst, end, part_start, part_end, aligned_start, aligned_end);
if ((mmc_block_read(mmc_buf, aligned_start, mmc_block_size)) < 0)
{
return -1;
}
memcpy(dst, mmc_buf+part_start, part_len);
dst += part_len;
src += part_len;
}
debug("src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
src, (ulong)dst, end, part_start, part_end, aligned_start, aligned_end);
for (; src < aligned_end; src += mmc_block_size, dst += mmc_block_size)
{
debug("al src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
src, (ulong)dst, end, part_start, part_end, aligned_start, aligned_end);
if ((mmc_block_read((uchar *)(dst), src, mmc_block_size)) < 0)
{
return -1;
}
}
debug("src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
src, (ulong)dst, end, part_start, part_end, aligned_start, aligned_end);
if (part_end && src < end)
{
debug("pe src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
src, (ulong)dst, end, part_start, part_end, aligned_start, aligned_end);
if ((mmc_block_read(mmc_buf, aligned_end, mmc_block_size)) < 0)
{
return -1;
}
memcpy(dst, mmc_buf, part_end);
}
return 0;
}
int
/****************************************************/
mmc_write(uchar *src, ulong dst, int size)
/****************************************************/
{
ulong end, part_start, part_end, part_len, aligned_start, aligned_end;
ulong mmc_block_size, mmc_block_address;
if (size == 0)
{
return 0;
}
if (!mmc_ready)
{
printf("Please initial the MMC first\n");
return -1;
}
mmc_block_size = MMC_BLOCK_SIZE;
mmc_block_address = ~(mmc_block_size - 1);
dst -= CFG_MMC_BASE;
end = dst + size;
part_start = ~mmc_block_address & dst;
part_end = ~mmc_block_address & end;
aligned_start = mmc_block_address & dst;
aligned_end = mmc_block_address & end;
/* all block aligned accesses */
debug("src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
src, (ulong)dst, end, part_start, part_end, aligned_start, aligned_end);
if (part_start)
{
part_len = mmc_block_size - part_start;
debug("ps src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
(ulong)src, dst, end, part_start, part_end, aligned_start, aligned_end);
if ((mmc_block_read(mmc_buf, aligned_start, mmc_block_size)) < 0)
{
return -1;
}
memcpy(mmc_buf+part_start, src, part_len);
if ((mmc_block_write(aligned_start, mmc_buf, mmc_block_size)) < 0)
{
return -1;
}
dst += part_len;
src += part_len;
}
debug("src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
src, (ulong)dst, end, part_start, part_end, aligned_start, aligned_end);
for (; dst < aligned_end; src += mmc_block_size, dst += mmc_block_size)
{
debug("al src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
src, (ulong)dst, end, part_start, part_end, aligned_start, aligned_end);
if ((mmc_block_write(dst, (uchar *)src, mmc_block_size)) < 0)
{
return -1;
}
}
debug("src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
src, (ulong)dst, end, part_start, part_end, aligned_start, aligned_end);
if (part_end && dst < end)
{
debug("pe src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
src, (ulong)dst, end, part_start, part_end, aligned_start, aligned_end);
if ((mmc_block_read(mmc_buf, aligned_end, mmc_block_size)) < 0)
{
return -1;
}
memcpy(mmc_buf, src, part_end);
if ((mmc_block_write(aligned_end, mmc_buf, mmc_block_size)) < 0)
{
return -1;
}
}
return 0;
}
int
/****************************************************/
mmc_bread(int dev_num, ulong blknr, ulong blkcnt, uchar *dst)
/****************************************************/
{
int mmc_block_size = MMC_BLOCK_SIZE;
ulong src = blknr * mmc_block_size + CFG_MMC_BASE;
mmc_read(src, (uchar *)dst, blkcnt*mmc_block_size);
return blkcnt;
}
int
/****************************************************/
mmc_init(int verbose)
/****************************************************/
{
int retries, rc = -ENODEV;
uchar *resp;
#ifdef CONFIG_LUBBOCK
set_GPIO_mode( GPIO6_MMCCLK_MD );
set_GPIO_mode( GPIO8_MMCCS0_MD );
#endif
CKEN |= CKEN12_MMC; /* enable MMC unit clock */
mmc_csd.c_size = 0;
MMC_CLKRT = MMC_CLKRT_0_3125MHZ;
MMC_RESTO = MMC_RES_TO_MAX;
MMC_SPI = MMC_SPI_DISABLE;
/* reset */
retries = 10;
resp = mmc_cmd(0, 0, 0, 0);
resp = mmc_cmd(1, 0x00ff, 0xc000, MMC_CMDAT_INIT|MMC_CMDAT_BUSY|MMC_CMDAT_R3);
while (retries-- && resp && !(resp[4] & 0x80))
{
debug("resp %x %x\n", resp[0], resp[1]);
udelay(50);
resp = mmc_cmd(1, 0x00ff, 0xff00, MMC_CMDAT_BUSY|MMC_CMDAT_R3);
}
/* try to get card id */
resp = mmc_cmd(2, 0, 0, MMC_CMDAT_R2);
if (resp)
{
/* TODO configure mmc driver depending on card attributes */
mmc_cid_t *cid = (mmc_cid_t *)resp;
if (verbose)
{
printf("MMC found. Card desciption is:\n");
printf("Manufacturer ID = %02x%02x%02x\n",
cid->id[0], cid->id[1], cid->id[2]);
printf("HW/FW Revision = %x %x\n",cid->hwrev, cid->fwrev);
cid->hwrev = cid->fwrev = 0; /* null terminate string */
printf("Product Name = %s\n",cid->name);
printf("Serial Number = %02x%02x%02x\n",
cid->sn[0], cid->sn[1], cid->sn[2]);
printf("Month = %d\n",cid->month);
printf("Year = %d\n",1997 + cid->year);
}
/* MMC exists, get CSD too */
resp = mmc_cmd(MMC_CMD_SET_RCA, MMC_DEFAULT_RCA, 0, MMC_CMDAT_R1);
resp = mmc_cmd(MMC_CMD_SEND_CSD, MMC_DEFAULT_RCA, 0, MMC_CMDAT_R2);
if (resp)
{
mmc_csd_t *csd = (mmc_csd_t *)resp;
memcpy(&mmc_csd, csd, sizeof(csd));
rc = 0;
mmc_ready = 1;
/* FIXME add verbose printout for csd */
}
}
MMC_CLKRT = 0; /* 20 MHz */
resp = mmc_cmd(7, MMC_DEFAULT_RCA, 0, MMC_CMDAT_R1);
fat_register_read(mmc_bread);
return rc;
}
int
mmc_ident(block_dev_desc_t *dev)
{
return 0;
}
int
mmc2info(ulong addr)
{
/* FIXME hard codes to 32 MB device */
if (addr >= CFG_MMC_BASE && addr < CFG_MMC_BASE + 0x02000000)
{
return 1;
}
return 0;
}
#endif

1089
cpu/pxa/pxafb.c Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -27,9 +27,9 @@ include $(TOPDIR)/config.mk
LIB = libdrivers.a
OBJS = 3c589.o 5701rls.o ali512x.o at91rm9200_ether.o \
OBJS = 3c589.o 5701rls.o ali512x.o \
bcm570x.o bcm570x_autoneg.o cfb_console.o \
cs8900.o ct69000.o dc2114x.o \
cs8900.o ct69000.o dataflash.o dc2114x.o \
e1000.o eepro100.o \
i8042.o i82365.o inca-ip_sw.o \
lan91c96.o natsemi.o \
@@ -38,10 +38,11 @@ OBJS = 3c589.o 5701rls.o ali512x.o at91rm9200_ether.o \
pcnet.o plb2800_eth.o \
s3c24x0_i2c.o sed13806.o serial.o \
smc91111.o smiLynxEM.o sym53c8xx.o \
ti_pci1410a.o tigon3.o w83c553f.o
ti_pci1410a.o tigon3.o w83c553f.o \
status_led.o
## Disabled for now:
## cs8900.o ct69000.o dc2114x.o ds1722.o \
## cs8900.o ct69000.o dataflash.o dc2114x.o ds1722.o \
## lan91c96.o mw_eeprom.o natsemi.o \
## smc91111.o smiLynxEM.o spi_eeprom.o sym53c8xx.o \
##

View File

@@ -1,251 +0,0 @@
#include <common.h>
#include <command.h>
#include <asm/io.h>
#include <net.h>
/* ----- Ethernet Buffer definitions ----- */
typedef struct {
unsigned long addr,size;
} rbf_t;
#define RBF_ADDR 0xfffffffc
#define RBF_OWNER (1<<0)
#define RBF_WRAP (1<<1)
#define RBF_BROADCAST (1<<31)
#define RBF_MULTICAST (1<<30)
#define RBF_UNICAST (1<<29)
#define RBF_EXTERNAL (1<<28)
#define RBF_UNKOWN (1<<27)
#define RBF_SIZE 0x07ff
#define RBF_LOCAL4 (1<<26)
#define RBF_LOCAL3 (1<<25)
#define RBF_LOCAL2 (1<<24)
#define RBF_LOCAL1 (1<<23)
#define RBF_FRAMEMAX 10
#define RBF_FRAMEMEM 0x200000
#define RBF_FRAMELEN 0x600
#define RBF_FRAMEBTD RBF_FRAMEMEM
#define RBF_FRAMEBUF (RBF_FRAMEMEM + RBF_FRAMEMAX*sizeof(rbf_t))
/* stolen from mii.h */
/* Generic MII registers. */
#define MII_BMCR 0x00 /* Basic mode control register */
#define MII_BMSR 0x01 /* Basic mode status register */
#define BMSR_JCD 0x0002 /* Jabber detected */
#define BMSR_LSTATUS 0x0004 /* Link status */
#define BMSR_10HALF 0x0800 /* Can do 10mbps, half-duplex */
#define BMSR_100FULL 0x4000 /* Can do 100mbps, full-duplex */
#define BMSR_10FULL 0x1000 /* Can do 10mbps, full-duplex */
#define BMSR_100HALF 0x2000 /* Can do 100mbps, half-duplex */
#define MII_STS2_REG 17 /* Davicom specific */
#define MII_MDINTR_REG 21 /* Davicom specific */
#ifdef CONFIG_DRIVER_ETHER
#if (CONFIG_COMMANDS & CFG_CMD_NET)
AT91PS_EMAC p_mac;
int MII_ReadPhy(unsigned char addr, unsigned short *ret)
{
p_mac->EMAC_MAN = 0x60020000 | (addr << 18);
udelay(10000);
*ret = (unsigned short)p_mac->EMAC_MAN;
return 1;
}
int MII_GetLinkSpeed(void)
{
unsigned short stat1, stat2;
int ret;
if (!(ret = MII_ReadPhy(MII_BMSR, &stat1)))
return 0;
if (stat1 & BMSR_JCD)
{
#ifdef DEBUG
printf("MII: jabber condition detected\n");
#endif /*jabber detected re-read the register*/
}
if (!(ret = MII_ReadPhy(MII_BMSR, &stat1)))
return 0;
if (!(stat1 & BMSR_LSTATUS)) /* link status up? */
{
printf("MII: no Link\n");
return 0;
}
if (!(ret = MII_ReadPhy(MII_STS2_REG, &stat2)))
return 0;
if ((stat1 & BMSR_100FULL) && (stat2 & 0x8000) )
{
/* set MII for 100BaseTX and Full Duplex */
p_mac->EMAC_CFG |= AT91C_EMAC_SPD | AT91C_EMAC_FD;
#ifdef DEBUG
printf("MII: 100BaseTX and Full Duplex detected\n");
#endif
return 1;
}
else
if ((stat1 & BMSR_10FULL) && (stat2 & 0x2000))
{
/* set MII for 10BaseT and Full Duplex */
p_mac->EMAC_CFG = (p_mac->EMAC_CFG & ~(AT91C_EMAC_SPD | AT91C_EMAC_FD));
#ifdef DEBUG
printf("MII: 10BaseT and Full Duplex detected\n");
#endif
return 1;
}
else
if ((stat1 & BMSR_100HALF) && (stat2 & 0x4000))
{
/* set MII for 100BaseTX and Half Duplex */
p_mac->EMAC_CFG = (p_mac->EMAC_CFG & ~(AT91C_EMAC_SPD | AT91C_EMAC_FD));
#ifdef DEBUG
printf("MII: 100BaseTX and Hall Duplex detected\n");
#endif
return 1;
}
else
if ((stat1 & BMSR_10HALF) && (stat2 & 0x1000))
{
/*set MII for 10BaseT and Half Duplex */
p_mac->EMAC_CFG &= ~(AT91C_EMAC_SPD | AT91C_EMAC_FD);
#ifdef DEBUG
printf("MII: 10BaseT and Hall Duplex detected\n");
#endif
return 1;
}
return 0;
}
int MDIO_StartupPhy(void)
{
int ret;
if(p_mac->EMAC_SR & AT91C_EMAC_LINK)
{
printf("MDIO_StartupPhy: no link\n");
return 0;
};
p_mac->EMAC_CTL |= AT91C_EMAC_MPE;
ret = MII_GetLinkSpeed();
if (ret == 0)
{
printf("MDIO_StartupPhy: MII_GetLinkSpeed failed\n");
ret = 0;
}
else
{
ret = 1;
}
p_mac->EMAC_CTL &= ~AT91C_EMAC_MPE;
return ret;
}
rbf_t* rbfdt;
rbf_t* rbfp;
int eth_init( bd_t *bd )
{
int ret;
int i;
p_mac = AT91C_BASE_EMAC;
*AT91C_PIOA_PDR = AT91C_PA16_EMDIO |
AT91C_PA15_EMDC | AT91C_PA14_ERXER | AT91C_PA13_ERX1 | AT91C_PA12_ERX0 |
AT91C_PA11_ECRS_ECRSDV | AT91C_PA10_ETX1 | AT91C_PA9_ETX0 | AT91C_PA8_ETXEN |
AT91C_PA7_ETXCK_EREFCK; /* PIO Disable Register */
*AT91C_PIOB_PDR = AT91C_PB25_EF100 |
AT91C_PB19_ERXCK | AT91C_PB18_ECOL | AT91C_PB17_ERXDV | AT91C_PB16_ERX3 |
AT91C_PB15_ERX2 | AT91C_PB14_ETXER | AT91C_PB13_ETX3 | AT91C_PB12_ETX2;
*AT91C_PIOB_BSR = AT91C_PB25_EF100 |
AT91C_PB19_ERXCK | AT91C_PB18_ECOL | AT91C_PB17_ERXDV | AT91C_PB16_ERX3 |
AT91C_PB15_ERX2 | AT91C_PB14_ETXER | AT91C_PB13_ETX3 | AT91C_PB12_ETX2; /* Select B Register */
*AT91C_PMC_PCER = 1 << AT91C_ID_EMAC; /* Peripheral Clock Enable Register */
p_mac->EMAC_CFG |= AT91C_EMAC_CSR; /* Clear statistics */
rbfdt=(rbf_t *)RBF_FRAMEBTD;
for(i = 0; i < RBF_FRAMEMAX; i++)
{
rbfdt[i].addr=RBF_FRAMEBUF+RBF_FRAMELEN*i;
rbfdt[i].size=0;
}
rbfdt[RBF_FRAMEMAX-1].addr|=RBF_WRAP;
rbfp=&rbfdt[0];
if (!(ret = MDIO_StartupPhy()))
{
printf("MAC: error during MII initialization\n");
return 0;
}
p_mac->EMAC_SA2L = (bd->bi_enetaddr[3] << 24) | (bd->bi_enetaddr[2] << 16)
| (bd->bi_enetaddr[1] << 8) | (bd->bi_enetaddr[0]);
p_mac->EMAC_SA2H = (bd->bi_enetaddr[5] << 8) | (bd->bi_enetaddr[4]);
p_mac->EMAC_RBQP = (long)(&rbfdt[0]);
p_mac->EMAC_RSR &= ~(AT91C_EMAC_RSR_OVR | AT91C_EMAC_REC | AT91C_EMAC_BNA);
p_mac->EMAC_CFG = (p_mac->EMAC_CFG | AT91C_EMAC_CAF | AT91C_EMAC_NBC | AT91C_EMAC_RMII) & ~AT91C_EMAC_CLK;
p_mac->EMAC_CTL |= AT91C_EMAC_TE | AT91C_EMAC_RE ;
return 0;
}
int eth_send(volatile void *packet, int length)
{
while(!(p_mac->EMAC_TSR & AT91C_EMAC_BNQ))
;
p_mac->EMAC_TAR = (long)packet;
p_mac->EMAC_TCR = length;
while(p_mac->EMAC_TCR & 0x7ff)
;
p_mac->EMAC_TSR |= AT91C_EMAC_COMP;
return 0;
}
int eth_rx(void)
{
int size;
if(!(rbfp->addr & RBF_OWNER))
return 0;
size=rbfp->size & RBF_SIZE;
NetReceive((volatile uchar *) (rbfp->addr & RBF_ADDR), size);
rbfp->addr &= ~RBF_OWNER;
if(rbfp->addr & RBF_WRAP)
rbfp = &rbfdt[0];
else
rbfp++;
p_mac->EMAC_RSR |= AT91C_EMAC_REC;
return size;
}
void eth_halt( void )
{};
#endif
#endif

245
drivers/dataflash.c Normal file
View File

@@ -0,0 +1,245 @@
/* LowLevel function for ATMEL DataFlash support
* Author : Hamid Ikdoumi (Atmel)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public 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>
#ifdef CONFIG_HAS_DATAFLASH
#include <asm/hardware.h>
#include <dataflash.h>
AT91S_DATAFLASH_INFO dataflash_info[CFG_MAX_DATAFLASH_BANKS];
static AT91S_DataFlash DataFlashInst;
int cs[][CFG_MAX_DATAFLASH_BANKS] = {
{CFG_DATAFLASH_LOGIC_ADDR_CS0, 0}, /* Logical adress, CS */
{CFG_DATAFLASH_LOGIC_ADDR_CS3, 3}
};
extern void AT91F_SpiInit (void);
extern int AT91F_DataflashProbe (int i, AT91PS_DataflashDesc pDesc);
extern int AT91F_DataFlashRead (AT91PS_DataFlash pDataFlash,
unsigned long addr,
unsigned long size, char *buffer);
int AT91F_DataflashInit (void)
{
int i, j;
int dfcode;
AT91F_SpiInit ();
for (i = 0; i < CFG_MAX_DATAFLASH_BANKS; i++) {
dataflash_info[i].id = 0;
dataflash_info[i].Device.pages_number = 0;
dfcode = AT91F_DataflashProbe (cs[i][1], &dataflash_info[i].Desc);
switch (dfcode) {
case AT45DB161:
dataflash_info[i].Device.pages_number = 4096;
dataflash_info[i].Device.pages_size = 528;
dataflash_info[i].Device.page_offset = 10;
dataflash_info[i].Device.byte_mask = 0x300;
dataflash_info[i].Device.cs = cs[i][1];
dataflash_info[i].Desc.DataFlash_state = IDLE;
dataflash_info[i].logical_address = cs[i][0];
dataflash_info[i].id = dfcode;
break;
case AT45DB321:
dataflash_info[i].Device.pages_number = 8192;
dataflash_info[i].Device.pages_size = 528;
dataflash_info[i].Device.page_offset = 10;
dataflash_info[i].Device.byte_mask = 0x300;
dataflash_info[i].Device.cs = cs[i][1];
dataflash_info[i].Desc.DataFlash_state = IDLE;
dataflash_info[i].logical_address = cs[i][0];
dataflash_info[i].id = dfcode;
break;
case AT45DB642:
dataflash_info[i].Device.pages_number = 8192;
dataflash_info[i].Device.pages_size = 1056;
dataflash_info[i].Device.page_offset = 11;
dataflash_info[i].Device.byte_mask = 0x700;
dataflash_info[i].Device.cs = cs[i][1];
dataflash_info[i].Desc.DataFlash_state = IDLE;
dataflash_info[i].logical_address = cs[i][0];
dataflash_info[i].id = dfcode;
break;
default:
break;
}
for (j = 0; j < dataflash_info[i].Device.pages_number; j++)
dataflash_info[i].protect[j] = FLAG_PROTECT_SET;
}
return (1);
}
void dataflash_print_info (void)
{
int i;
for (i = 0; i < CFG_MAX_DATAFLASH_BANKS; i++) {
if (dataflash_info[i].id != 0) {
printf ("DataFlash:");
switch (dataflash_info[i].id) {
case AT45DB161:
printf ("AT45DB161\n");
break;
case AT45DB321:
printf ("AT45DB321\n");
break;
case AT45DB642:
printf ("AT45DB642\n");
break;
}
printf ("Nb pages: %6d\n"
"Page Size: %6d\n"
"Size=%8d bytes\n"
"Logical address: 0x%08X\n",
(unsigned int) dataflash_info[i].Device.pages_number,
(unsigned int) dataflash_info[i].Device.pages_size,
(unsigned int) dataflash_info[i].Device.pages_number *
dataflash_info[i].Device.pages_size,
(unsigned int) dataflash_info[i].logical_address);
}
}
}
/*------------------------------------------------------------------------------*/
/* Function Name : AT91F_DataflashSelect */
/* Object : Select the correct device */
/*------------------------------------------------------------------------------*/
AT91PS_DataFlash AT91F_DataflashSelect (AT91PS_DataFlash pFlash,
unsigned int *addr)
{
char addr_valid = 0;
int i;
for (i = 0; i < CFG_MAX_DATAFLASH_BANKS; i++)
if ((*addr & 0xFF000000) == dataflash_info[i].logical_address) {
addr_valid = 1;
break;
}
if (!addr_valid) {
pFlash = (AT91PS_DataFlash) 0;
return pFlash;
}
pFlash->pDataFlashDesc = &(dataflash_info[i].Desc);
pFlash->pDevice = &(dataflash_info[i].Device);
*addr -= dataflash_info[i].logical_address;
return (pFlash);
}
/*------------------------------------------------------------------------------*/
/* Function Name : addr_dataflash */
/* Object : Test if address is valid */
/*------------------------------------------------------------------------------*/
int addr_dataflash (unsigned long addr)
{
int addr_valid = 0;
int i;
for (i = 0; i < CFG_MAX_DATAFLASH_BANKS; i++) {
if ((((int) addr) & 0xFF000000) ==
dataflash_info[i].logical_address) {
addr_valid = 1;
break;
}
}
return addr_valid;
}
/*------------------------------------------------------------------------------*/
/* Function Name : read_dataflash */
/* Object : dataflash memory read */
/*------------------------------------------------------------------------------*/
int read_dataflash (unsigned long addr, unsigned long size, char *result)
{
int AddrToRead = addr;
AT91PS_DataFlash pFlash = &DataFlashInst;
pFlash = AT91F_DataflashSelect (pFlash, &AddrToRead);
if (pFlash == 0)
return -1;
return (AT91F_DataFlashRead (pFlash, AddrToRead, size, result));
}
/*-----------------------------------------------------------------------------*/
/* Function Name : write_dataflash */
/* Object : write a block in dataflash */
/*-----------------------------------------------------------------------------*/
int write_dataflash (unsigned long addr_dest, unsigned long addr_src,
unsigned long size)
{
extern AT91S_DataFlashStatus AT91F_DataFlashWrite(
AT91PS_DataFlash, uchar *, int, int);
int AddrToWrite = addr_dest;
AT91PS_DataFlash pFlash = &DataFlashInst;
pFlash = AT91F_DataflashSelect (pFlash, &AddrToWrite);
if (AddrToWrite == -1)
return -1;
return AT91F_DataFlashWrite (pFlash, (char *) addr_src, AddrToWrite,
size);
}
void dataflash_perror (int err)
{
switch (err) {
case ERR_OK:
break;
case ERR_TIMOUT:
printf ("Timeout writing to DataFlash\n");
break;
case ERR_PROTECTED:
printf ("Can't write to protected DataFlash sectors\n");
break;
case ERR_INVAL:
printf ("Outside available DataFlash\n");
break;
case ERR_UNKNOWN_FLASH_TYPE:
printf ("Unknown Type of DataFlash\n");
break;
case ERR_PROG_ERROR:
printf ("General DataFlash Programming Error\n");
break;
default:
printf ("%s[%d] FIXME: rc=%d\n", __FILE__, __LINE__, err);
break;
}
}
#endif

View File

@@ -39,103 +39,114 @@
#ifdef CONFIG_HARD_I2C
#define IIC_WRITE 0
#define IIC_READ 1
#define I2C_WRITE 0
#define I2C_READ 1
#define IIC_OK 0
#define IIC_NOK 1
#define IIC_NACK 2
#define IIC_NOK_LA 3 /* Lost arbitration */
#define IIC_NOK_TOUT 4 /* time out */
#define I2C_OK 0
#define I2C_NOK 1
#define I2C_NACK 2
#define I2C_NOK_LA 3 /* Lost arbitration */
#define I2C_NOK_TOUT 4 /* time out */
#define IICSTAT_BSY 0x20 /* Busy bit */
#define IICSTAT_NACK 0x01 /* Nack bit */
#define IICCON_IRPND 0x10 /* Interrupt pending bit */
#define IIC_MODE_MT 0xC0 /* Master Transmit Mode */
#define IIC_MODE_MR 0x80 /* Master Receive Mode */
#define IIC_START_STOP 0x20 /* START / STOP */
#define IIC_TXRX_ENA 0x10 /* I2C Tx/Rx enable */
#define I2CSTAT_BSY 0x20 /* Busy bit */
#define I2CSTAT_NACK 0x01 /* Nack bit */
#define I2CCON_IRPND 0x10 /* Interrupt pending bit */
#define I2C_MODE_MT 0xC0 /* Master Transmit Mode */
#define I2C_MODE_MR 0x80 /* Master Receive Mode */
#define I2C_START_STOP 0x20 /* START / STOP */
#define I2C_TXRX_ENA 0x10 /* I2C Tx/Rx enable */
#define IIC_TIMEOUT 1 /* 1 seconde */
#define I2C_TIMEOUT 1 /* 1 seconde */
static int GetIICSDA(void)
static int GetI2CSDA(void)
{
return (rGPEDAT & 0x8000) >> 15;
S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
return (gpio->GPEDAT & 0x8000) >> 15;
}
#if 0
static void SetIICSDA(int x)
static void SetI2CSDA(int x)
{
rGPEDAT = (rGPEDAT & ~0x8000) | (x&1) << 15;
}
#endif
static void SetIICSCL(int x)
static void SetI2CSCL(int x)
{
rGPEDAT = (rGPEDAT & ~0x4000) | (x&1) << 14;
S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
gpio->GPEDAT = (gpio->GPEDAT & ~0x4000) | (x&1) << 14;
}
static int WaitForXfer(void)
{
S3C24X0_I2C * const i2c = S3C24X0_GetBase_I2C();
int i, status;
i = IIC_TIMEOUT * 1000;
status = rIICCON;
while ((i > 0) && !(status & IICCON_IRPND)) {
i = I2C_TIMEOUT * 1000;
status = i2c->IICCON;
while ((i > 0) && !(status & I2CCON_IRPND)) {
udelay(1000);
status = rIICCON;
status = i2c->IICCON;
i--;
}
return(status & IICCON_IRPND) ? IIC_OK : IIC_NOK_TOUT;
return(status & I2CCON_IRPND) ? I2C_OK : I2C_NOK_TOUT;
}
static int IsACK(void)
{
return(!(rIICSTAT & IICSTAT_NACK));
S3C24X0_I2C * const i2c = S3C24X0_GetBase_I2C();
return(!(i2c->IICSTAT & I2CSTAT_NACK));
}
static void ReadWriteByte(void)
{
rIICCON &= ~IICCON_IRPND;
S3C24X0_I2C * const i2c = S3C24X0_GetBase_I2C();
i2c->IICCON &= ~I2CCON_IRPND;
}
void i2c_init (int speed, int slaveadd)
{
S3C24X0_I2C * const i2c = S3C24X0_GetBase_I2C();
S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
ulong freq, pres = 16, div;
int i, status;
/* wait for some time to give previous transfer a chance to finish */
i = IIC_TIMEOUT * 1000;
status = rIICSTAT;
while ((i > 0) && (status & IICSTAT_BSY)) {
i = I2C_TIMEOUT * 1000;
status = i2c->IICSTAT;
while ((i > 0) && (status & I2CSTAT_BSY)) {
udelay(1000);
status = rIICSTAT;
status = i2c->IICSTAT;
i--;
}
if ((status & IICSTAT_BSY) || GetIICSDA() == 0) {
ulong old_gpecon = rGPECON;
if ((status & I2CSTAT_BSY) || GetI2CSDA() == 0) {
ulong old_gpecon = gpio->GPECON;
/* bus still busy probably by (most) previously interrupted transfer */
/* set IICSDA and IICSCL (GPE15, GPE14) to GPIO */
rGPECON = (rGPECON & ~0xF0000000) | 0x10000000;
/* set I2CSDA and I2CSCL (GPE15, GPE14) to GPIO */
gpio->GPECON = (gpio->GPECON & ~0xF0000000) | 0x10000000;
/* toggle IICSCL until bus idle */
SetIICSCL(0); udelay(1000);
/* toggle I2CSCL until bus idle */
SetI2CSCL(0); udelay(1000);
i = 10;
while ((i > 0) && (GetIICSDA() != 1)) {
SetIICSCL(1); udelay(1000);
SetIICSCL(0); udelay(1000);
while ((i > 0) && (GetI2CSDA() != 1)) {
SetI2CSCL(1); udelay(1000);
SetI2CSCL(0); udelay(1000);
i--;
}
SetIICSCL(1); udelay(1000);
SetI2CSCL(1); udelay(1000);
/* restore pin functions */
rGPECON = old_gpecon;
gpio->GPECON = old_gpecon;
}
/* calculate prescaler and divisor values */
@@ -150,13 +161,13 @@ void i2c_init (int speed, int slaveadd)
/* set prescaler, divisor according to freq, also set
ACKGEN, IRQ */
rIICCON = (div & 0x0F) | 0xA0 | ((pres == 512) ? 0x40 : 0);
i2c->IICCON = (div & 0x0F) | 0xA0 | ((pres == 512) ? 0x40 : 0);
/* init to SLAVE REVEIVE and set slaveaddr */
rIICSTAT = 0;
rIICADD = slaveadd;
i2c->IICSTAT = 0;
i2c->IICADD = slaveadd;
/* program Master Transmit (and implicit STOP) */
rIICSTAT = IIC_MODE_MT | IIC_TXRX_ENA;
i2c->IICSTAT = I2C_MODE_MT | I2C_TXRX_ENA;
}
@@ -176,142 +187,143 @@ int i2c_transfer(unsigned char cmd_type,
unsigned char data[],
unsigned short data_len)
{
S3C24X0_I2C * const i2c = S3C24X0_GetBase_I2C();
int i, status, result;
if (data == 0 || data_len == 0) {
/*Don't support data transfer of no length or to address 0*/
printf( "i2c_transfer: bad call\n" );
return IIC_NOK;
return I2C_NOK;
}
//CheckDelay();
/* Check I2C bus idle */
i = IIC_TIMEOUT * 1000;
status = rIICSTAT;
while ((i > 0) && (status & IICSTAT_BSY)) {
i = I2C_TIMEOUT * 1000;
status = i2c->IICSTAT;
while ((i > 0) && (status & I2CSTAT_BSY)) {
udelay(1000);
status = rIICSTAT;
status = i2c->IICSTAT;
i--;
}
if (status & IICSTAT_BSY) {
result = IIC_NOK_TOUT;
if (status & I2CSTAT_BSY) {
result = I2C_NOK_TOUT;
return(result);
}
rIICCON |= 0x80;
i2c->IICCON |= 0x80;
result = IIC_OK;
result = I2C_OK;
switch (cmd_type) {
case IIC_WRITE:
case I2C_WRITE:
if (addr && addr_len) {
rIICDS = chip;
i2c->IICDS = chip;
/* send START */
rIICSTAT = IIC_MODE_MT | IIC_TXRX_ENA | IIC_START_STOP;
i2c->IICSTAT = I2C_MODE_MT | I2C_TXRX_ENA | I2C_START_STOP;
i = 0;
while ((i < addr_len) && (result == IIC_OK)) {
while ((i < addr_len) && (result == I2C_OK)) {
result = WaitForXfer();
rIICDS = addr[i];
i2c->IICDS = addr[i];
ReadWriteByte();
i++;
}
i = 0;
while ((i < data_len) && (result == IIC_OK)) {
while ((i < data_len) && (result == I2C_OK)) {
result = WaitForXfer();
rIICDS = data[i];
i2c->IICDS = data[i];
ReadWriteByte();
i++;
}
} else {
rIICDS = chip;
i2c->IICDS = chip;
/* send START */
rIICSTAT = IIC_MODE_MT | IIC_TXRX_ENA | IIC_START_STOP;
i2c->IICSTAT = I2C_MODE_MT | I2C_TXRX_ENA | I2C_START_STOP;
i = 0;
while ((i < data_len) && (result = IIC_OK)) {
while ((i < data_len) && (result = I2C_OK)) {
result = WaitForXfer();
rIICDS = data[i];
i2c->IICDS = data[i];
ReadWriteByte();
i++;
}
}
if (result == IIC_OK)
if (result == I2C_OK)
result = WaitForXfer();
/* send STOP */
rIICSTAT = IIC_MODE_MR | IIC_TXRX_ENA;
i2c->IICSTAT = I2C_MODE_MR | I2C_TXRX_ENA;
ReadWriteByte();
break;
case IIC_READ:
case I2C_READ:
if (addr && addr_len) {
rIICSTAT = IIC_MODE_MT | IIC_TXRX_ENA;
rIICDS = chip;
i2c->IICSTAT = I2C_MODE_MT | I2C_TXRX_ENA;
i2c->IICDS = chip;
/* send START */
rIICSTAT |= IIC_START_STOP;
i2c->IICSTAT |= I2C_START_STOP;
result = WaitForXfer();
if (IsACK()) {
i = 0;
while ((i < addr_len) && (result == IIC_OK)) {
rIICDS = addr[i];
while ((i < addr_len) && (result == I2C_OK)) {
i2c->IICDS = addr[i];
ReadWriteByte();
result = WaitForXfer();
i++;
}
rIICDS = chip;
i2c->IICDS = chip;
/* resend START */
rIICSTAT = IIC_MODE_MR | IIC_TXRX_ENA | IIC_START_STOP;
i2c->IICSTAT = I2C_MODE_MR | I2C_TXRX_ENA | I2C_START_STOP;
ReadWriteByte();
result = WaitForXfer();
i = 0;
while ((i < data_len) && (result == IIC_OK)) {
while ((i < data_len) && (result == I2C_OK)) {
/* disable ACK for final READ */
if (i == data_len - 1)
rIICCON &= ~0x80;
i2c->IICCON &= ~0x80;
ReadWriteByte();
result = WaitForXfer();
data[i] = rIICDS;
data[i] = i2c->IICDS;
i++;
}
} else {
result = IIC_NACK;
result = I2C_NACK;
}
} else {
rIICSTAT = IIC_MODE_MR | IIC_TXRX_ENA;
rIICDS = chip;
i2c->IICSTAT = I2C_MODE_MR | I2C_TXRX_ENA;
i2c->IICDS = chip;
/* send START */
rIICSTAT |= IIC_START_STOP;
i2c->IICSTAT |= I2C_START_STOP;
result = WaitForXfer();
if (IsACK()) {
i = 0;
while ((i < data_len) && (result == IIC_OK)) {
while ((i < data_len) && (result == I2C_OK)) {
/* disable ACK for final READ */
if (i == data_len - 1)
rIICCON &= ~0x80;
i2c->IICCON &= ~0x80;
ReadWriteByte();
result = WaitForXfer();
data[i] = rIICDS;
data[i] = i2c->IICDS;
i++;
}
} else {
result = IIC_NACK;
result = I2C_NACK;
}
}
/* send STOP */
rIICSTAT = IIC_MODE_MR | IIC_TXRX_ENA;
i2c->IICSTAT = I2C_MODE_MR | I2C_TXRX_ENA;
ReadWriteByte();
break;
default:
printf( "i2c_transfer: bad call\n" );
result = IIC_NOK;
result = I2C_NOK;
break;
}
@@ -329,7 +341,7 @@ int i2c_probe (uchar chip)
* address was <ACK>ed (i.e. there was a chip at that address which
* drove the data line low).
*/
return(i2c_transfer (IIC_READ, chip << 1, 0, 0, buf, 1) != IIC_OK);
return(i2c_transfer (I2C_READ, chip << 1, 0, 0, buf, 1) != I2C_OK);
}
int i2c_read (uchar chip, uint addr, int alen, uchar * buffer, int len)
@@ -365,7 +377,7 @@ int i2c_read (uchar chip, uint addr, int alen, uchar * buffer, int len)
if( alen > 0 )
chip |= ((addr >> (alen * 8)) & CFG_I2C_EEPROM_ADDR_OVERFLOW);
#endif
if( (ret = i2c_transfer(IIC_READ, chip<<1, &xaddr[4-alen], alen, buffer, len )) != 0) {
if( (ret = i2c_transfer(I2C_READ, chip<<1, &xaddr[4-alen], alen, buffer, len )) != 0) {
printf( "I2c read: failed %d\n", ret);
return 1;
}
@@ -403,7 +415,7 @@ int i2c_write (uchar chip, uint addr, int alen, uchar * buffer, int len)
if( alen > 0 )
chip |= ((addr >> (alen * 8)) & CFG_I2C_EEPROM_ADDR_OVERFLOW);
#endif
return (i2c_transfer(IIC_WRITE, chip<<1, &xaddr[4-alen], alen, buffer, len ) != 0);
return (i2c_transfer(I2C_WRITE, chip<<1, &xaddr[4-alen], alen, buffer, len ) != 0);
}
#endif /* CONFIG_HARD_I2C */

View File

@@ -46,7 +46,8 @@ int serial_init (void)
{
DECLARE_GLOBAL_DATA_PTR;
int clock_divisor = CFG_NS16550_CLK / 16 / gd->baudrate;
int clock_divisor = (CFG_NS16550_CLK + gd->baudrate * 8 )
/ (gd->baudrate * 16);
#ifdef CFG_NS87308
initialise_ns87308();

View File

@@ -52,6 +52,7 @@
. o skeleton.c by Donald Becker ( becker@cesdis.gsfc.nasa.gov )
.
. History:
. 06/19/03 Richard Woodruff Made u-boot environment aware and added mac addr checks.
. 10/17/01 Marco Hasewinkel Modify for DNP/1110
. 07/25/01 Woojung Huh Modify for ADS Bitsy
. 04/25/01 Daris A Nevil Initial public release through SMSC
@@ -176,7 +177,7 @@ void smc_destructor(void);
. The kernel calls this function when someone wants to use the device,
. typically 'ifconfig ethX up'.
*/
static int smc_open(void);
static int smc_open(bd_t *bd);
/*
@@ -199,7 +200,12 @@ static void smc_phy_configure(void);
*/
static int smc_rcv(void);
/* See if a MAC address is defined in the current environment. If so use it. If not
. print a warning and set the environment and other globals with the default.
. If an EEPROM is present it really should be consulted.
*/
int smc_get_ethaddr(bd_t *bd);
int get_rom_mac(char *v_rom_mac);
/*
------------------------------------------------------------
@@ -226,7 +232,7 @@ void smc_set_mac_addr(const char *addr) {
/*
* smc_get_macaddr is no longer used. If you want to override the default
* mac address, call smc_get_mac_addr as a part of the board initialisation.
* mac address, call smc_get_mac_addr as a part of the board initialization.
*/
#if 0
@@ -317,6 +323,17 @@ static int poll4int( byte mask, int timeout ) {
return 0;
}
/* Only one release command at a time, please */
static inline void smc_wait_mmu_release_complete(void)
{
int count = 0;
/* assume bank 2 selected */
while ( SMC_inw(MMU_CMD_REG) & MC_BUSY ) {
udelay(1); // Wait until not busy
if( ++count > 200) break;
}
}
/*
. Function: smc_reset( void )
. Purpose:
@@ -374,6 +391,7 @@ static void smc_reset( void )
/* Reset the MMU */
SMC_SELECT_BANK( 2 );
smc_wait_mmu_release_complete();
SMC_outw( MC_RESET, MMU_CMD_REG );
while ( SMC_inw( MMU_CMD_REG ) & MC_BUSY )
udelay(1); /* Wait until not busy */
@@ -653,14 +671,13 @@ void smc_destructor()
* Set up everything, reset the card, etc ..
*
*/
static int smc_open()
static int smc_open(bd_t *bd)
{
int i; /* used to set hw ethernet address */
int i, err;
PRINTK2("%s:smc_open\n", SMC_DEV_NAME);
/* reset the hardware */
smc_reset();
smc_enable();
@@ -669,10 +686,16 @@ static int smc_open()
smc_phy_configure();
#endif
/* conservative setting (10Mbps, HalfDuplex, no AutoNeg.) */
/* SMC_SELECT_BANK(0); */
/* SMC_outw(0, RPC_REG); */
SMC_SELECT_BANK(1);
err = smc_get_ethaddr(bd); /* set smc_mac_addr, and sync it with u-boot globals */
if(err < 0){
memset(bd->bi_enetaddr, 0, 6); /* hack to make error stick! upper code will abort if not set*/
return(-1); /* upper code ignores this, but NOT bi_enetaddr */
}
#ifdef USE_32_BIT
for ( i = 0; i < 6; i += 2 ) {
@@ -1371,8 +1394,7 @@ static void print_packet( byte * buf, int length )
#endif
int eth_init(bd_t *bd) {
smc_open();
return 0;
return (smc_open(bd));
}
void eth_halt() {
@@ -1387,4 +1409,74 @@ int eth_send(volatile void *packet, int length) {
return smc_send_packet(packet, length);
}
int smc_get_ethaddr(bd_t *bd)
{
int env_size, rom_valid, env_present = 0, reg;
char *s = NULL, *e, *v_mac, es[] = "11:22:33:44:55:66";
uchar s_env_mac[64], v_env_mac[6], v_rom_mac[6];
env_size = getenv_r ("ethaddr", s_env_mac, sizeof (s_env_mac));
if ((env_size > 0) && (env_size < sizeof(es))) { /* exit if env is bad */
printf("\n*** ERROR: ethaddr is not set properly!!\n");
return(-1);
}
if(env_size > 0){
env_present = 1;
s = s_env_mac;
}
for (reg = 0; reg < 6; ++reg) { /* turn string into mac value */
v_env_mac[reg] = s ? simple_strtoul (s, &e, 16) : 0;
if (s)
s = (*e) ? e + 1 : e;
}
rom_valid = get_rom_mac(v_rom_mac); /* get ROM mac value if any */
if(!env_present){ /* if NO env */
if(rom_valid){ /* but ROM is valid */
v_mac = v_rom_mac;
sprintf (s_env_mac, "%02X:%02X:%02X:%02X:%02X:%02X", v_mac[0],
v_mac[1] ,v_mac[2], v_mac[3],v_mac[4], v_mac[5]) ;
setenv ("ethaddr", s_env_mac);
}else{ /* no env, bad ROM */
printf("\n*** ERROR: ethaddr is NOT set !!\n");
return(-1);
}
}else /* good env, don't care ROM */
v_mac = v_env_mac; /* always use a good env over a ROM */
if(env_present && rom_valid) /* if both env and ROM are good */
if(memcmp(v_env_mac, v_rom_mac, 6) != 0){
printf("\n*** Warning: Environment and ROM MAC addresses don't match\n");
printf("*** Using Environment MAC\n");
}
memcpy (bd->bi_enetaddr, v_mac, 6); /* update global address to match env (allows env changing) */
smc_set_mac_addr(v_mac); /* use old function to update smc default */
return(0);
}
int get_rom_mac(char *v_rom_mac)
{
int is_rom_present = 0;
#ifdef HARDCODE_MAC /* used for testing or to supress run time warnings */
char hw_mac_addr[] = {0x02, 0x80, 0xad, 0x20, 0x31, 0xb8};
memcpy (v_rom_mac, hw_mac_addr, 6);
return(1);
#else
if(is_rom_present)
{
/* if eeprom contents are valid
* extract mac address into hw_mac_addr, 8 or 16 bit accesses
* memcpy (v_rom_mac, hc_mac_addr, 6);
* return(1);
*/
}
memset(v_rom_mac, 0, 6);
return(0);
#endif
}
#endif /* CONFIG_DRIVER_SMC91111 */

View File

@@ -80,7 +80,7 @@ typedef unsigned long int dword;
#define SMC_inw(r) (*((volatile word *)(SMC_BASE_ADDRESS+(r))))
#define SMC_inb(p) ({ \
unsigned int __p = (unsigned int)(SMC_BASE_ADDRESS + (p)); \
unsigned int __v = *(volatile unsigned short *)((SMC_BASE_ADDRESS + __p) & ~1); \
unsigned int __v = *(volatile unsigned short *)((__p) & ~1); \
if (__p & 1) __v >>= 8; \
else __v &= 0xff; \
__v; })

View File

@@ -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
@@ -22,13 +22,12 @@
*/
#include <common.h>
#include <mpc8xx.h>
#include <status_led.h>
/*
* The purpose of this code is to signal the operational status of a
* target which usually boots over the network; while running in
* PCBoot, a status LED is blinking. As soon as a valid BOOTP reply
* U-Boot, a status LED is blinking. As soon as a valid BOOTP reply
* message has been received, the LED is turned off. The Linux
* kernel, once it is running, will start blinking the LED again,
* with another frequency.
@@ -39,10 +38,10 @@
#ifdef CONFIG_STATUS_LED
typedef struct {
ulong mask;
int state;
int period;
int cnt;
led_id_t mask;
int state;
int period;
int cnt;
} led_dev_t;
led_dev_t led_dev[] = {
@@ -80,89 +79,53 @@ static int status_led_init_done = 0;
static void status_led_init (void)
{
volatile immap_t *immr = (immap_t *)CFG_IMMR;
int i;
led_dev_t *ld;
int i;
for (i=0; i<MAX_LED_DEV; ++i) {
led_dev_t *ld = &led_dev[i];
immr->STATUS_LED_PAR &= ~(ld->mask);
#ifdef STATUS_LED_ODR
immr->STATUS_LED_ODR &= ~(ld->mask);
#endif
#if (STATUS_LED_ACTIVE == 0)
if (ld->state == STATUS_LED_ON)
immr->STATUS_LED_DAT &= ~(ld->mask);
else
immr->STATUS_LED_DAT |= ld->mask ;
#else
if (ld->state == STATUS_LED_ON)
immr->STATUS_LED_DAT |= ld->mask ;
else
immr->STATUS_LED_DAT &= ~(ld->mask);
#endif
immr->STATUS_LED_DIR |= ld->mask ;
}
status_led_init_done = 1;
for (i = 0, ld = led_dev; i < MAX_LED_DEV; i++, ld++)
__led_init (ld->mask, ld->state);
status_led_init_done = 1;
}
void status_led_tick (ulong timestamp)
{
volatile immap_t *immr = (immap_t *)CFG_IMMR;
int i;
led_dev_t *ld;
int i;
if (!status_led_init_done)
status_led_init();
if (!status_led_init_done)
status_led_init ();
for (i=0; i<MAX_LED_DEV; ++i) {
led_dev_t *ld = &led_dev[i];
for (i = 0, ld = led_dev; i < MAX_LED_DEV; i++, ld++) {
if (ld->state != STATUS_LED_BLINKING)
continue;
if (ld->state != STATUS_LED_BLINKING)
continue;
if (++ld->cnt >= ld->period) {
__led_toggle (ld->mask);
ld->cnt -= ld->period;
}
if (++(ld->cnt) >= ld->period) {
immr->STATUS_LED_DAT ^= ld->mask;
ld->cnt -= ld->period;
}
}
}
void status_led_set (int led, int state)
{
volatile immap_t *immr = (immap_t *)CFG_IMMR;
led_dev_t *ld;
led_dev_t *ld;
if (led < 0 || led >= MAX_LED_DEV)
return;
if (led < 0 || led >= MAX_LED_DEV)
return;
if (!status_led_init_done)
status_led_init();
if (!status_led_init_done)
status_led_init ();
ld = &led_dev[led];
ld = &led_dev[led];
switch (state) {
default:
return;
case STATUS_LED_BLINKING:
ld->cnt = 0; /* always start with full period */
/* fall through */ /* always start with LED _ON_ */
case STATUS_LED_ON:
#if (STATUS_LED_ACTIVE == 0)
immr->STATUS_LED_DAT &= ~(ld->mask);
#else
immr->STATUS_LED_DAT |= ld->mask ;
#endif
break;
case STATUS_LED_OFF:
#if (STATUS_LED_ACTIVE == 0)
immr->STATUS_LED_DAT |= ld->mask ;
#else
immr->STATUS_LED_DAT &= ~(ld->mask);
#endif
break;
}
ld->state = state;
ld->state = state;
if (state == STATUS_LED_BLINKING) {
ld->cnt = 0; /* always start with full period */
state = STATUS_LED_ON; /* always start with LED _ON_ */
}
__led_set (ld->mask, state);
}
#endif /* CONFIG_STATUS_LED */

View File

@@ -27,7 +27,7 @@ include $(TOPDIR)/config.mk
LIB = libdtt.a
OBJS = lm75.o ds1621.o
OBJS = lm75.o ds1621.o adm1021.o
all: $(LIB)

171
dtt/adm1021.c Normal file
View File

@@ -0,0 +1,171 @@
/*
* (C) Copyright 2003
* Murray Jensen, CSIRO-MIT, Murray.Jensen@csiro.au
*
* based on dtt/lm75.c which is ...
*
* (C) Copyright 2001
* Bill Hunter, Wave 7 Optics, williamhunter@mediaone.net
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
/*
* Analog Devices's ADM1021
* "Low Cost Microprocessor System Temperature Monitor"
*/
#include <common.h>
#ifdef CONFIG_DTT_ADM1021
#include <i2c.h>
#include <dtt.h>
typedef
struct {
uint i2c_addr:7; /* 7bit i2c chip address */
uint conv_rate:3; /* conversion rate */
uint enable_alert:1; /* enable alert output pin */
uint enable_local:1; /* enable internal temp sensor */
uint max_local:8; /* internal temp maximum */
uint min_local:8; /* internal temp minimum */
uint enable_remote:1; /* enable remote temp sensor */
uint max_remote:8; /* remote temp maximum */
uint min_remote:8; /* remote temp minimum */
}
dtt_cfg_t;
dtt_cfg_t dttcfg[] = CFG_DTT_ADM1021;
int
dtt_read (int sensor, int reg)
{
dtt_cfg_t *dcp = &dttcfg[sensor >> 1];
uchar data;
if (i2c_read(dcp->i2c_addr, reg, 1, &data, 1) != 0)
return -1;
return (int)data;
} /* dtt_read() */
int
dtt_write (int sensor, int reg, int val)
{
dtt_cfg_t *dcp = &dttcfg[sensor >> 1];
uchar data;
data = (uchar)(val & 0xff);
if (i2c_write(dcp->i2c_addr, reg, 1, &data, 1) != 0)
return 1;
return 0;
} /* dtt_write() */
static int
_dtt_init (int sensor)
{
dtt_cfg_t *dcp = &dttcfg[sensor >> 1];
int reg, val;
if (((sensor & 1) == 0 ? dcp->enable_local : dcp->enable_remote) == 0)
return 1; /* sensor is disabled (or rather ignored) */
/*
* Setup High Limit register
*/
if ((sensor & 1) == 0) {
reg = DTT_WRITE_LOC_HIGHLIM;
val = dcp->max_local;
}
else {
reg = DTT_WRITE_REM_HIGHLIM;
val = dcp->max_remote;
}
if (dtt_write (sensor, reg, val) != 0)
return 1;
/*
* Setup Low Limit register
*/
if ((sensor & 1) == 0) {
reg = DTT_WRITE_LOC_LOWLIM;
val = dcp->min_local;
}
else {
reg = DTT_WRITE_REM_LOWLIM;
val = dcp->min_remote;
}
if (dtt_write (sensor, reg, val) != 0)
return 1;
/* shouldn't hurt if the rest gets done twice */
/*
* Setup Conversion Rate register
*/
if (dtt_write (sensor, DTT_WRITE_CONVRATE, dcp->conv_rate) != 0)
return 1;
/*
* Setup configuraton register
*/
val = 0; /* running */
if (dcp->enable_alert == 0)
val |= DTT_CONFIG_ALERT_MASKED; /* mask ALERT pin */
if (dtt_write (sensor, DTT_WRITE_CONFIG, val) != 0)
return 1;
return 0;
} /* _dtt_init() */
int
dtt_init (void)
{
int i;
unsigned char sensors[] = CONFIG_DTT_SENSORS;
const char *const header = "DTT: ";
for (i = 0; i < sizeof(sensors); i++) {
if (_dtt_init(sensors[i]) != 0)
printf ("%s%d FAILED INIT\n", header, i+1);
else
printf ("%s%d is %i C\n", header, i+1,
dtt_get_temp(sensors[i]));
}
return (0);
} /* dtt_init() */
int
dtt_get_temp (int sensor)
{
signed char val;
if ((sensor & 1) == 0)
val = dtt_read(sensor, DTT_READ_LOC_VALUE);
else
val = dtt_read(sensor, DTT_READ_REM_VALUE);
return (int) val;
} /* dtt_get_temp() */
#endif /* CONFIG_DTT_ADM1021 */

View File

@@ -22,7 +22,7 @@
#
#
SUBDIRS := jffs2 fdos
SUBDIRS := jffs2 fdos fat
.depend all:
@for dir in $(SUBDIRS) ; do \

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