diff options
Diffstat (limited to 'board/mousse')
-rwxr-xr-x | board/mousse/Makefile | 41 | ||||
-rwxr-xr-x | board/mousse/README | 346 | ||||
-rwxr-xr-x | board/mousse/config.mk | 28 | ||||
-rwxr-xr-x | board/mousse/flash.c | 939 | ||||
-rwxr-xr-x | board/mousse/flash.h | 78 | ||||
-rwxr-xr-x | board/mousse/m48t59y.c | 322 | ||||
-rwxr-xr-x | board/mousse/m48t59y.h | 57 | ||||
-rwxr-xr-x | board/mousse/mousse.c | 86 | ||||
-rwxr-xr-x | board/mousse/mousse.h | 259 | ||||
-rwxr-xr-x | board/mousse/pci.c | 283 | ||||
-rwxr-xr-x | board/mousse/u-boot.lds | 131 | ||||
-rwxr-xr-x | board/mousse/u-boot.lds.ram | 105 | ||||
-rwxr-xr-x | board/mousse/u-boot.lds.rom | 133 |
13 files changed, 2808 insertions, 0 deletions
diff --git a/board/mousse/Makefile b/board/mousse/Makefile new file mode 100755 index 0000000..ddc5546 --- /dev/null +++ b/board/mousse/Makefile @@ -0,0 +1,41 @@ + +# +# (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 m48t59y.o pci.o flash.o + +$(LIB): .depend $(OBJS) + $(AR) crv $@ $(OBJS) + +######################################################################### + +.depend: Makefile $(SOBJS:.o=.S) $(OBJS:.o=.c) + $(CC) -M $(CFLAGS) $(SOBJS:.o=.S) $(OBJS:.o=.c) > $@ + +sinclude .depend + +######################################################################### diff --git a/board/mousse/README b/board/mousse/README new file mode 100755 index 0000000..d5dda7a --- /dev/null +++ b/board/mousse/README @@ -0,0 +1,346 @@ + +U-Boot for MOUSSE/MPC8240 (KAHLUA) +---------------------------------- +James Dougherty (jfd@broadcom.com), 09/10/01 + +The Broadcom/Vooha Mousse board is a 3U Compact PCI system board +which uses the MPC8240, a 64MB SDRAM SIMM, and has onboard +DEC 21143, NS16550 UART, an SGS M48T59Y TOD, and 4MB FLASH. +See also: http://www.vooha.com/ + +* NVRAM setenv/printenv/savenv supported. +* Date Command +* Serial Console support +* Network support +* FLASH of kernel images is supported. +* FLASH of U-Boot to onboard and PLCC boot region. +* Kernel command line options from NVRAM is supported. +* IP PNP options supported. + +U-Boot Loading... + + +U-Boot 1.0.5 (Sep 10 2001 - 00:22:25) + +CPU: MPC8240 Revision 1.1 at 198 MHz: 16 kB I-Cache 16 kB D-Cache +Board: MOUSSE MPC8240/KAHLUA - CHRP (MAP B) +Built: Sep 10 2001 at 01:01:50 +MPLD: Revision 127 +Local Bus: 33 MHz +RTC: M48T589 TOD/NVRAM (8176) bytes + Current date/time: 9/10/2001 0:18:52 +DRAM: 64 MB +FLASH: 1.960 MB +PCI: scanning bus0 ... + bus dev fn venID devID class rev MBAR0 MBAR1 IPIN ILINE + 00 00 00 1057 0003 060000 11 00000008 00000000 01 00 + 00 0d 00 1011 0019 020000 41 80000001 80000000 01 01 + 00 0e 00 105a 4d38 018000 01 a0000001 a0001001 01 03 +In: serial +Out: serial +Err: serial + +Hit any key to stop autoboot: 0 +=> + +I. Root FileSystem/IP Configuration + +bootcmd=tftp 100000 vmlinux.img;bootm +bootdelay=3 +baudrate=9600 +ipaddr=<IP ADDRESS> +netmask=<NETMASK> +hostname=<NAME> +serverip=<NFS SERVER IP ADDRESS> +ethaddr=00:00:10:20:30:44 +nfsroot=<NFS SERVER IP ADDRESS>:/boot/root-fs +gateway=<IP ADDRESS> +root=/dev/nfs +stdin=serial +stdout=serial +stderr=serial + +NVRAM environment variables. + +use the command: + +setenv <attribute> <value> + +type "saveenv" to write to NVRAM. + + +II. To boot from a hard drive: + +setenv root /dev/hda1 + + +III. IP options which configure the network: + +ipaddr=<IP ADDRESS OF MACHINE> +netmask=<NETMASK> +hostname=mousse +ethaddr=00:00:10:20:30:44 +gateway=<IP ADDRESS OF GATEWAY/ROUTER> + + +IV. IP Options which configure NFS Root/Boot Support + +root=/dev/nfs +serverip=<NFS SERVER IP ADDRESS> +nfsroot=<NFS SERVER IP ADDRESS>:/boot/root-fs + +V. U-Boot Image Support + +The U-Boot boot loader assumes that after you build +your kernel (vmlinux), you will create a U-Boot image +using the following commands or script: + +#!/bin/csh +/bin/touch vmlinux.img +/bin/rm vmlinux.img +set path=($TOOLBASE/bin $path) +set path=($U_BOOT/tools $path) +powerpc-linux-objcopy -S -O binary vmlinux vmlinux.bin +gzip -vf vmlinux.bin +mkimage -A ppc -O linux -T kernel -C gzip -a 0 -e 0 -n vmlinux.bin.gz -d vmlinux.bin.gz vmlinux.img +ls -l vmlinux.img + + +VI. ONBOARD FLASH Support + +FLASH support is provided for the onboard FLASH chip Bootrom area. +U-Boot is loaded into either the ROM boot region of the FLASH chip, +after first being boot-strapped from a pre-progammed AMD29F040 PLCC +bootrom. The PLCC needs to be programmed with a ROM burner using +AMD 29F040 ROM parts and the u-boot.bin or u-boot.hex (S-Record) +images. + +The PLCC overlays this same region of flash as the onboard FLASH, +the jumper J100 is a chip-select for which flash chip you want to +progam. When jumper J100 is connected to pins 2-3, you boot from +PLCC FLASH. + +To bringup a system, simply flash a flash an AMD29F040 PLCC +bootrom, and put this in the PLCC socket. Move jumper J100 to +pins 2-3 and boot from the PLCC. + + +Now, while the system is running, move Jumper J100 to +pins 1-2 and follow the procedure below to FLASH a bootrom +(u-boot.bin) image into the onboard bootrom region (AMD29LV160DB): + +tftp 100000 u-boot.bin +protect off FFF00000 FFF7FFFF +erase FFF00000 FFF7FFFF +cp.b 100000 FFF00000 \${filesize}\ + + +Here is an example: + +=>tftp 100000 u-boot.bin +eth_halt +eth0: DC21143 Ethernet adapter(bus=0, device=13, func=0) +DEC Ethernet iobase=0x80000000 +ARP broadcast 1 +Filename 'u-boot.bin'. +Load address: 0x100000 +Loading: ######################### +done +Bytes transferred = 123220 (1e154 hex) +eth_halt +=>protect off FFF00000 FFF7FFFF +Un-Protected 8 sectors +=>erase FFF00000 FFF7FFFF +Erase Flash from 0xfff00000 to 0xfff7ffff +Erase FLASH[PLCC_BOOT] -8 sectors:........ done +Erased 8 sectors +=>cp.b 100000 FFF00000 1e154 +Copy to Flash... FLASH[PLCC_BOOT]:..done +=> + + +B. FLASH RAMDISK REGION + +FLASH support is provided for an Onboard 512K RAMDISK region. + +TThe following commands will FLASH a bootrom (u-boot.bin) image +into the onboard FLASH region (AMD29LV160DB 2MB FLASH): + +tftp 100000 u-boot.bin +protect off FFF80000 FFFFFFFF +erase FFF80000 FFFFFFFF +cp.b 100000 FFF80000 \${filesize}\ + + +C. FLASH KERNEL REGION (960KB) + +FLASH support is provided for the 960KB onboard FLASH1 segment. +This allows flashing of kernel images which U-Boot can load +and run (standalone) from the onboard FLASH chip. It also assumes + +The following commands will FLASH a kernel image to 0xffe10000 + +tftp 100000 vmlinux.img +protect off FFE10000 FFEFFFFF +erase FFE10000 FFEFFFFF +cp.b 100000 FFE10000 \${filesize}\ +reset + +Here is an example: + + +=>tftp 100000 vmlinux.img +eth_halt +eth0: DC21143 Ethernet adapter(bus=0, device=13, func=0) +DEC Ethernet iobase=0x80000000 +ARP broadcast 1 +TFTP from server 209.128.93.133; our IP address is 209.128.93.138 +Filename 'vmlinux.img'. +Load address: 0x100000 +Loading: ##################################################################################################################################################### +done +Bytes transferred = 760231 (b99a7 hex) +eth_halt +=>protect off FFE10000 FFEFFFFF +Un-Protected 15 sectors +=>erase FFE10000 FFEFFFFF +Erase Flash from 0xffe10000 to 0xffefffff +Erase FLASH[F0_SA3(KERNEL)] -15 sectors:............... done +Erased 15 sectors +=>cp.b 100000 FFE10000 b99a7 +Copy to Flash... FLASH[F0_SA3(KERNEL)]:............done +=> + + +When finished, use the command: + +bootm ffe10000 + +to start the kernel. + +Finally, to make this the default boot command, use +the following commands: + +setenv bootcmd bootm ffe10000 +savenv + +to make it automatically boot the kernel from FLASH. + + +To go back to development mode (NFS boot) + +setenv bootcmd tftp 100000 vmlinux.img\;bootm +savenv + + +=>tftp 100000 vmlinux.img +eth0: DC21143 Ethernet adapter(bus=0, device=13, func=0) +DEC Ethernet iobase=0x80000000 +ARP broadcast 1 +Filename 'vmlinux.img'. +Load address: 0x100000 +Loading: #################################################################################################################################################### +done +Bytes transferred = 752717 (b7c4d hex) +eth_halt +=>protect off FFE10000 FFEFFFFF +Un-Protected 15 sectors +=>erase FFE10000 FFEFFFFF +Erase Flash from 0xffe10000 to 0xffefffff +Erase FLASH[F0_SA3(KERNEL)] -15 sectors:............... done +Erased 15 sectors +=>cp.b 100000 FFE10000 b7c4d +Copy to Flash... FLASH[F0_SA3(KERNEL)]:............done +=>bootm ffe10000 +## Booting image at ffe10000 ... + Image Name: vmlinux.bin.gz + Image Type: PowerPC Linux Kernel Image (gzip compressed) + Data Size: 752653 Bytes = 735 kB = 0 MB + Load Address: 00000000 + Entry Point: 00000000 + Verifying Checksum ... OK + Uncompressing Kernel Image ... OK +Total memory = 64MB; using 0kB for hash table (at 00000000) +Linux version 2.4.2_hhl20 (jfd@atlantis) (gcc version 2.95.2 19991024 (release)) #597 Wed Sep 5 23:23:23 PDT 2001 +cpu0: MPC8240/KAHLUA : MOUSSE Platform : 64MB RAM: MPLD Rev. 7f +Sandpoint port (C) 2000, 2001 MontaVista Software, Inc. (source@mvista.com) +IP PNP: 802.3 Ethernet Address=<0:0:10:20:30:44> +NOTICE: mounting root file system via NFS +On node 0 totalpages: 16384 +zone(0): 16384 pages. +zone(1): 0 pages. +zone(2): 0 pages. +time_init: decrementer frequency = 16.665914 MHz +time_init: MPC8240 PCI Bus frequency = 33.331828 MHz +Calibrating delay loop... 133.12 BogoMIPS +Memory: 62436k available (1336k kernel code, 500k data, 88k init, 0k highmem) +Dentry-cache hash table entries: 8192 (order: 4, 65536 bytes) +Buffer-cache hash table entries: 4096 (order: 2, 16384 bytes) +Page-cache hash table entries: 16384 (order: 4, 65536 bytes) +Inode-cache hash table entries: 4096 (order: 3, 32768 bytes) +POSIX conformance testing by UNIFIX +PCI: Probing PCI hardware +Linux NET4.0 for Linux 2.4 +Based upon Swansea University Computer Society NET3.039 +Initializing RT netlink socket +Starting kswapd v1.8 +pty: 256 Unix98 ptys configured +block: queued sectors max/low 41394kB/13798kB, 128 slots per queue +Uniform Multi-Platform E-IDE driver Revision: 6.31 +ide: Assuming 33MHz system bus speed for PIO modes; override with idebus=xx +PDC20262: IDE controller on PCI bus 00 dev 70 +PDC20262: chipset revision 1 +PDC20262: not 100% native mode: will probe irqs later +PDC20262: ROM enabled at 0x000d0000 +PDC20262: (U)DMA Burst Bit DISABLED Primary PCI Mode Secondary PCI Mode. +PDC20262: FORCING BURST BIT 0x00 -> 0x01 ACTIVE +PDC20262: irq=3 dev->irq=3 + ide0: BM-DMA at 0xbfff00-0xbfff07, BIOS settings: hda:DMA, hdb:DMA + ide1: BM-DMA at 0xbfff08-0xbfff0f, BIOS settings: hdc:pio, hdd:pio +hda: WDC WD300AB-00BVA0, ATA DISK drive +hdc: SONY CD-RW CRX160E, ATAPI CD/DVD-ROM drive +ide0 at 0xbfff78-0xbfff7f,0xbfff76 on irq 3 +ide1 at 0xbfff68-0xbfff6f,0xbfff66 on irq 3 +hda: 58633344 sectors (30020 MB) w/2048KiB Cache, CHS=58168/16/63, UDMA(66) +hdc: ATAPI 32X CD-ROM CD-R/RW drive, 4096kB Cache +Uniform CD-ROM driver Revision: 3.12 +Partition check: + /dev/ide/host0/bus0/target0/lun0: p1 p2 +hd: unable to get major 3 for hard disk +udf: registering filesystem +loop: loaded (max 8 devices) +Serial driver version 5.02 (2000-08-09) with MANY_PORTS SHARE_IRQ SERIAL_PCI enabled +ttyS00 at 0xffe08080 (irq = 4) is a ST16650 +Linux Tulip driver version 0.9.13a (January 20, 2001) +eth0: Digital DS21143 Tulip rev 65 at 0xbfff80, EEPROM not present, 00:00:10:20:30:44, IRQ 1. +eth0: MII transceiver #0 config 3000 status 7829 advertising 01e1. +NET4: Linux TCP/IP 1.0 for NET4.0 +IP Protocols: ICMP, UDP, TCP +IP: routing cache hash table of 512 buckets, 4Kbytes +TCP: Hash tables configured (established 4096 bind 4096) +NET4: Unix domain sockets 1.0/SMP for Linux NET4.0. +devfs: v0.102 (20000622) Richard Gooch (rgooch@atnf.csiro.au) +devfs: boot_options: 0x0 +VFS: Mounted root (nfs filesystem). +Mounted devfs on /dev +Freeing unused kernel memory: 88k init 4k openfirmware +eth0: Setting full-duplex based on MII#0 link partner capability of 45e1. +INIT: version 2.78 booting +INIT: Entering runlevel: 2 + + +Welcome to Linux/PPC +MPC8240/MOUSSE + + +mousse login: root +Password: +PAM_unix[13]: (login) session opened for user root by LOGIN(uid=0) +Last login: Thu Sep 6 00:16:51 2001 on console + + +Welcome to Linux/PPC +MPC8240/MOUSSE + + +mousse# diff --git a/board/mousse/config.mk b/board/mousse/config.mk new file mode 100755 index 0000000..64cffa4 --- /dev/null +++ b/board/mousse/config.mk @@ -0,0 +1,28 @@ +# +# (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 +# + +# +# MOUSSE boards +# +TEXT_BASE = 0xFFF00000 +PLATFORM_CPPFLAGS += -DTEXT_BASE=$(TEXT_BASE) diff --git a/board/mousse/flash.c b/board/mousse/flash.c new file mode 100755 index 0000000..2c32b8f --- /dev/null +++ b/board/mousse/flash.c @@ -0,0 +1,939 @@ +/* + * MOUSSE/MPC8240 Board definitions. + * Flash Routines for MOUSSE onboard AMD29LV106DB devices + * + * (C) Copyright 2000 + * Marius Groeger <mgroeger@sysgo.de> + * Sysgo Real-Time Solutions, GmbH <www.elinos.com> + * + * (C) Copyright 2000 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * (C) Copyright 1999, by Curt McDowell, 08-06-99, Broadcom Corp. + * (C) Copyright 2001, James Dougherty, 07/18/01, Broadcom Corp. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <mpc8xx.h> +#include <malloc.h> +#include "mousse.h" +#include "flash.h" + +int flashLibDebug = 0; +int flashLibInited = 0; + +#define OK 0 +#define ERROR -1 +#define STATUS int +#define PRINTF if (flashLibDebug) printf +#if 0 +#define PRIVATE static +#else +#define PRIVATE +#endif + +flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; + +#define SLEEP_DELAY 166 +#define FLASH_SECTOR_SIZE (64*1024) +/*********************************************************************** + * + * Virtual Flash Devices on Mousse board + * + * These must be kept in sync with the definitions in flashLib.h. + * + ***********************************************************************/ + +PRIVATE flash_dev_t flashDev[] = { + /* Bank 0 sector SA0 (16 kB) */ + { "SA0",FLASH0_BANK, FLASH0_SEG0_START, 1, 14, + FLASH0_VENDOR_ID, FLASH0_DEVICE_ID + }, + /* Bank 0 sector SA1 (8 kB) */ + { "SA1", FLASH0_BANK, FLASH0_SEG0_START + 0x4000, 1, 13, + FLASH0_VENDOR_ID, FLASH0_DEVICE_ID + }, + /* Bank 0 sector SA2 (8 kB) */ + { "SA2", FLASH0_BANK, FLASH0_SEG0_START + 0x6000, 1, 13, + FLASH0_VENDOR_ID, FLASH0_DEVICE_ID + }, + /* Bank 0 sector SA3 is occluded by Mousse I/O devices */ + /* Bank 0 sectors SA4-SA18, after Mousse devices up to PLCC (960 kB) */ + { "KERNEL", FLASH0_BANK, FLASH0_SEG1_START, 15, 16, + FLASH0_VENDOR_ID, FLASH0_DEVICE_ID + }, + /* Bank 0 sectors SA19-SA26, jumper can occlude this by PLCC (512 kB) */ + /* This is where the Kahlua boot vector and boot ROM code resides. */ + { "BOOT",FLASH0_BANK, FLASH0_SEG2_START, 8, 16, + FLASH0_VENDOR_ID, FLASH0_DEVICE_ID + }, + /* Bank 0 sectors SA27-SA34 (512 kB) */ + { "RAMDISK",FLASH0_BANK, FLASH0_SEG3_START, 8, 16, + FLASH0_VENDOR_ID, FLASH0_DEVICE_ID + }, +}; + +int flashDevCount = (sizeof (flashDev) / sizeof (flashDev[0])); + +#define DEV(no) (&flashDev[no]) +#define DEV_NO(dev) ((dev) - flashDev) + +/*********************************************************************** + * + * Private Flash Routines + * + ***********************************************************************/ + +/* + * The convention is: + * + * "addr" is always the PROM raw address, which is the address of an + * 8-bit quantity for flash 0 and 16-bit quantity for flash 1. + * + * "pos" is always a logical byte position from the PROM beginning. + */ + +#define FLASH0_ADDR(dev, addr) \ + ((unsigned char *) ((dev)->base + (addr))) + +#define FLASH0_WRITE(dev, addr, value) \ + (*FLASH0_ADDR(dev, addr) = (value)) + +#define FLASH0_READ(dev, addr) \ + (*FLASH0_ADDR(dev, addr)) + +PRIVATE int flashCheck (flash_dev_t * dev) +{ + if (!flashLibInited) { + printf ("flashCheck: flashLib not initialized\n"); + return ERROR; + } + + if (dev < &flashDev[0] || dev >= &flashDev[flashDevCount]) { + printf ("flashCheck: Bad dev parameter\n"); + return ERROR; + } + + if (!dev->found) { + printf ("flashCheck: Device %d not available\n", DEV_NO (dev)); + return ERROR; + } + + return OK; +} + +PRIVATE void flashReset (flash_dev_t * dev) +{ + PRINTF ("flashReset: dev=%d\n", DEV_NO (dev)); + + if (dev->bank == FLASH0_BANK) { + FLASH0_WRITE (dev, 0x555, 0xaa); + FLASH0_WRITE (dev, 0xaaa, 0x55); + FLASH0_WRITE (dev, 0x555, 0xf0); + } + + udelay (SLEEP_DELAY); + + PRINTF ("flashReset: done\n"); +} + +PRIVATE int flashProbe (flash_dev_t * dev) +{ + int rv, deviceID, vendorID; + + PRINTF ("flashProbe: dev=%d\n", DEV_NO (dev)); + + if (dev->bank != FLASH0_BANK) { + rv = ERROR; + goto DONE; + } + + FLASH0_WRITE (dev, 0xaaa, 0xaa); + FLASH0_WRITE (dev, 0x555, 0x55); + FLASH0_WRITE (dev, 0xaaa, 0x90); + + udelay (SLEEP_DELAY); + + vendorID = FLASH0_READ (dev, 0); + deviceID = FLASH0_READ (dev, 2); + + FLASH0_WRITE (dev, 0, 0xf0); + + PRINTF ("flashProbe: vendor=0x%x device=0x%x\n", vendorID, deviceID); + + if (vendorID == dev->vendorID && deviceID == dev->deviceID) + rv = OK; + else + rv = ERROR; + + DONE: + PRINTF ("flashProbe: rv=%d\n", rv); + + return rv; +} + +PRIVATE int flashWait (flash_dev_t * dev, int addr, int expect, int erase) +{ + int rv = ERROR; + int i, data; + int polls; + +#if 0 + PRINTF ("flashWait: dev=%d addr=0x%x expect=0x%x erase=%d\n", + DEV_NO (dev), addr, expect, erase); +#endif + + if (dev->bank != FLASH0_BANK) { + rv = ERROR; + goto done; + } + + if (erase) + polls = FLASH_ERASE_SECTOR_TIMEOUT; /* Ticks */ + else + polls = FLASH_PROGRAM_POLLS; /* Loops */ + + for (i = 0; i < polls; i++) { + if (erase) + udelay (SLEEP_DELAY); + + data = FLASH0_READ (dev, addr); + + if (((data ^ expect) & 0x80) == 0) { + rv = OK; + goto done; + } + + if (data & 0x20) { + /* + * If the 0x20 bit has come on, it could actually be because + * the operation succeeded, so check the done bit again. + */ + + data = FLASH0_READ (dev, addr); + + if (((data ^ expect) & 0x80) == 0) { + rv = OK; + goto done; + } + + printf ("flashWait: Program error (dev: %d, addr: 0x%x)\n", + DEV_NO (dev), addr); + + flashReset (dev); + rv = ERROR; + goto done; + } + } + + printf ("flashWait: Timeout %s (dev: %d, addr: 0x%x)\n", + erase ? "erasing sector" : "programming byte", + DEV_NO (dev), addr); + + done: + +#if 0 + PRINTF ("flashWait: rv=%d\n", rv); +#endif + + return rv; +} + +/*********************************************************************** + * + * Public Flash Routines + * + ***********************************************************************/ + +STATUS flashLibInit (void) +{ + int i; + + PRINTF ("flashLibInit: devices=%d\n", flashDevCount); + + for (i = 0; i < flashDevCount; i++) { + flash_dev_t *dev = &flashDev[i]; + + /* + * For bank 1, probe both without and with byte swappage, + * so that this module works on both old and new Mousse boards. + */ + + flashReset (dev); + + if (flashProbe (dev) != ERROR) + dev->found = 1; + + flashReset (dev); + + if (flashProbe (dev) != ERROR) + dev->found = 1; + + dev->swap = 0; + + if (dev->found) { + PRINTF ("\n FLASH %s[%d]: iobase=0x%x - %d sectors %d KB", + flashDev[i].name, i, flashDev[i].base, + flashDev[i].sectors, + (flashDev[i].sectors * FLASH_SECTOR_SIZE) / 1024); + + } + } + + flashLibInited = 1; + + PRINTF ("flashLibInit: done\n"); + + return OK; +} + +STATUS flashEraseSector (flash_dev_t * dev, int sector) +{ + int pos, addr; + + PRINTF ("flashErasesector: dev=%d sector=%d\n", DEV_NO (dev), sector); + + if (flashCheck (dev) == ERROR) + return ERROR; + + if (sector < 0 || sector >= dev->sectors) { + printf ("flashEraseSector: Sector out of range (dev: %d, sector: %d)\n", DEV_NO (dev), sector); + return ERROR; + } + + pos = FLASH_SECTOR_POS (dev, sector); + + if (dev->bank != FLASH0_BANK) { + return ERROR; + } + + addr = pos; + + FLASH0_WRITE (dev, 0xaaa, 0xaa); + FLASH0_WRITE (dev, 0x555, 0x55); + FLASH0_WRITE (dev, 0xaaa, 0x80); + FLASH0_WRITE (dev, 0xaaa, 0xaa); + FLASH0_WRITE (dev, 0x555, 0x55); + FLASH0_WRITE (dev, addr, 0x30); + + return flashWait (dev, addr, 0xff, 1); +} + +/* + * Note: it takes about as long to flash all sectors together with Chip + * Erase as it does to flash them one at a time (about 30 seconds for 2 + * MB). Also since we want to be able to treat subsets of sectors as if + * they were complete devices, we don't use Chip Erase. + */ + +STATUS flashErase (flash_dev_t * dev) +{ + int sector; + + PRINTF ("flashErase: dev=%d sectors=%d\n", DEV_NO (dev), dev->sectors); + + if (flashCheck (dev) == ERROR) + return ERROR; + + for (sector = 0; sector < dev->sectors; sector++) { + if (flashEraseSector (dev, sector) == ERROR) + return ERROR; + } + return OK; +} + +/* + * Read and write bytes + */ + +STATUS flashRead (flash_dev_t * dev, int pos, char *buf, int len) +{ + int addr, words; + + PRINTF ("flashRead: dev=%d pos=0x%x buf=0x%x len=0x%x\n", + DEV_NO (dev), pos, (int) buf, len); + + if (flashCheck (dev) == ERROR) + return ERROR; + + if (pos < 0 || len < 0 || pos + len > FLASH_MAX_POS (dev)) { + printf ("flashRead: Position out of range " + "(dev: %d, pos: 0x%x, len: 0x%x)\n", + DEV_NO (dev), pos, len); + return ERROR; + } + + if (len == 0) + return OK; + + if (dev->bank == FLASH0_BANK) { + addr = pos; + words = len; + + PRINTF ("flashRead: memcpy(0x%x, 0x%x, 0x%x)\n", + (int) buf, (int) FLASH0_ADDR (dev, pos), len); + + memcpy (buf, FLASH0_ADDR (dev, addr), words); + + } + PRINTF ("flashRead: rv=OK\n"); + + return OK; +} + +STATUS flashWrite (flash_dev_t * dev, int pos, char *buf, int len) +{ + int addr, words; + + PRINTF ("flashWrite: dev=%d pos=0x%x buf=0x%x len=0x%x\n", + DEV_NO (dev), pos, (int) buf, len); + + if (flashCheck (dev) == ERROR) + return ERROR; + + if (pos < 0 || len < 0 || pos + len > FLASH_MAX_POS (dev)) { + printf ("flashWrite: Position out of range " + "(dev: %d, pos: 0x%x, len: 0x%x)\n", + DEV_NO (dev), pos, len); + return ERROR; + } + + if (len == 0) + return OK; + + if (dev->bank == FLASH0_BANK) { + unsigned char tmp; + + addr = pos; + words = len; + + while (words--) { + tmp = *buf; + if (~FLASH0_READ (dev, addr) & tmp) { + printf ("flashWrite: Attempt to program 0 to 1 " + "(dev: %d, addr: 0x%x, data: 0x%x)\n", + DEV_NO (dev), addr, tmp); + return ERROR; + } + FLASH0_WRITE (dev, 0xaaa, 0xaa); + FLASH0_WRITE (dev, 0x555, 0x55); + FLASH0_WRITE (dev, 0xaaa, 0xa0); + FLASH0_WRITE (dev, addr, tmp); + if (flashWait (dev, addr, tmp, 0) < 0) + return ERROR; + buf++; + addr++; + } + } + + PRINTF ("flashWrite: rv=OK\n"); + + return OK; +} + +/* + * flashWritable returns TRUE if a range contains all F's. + */ + +STATUS flashWritable (flash_dev_t * dev, int pos, int len) +{ + int addr, words; + int rv = ERROR; + + PRINTF ("flashWritable: dev=%d pos=0x%x len=0x%x\n", + DEV_NO (dev), pos, len); + + if (flashCheck (dev) == ERROR) + goto done; + + if (pos < 0 || len < 0 || pos + len > FLASH_MAX_POS (dev)) { + printf ("flashWritable: Position out of range " + "(dev: %d, pos: 0x%x, len: 0x%x)\n", + DEV_NO (dev), pos, len); + goto done; + } + + if (len == 0) { + rv = 1; + goto done; + } + + if (dev->bank == FLASH0_BANK) { + addr = pos; + words = len; + + while (words--) { + if (FLASH0_READ (dev, addr) != 0xff) { + rv = 0; + goto done; + } + addr++; + } + } + + rv = 1; + + done: + PRINTF ("flashWrite: rv=%d\n", rv); + return rv; +} + + +/* + * NOTE: the below code cannot run from FLASH!!! + */ +/*********************************************************************** + * + * Flash Diagnostics + * + ***********************************************************************/ + +STATUS flashDiag (flash_dev_t * dev) +{ + unsigned int *buf = 0; + int i, len, sector; + int rv = ERROR; + + if (flashCheck (dev) == ERROR) + return ERROR; + + printf ("flashDiag: Testing device %d, " + "base: 0x%x, %d sectors @ %d kB = %d kB\n", + DEV_NO (dev), dev->base, + dev->sectors, + 1 << (dev->lgSectorSize - 10), + dev->sectors << (dev->lgSectorSize - 10)); + + len = 1 << dev->lgSectorSize; + + printf ("flashDiag: Erasing\n"); + + if (flashErase (dev) == ERROR) { + printf ("flashDiag: Erase failed\n"); + goto done; + } + printf ("%d bytes requested ...\n", len); + buf = malloc (len); + printf ("allocated %d bytes ...\n", len); + if (buf == 0) { + printf ("flashDiag: Out of memory\n"); + goto done; + } + + /* + * Write unique counting pattern to each sector + */ + + for (sector = 0; sector < dev->sectors; sector++) { + printf ("flashDiag: Write sector %d\n", sector); + + for (i = 0; i < len / 4; i++) + buf[i] = sector << 24 | i; + + if (flashWrite (dev, + sector << dev->lgSectorSize, + (char *) buf, len) == ERROR) { + printf ("flashDiag: Write failed (dev: %d, sector: %d)\n", + DEV_NO (dev), sector); + goto done; + } + } + + /* + * Verify + */ + + for (sector = 0; sector < dev->sectors; sector++) { + printf ("flashDiag: Verify sector %d\n", sector); + + if (flashRead (dev, + sector << dev->lgSectorSize, + (char *) buf, len) == ERROR) { + printf ("flashDiag: Read failed (dev: %d, sector: %d)\n", + DEV_NO (dev), sector); + goto done; + } + + for (i = 0; i < len / 4; i++) { + if (buf[i] != (sector << 24 | i)) { + printf ("flashDiag: Verify error " + "(dev: %d, sector: %d, offset: 0x%x)\n", + DEV_NO (dev), sector, i); + printf ("flashDiag: Expected 0x%08x, got 0x%08x\n", + sector << 24 | i, buf[i]); + + goto done; + } + } + } + + printf ("flashDiag: Erasing\n"); + + if (flashErase (dev) == ERROR) { + printf ("flashDiag: Final erase failed\n"); + goto done; + } + + rv = OK; + + done: + if (buf) + free (buf); + + if (rv == OK) + printf ("flashDiag: Device %d passed\n", DEV_NO (dev)); + else + printf ("flashDiag: Device %d failed\n", DEV_NO (dev)); + + return rv; +} + +STATUS flashDiagAll (void) +{ + int i; + int rv = OK; + + PRINTF ("flashDiagAll: devices=%d\n", flashDevCount); + + for (i = 0; i < flashDevCount; i++) { + flash_dev_t *dev = &flashDev[i]; + + if (dev->found && flashDiag (dev) == ERROR) + rv = ERROR; + } + + if (rv == OK) + printf ("flashDiagAll: Passed\n"); + else + printf ("flashDiagAll: Failed because of earlier errors\n"); + + return OK; +} + + +/*----------------------------------------------------------------------- + */ +unsigned long flash_init (void) +{ + unsigned long size = 0; + flash_dev_t *dev = NULL; + + flashLibInit (); + + /* + * Provide info for FLASH (up to 960K) of Kernel Image data. + */ + dev = FLASH_DEV_BANK0_LOW; + flash_info[FLASH_BANK_KERNEL].flash_id = + (dev->vendorID << 16) | dev->deviceID; + flash_info[FLASH_BANK_KERNEL].sector_count = dev->sectors; + flash_info[FLASH_BANK_KERNEL].size = + flash_info[FLASH_BANK_KERNEL].sector_count * FLASH_SECTOR_SIZE; + flash_info[FLASH_BANK_KERNEL].start[FIRST_SECTOR] = dev->base; + size += flash_info[FLASH_BANK_KERNEL].size; + + /* + * Provide info for 512K PLCC FLASH ROM (U-Boot) + */ + dev = FLASH_DEV_BANK0_BOOT; + flash_info[FLASH_BANK_BOOT].flash_id = + (dev->vendorID << 16) | dev->deviceID; + flash_info[FLASH_BANK_BOOT].sector_count = dev->sectors; + flash_info[FLASH_BANK_BOOT].size = + flash_info[FLASH_BANK_BOOT].sector_count * FLASH_SECTOR_SIZE; + flash_info[FLASH_BANK_BOOT].start[FIRST_SECTOR] = dev->base; + size += flash_info[FLASH_BANK_BOOT].size; + + + /* + * Provide info for 512K FLASH0 segment (U-Boot) + */ + dev = FLASH_DEV_BANK0_HIGH; + flash_info[FLASH_BANK_AUX].flash_id = + (dev->vendorID << 16) | dev->deviceID; + flash_info[FLASH_BANK_AUX].sector_count = dev->sectors; + flash_info[FLASH_BANK_AUX].size = + flash_info[FLASH_BANK_AUX].sector_count * FLASH_SECTOR_SIZE; + flash_info[FLASH_BANK_AUX].start[FIRST_SECTOR] = dev->base; + size += flash_info[FLASH_BANK_AUX].size; + + + return size; +} + +/* + * Get flash device from U-Boot flash info. + */ +flash_dev_t *getFlashDevFromInfo (flash_info_t * info) +{ + int i; + + if (!info) + return NULL; + + for (i = 0; i < flashDevCount; i++) { + flash_dev_t *dev = &flashDev[i]; + + if (dev->found && (dev->base == info->start[0])) + return dev; + } + printf ("ERROR: notice, no FLASH mapped at address 0x%x\n", + (unsigned int) info->start[0]); + return NULL; +} + +ulong flash_get_size (vu_long * addr, flash_info_t * info) +{ + int i; + + for (i = 0; i < flashDevCount; i++) { + flash_dev_t *dev = &flashDev[i]; + + if (dev->found) { + if (dev->base == (unsigned int) addr) { + info->flash_id = (dev->vendorID << 16) | dev->deviceID; + info->sector_count = dev->sectors; + info->size = info->sector_count * FLASH_SECTOR_SIZE; + return dev->sectors * FLASH_SECTOR_SIZE; + } + } + } + return 0; +} + +void flash_print_info (flash_info_t * info) +{ + int i; + unsigned int chip; + + if (info->flash_id == FLASH_UNKNOWN) { + printf ("missing or unknown FLASH type\n"); + return; + } + + switch ((info->flash_id >> 16) & 0xff) { + case 0x1: + printf ("AMD "); + break; + default: + printf ("Unknown Vendor "); + break; + } + chip = (unsigned int) info->flash_id & 0x000000ff; + + switch (chip) { + + case AMD_ID_F040B: + printf ("AM29F040B (4 Mbit)\n"); + break; + + case AMD_ID_LV160B: + case FLASH_AM160LV: + case 0x49: + printf ("AM29LV160B (16 Mbit / 2M x 8bit)\n"); + break; + + default: + printf ("Unknown Chip Type:0x%x\n", chip); + break; + } + + printf (" Size: %ld bytes in %d Sectors\n", + info->size, 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[FIRST_SECTOR] + i * FLASH_SECTOR_SIZE, + info->protect[i] ? " (RO)" : " "); + } + printf ("\n"); +} + + +/* + * Erase a range of flash sectors. + */ +int flash_erase (flash_info_t * info, int s_first, int s_last) +{ + vu_long *addr = (vu_long *) (info->start[0]); + int prot, sect, l_sect; + flash_dev_t *dev = NULL; + + if ((s_first < 0) || (s_first > s_last)) { + if (info->flash_id == FLASH_UNKNOWN) { + printf ("- missing\n"); + } else { + printf ("- no sectors to erase\n"); + } + return 1; + } + + prot = 0; + for (sect = s_first; sect <= s_last; sect++) { + if (info->protect[sect]) { + prot++; + } + } + + if (prot) { + printf ("- Warning: %d protected sectors will not be erased!\n", + prot); + } else { + printf ("\n"); + } + + l_sect = -1; + + /* Start erase on unprotected sectors */ + dev = getFlashDevFromInfo (info); + if (dev) { + printf ("Erase FLASH[%s] -%d sectors:", dev->name, dev->sectors); + for (sect = s_first; sect <= s_last; sect++) { + if (info->protect[sect] == 0) { /* not protected */ + addr = (vu_long *) (dev->base); + /* printf("erase_sector: sector=%d, addr=0x%x\n", + sect, addr); */ + printf ("."); + if (ERROR == flashEraseSector (dev, sect)) { + printf ("ERROR: could not erase sector %d on FLASH[%s]\n", sect, dev->name); + return 1; + } + } + } + } + printf (" done\n"); + return 0; +} + +/*----------------------------------------------------------------------- + * 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) +{ + + flash_dev_t *dev = getFlashDevFromInfo (info); + int addr = dest - info->start[0]; + + if (!dev) + return 1; + + if (OK != flashWrite (dev, addr, (char *) &data, sizeof (ulong))) { + printf ("ERROR: could not write to addr=0x%x, data=0x%x\n", + (unsigned int) addr, (unsigned) data); + return 1; + } + + if ((addr % FLASH_SECTOR_SIZE) == 0) + printf ("."); + + + PRINTF ("write_word:0x%x, base=0x%x, addr=0x%x, data=0x%x\n", + (unsigned) info->start[0], + (unsigned) dest, + (unsigned) (dest - info->start[0]), (unsigned) data); + + return (0); +} + + +/*----------------------------------------------------------------------- + * Copy memory to flash, returns: + * 0 - OK + * 1 - write timeout + * 2 - Flash not erased + */ + +int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt) +{ + ulong cp, wp, data; + int i, l, rc; + flash_dev_t *dev = getFlashDevFromInfo (info); + + if (dev) { + printf ("FLASH[%s]:", dev->name); + wp = (addr & ~3); /* get lower word aligned address */ + + /* + * handle unaligned start bytes + */ + if ((l = addr - wp) != 0) { + data = 0; + for (i = 0, cp = wp; i < l; ++i, ++cp) { + data = (data << 8) | (*(uchar *) cp); + } + for (; i < 4 && cnt > 0; ++i) { + data = (data << 8) | *src++; + --cnt; + ++cp; + } + for (; cnt == 0 && i < 4; ++i, ++cp) { + data = (data << 8) | (*(uchar *) cp); + } + if ((rc = write_word (info, wp, data)) != 0) { + return (rc); + } + wp += 4; + } + + /* + * handle word aligned part + */ + while (cnt >= 4) { + data = 0; + for (i = 0; i < 4; ++i) { + data = (data << 8) | *src++; + } + if ((rc = write_word (info, wp, data)) != 0) { + return (rc); + } + wp += 4; + cnt -= 4; + } + + if (cnt == 0) { + return (0); + } + + /* + * handle unaligned tail bytes + */ + data = 0; + for (i = 0, cp = wp; i < 4 && cnt > 0; ++i, ++cp) { + data = (data << 8) | *src++; + --cnt; + } + for (; i < 4; ++i, ++cp) { + data = (data << 8) | (*(uchar *) cp); + } + + return (write_word (info, wp, data)); + } + return 1; +} + +/*----------------------------------------------------------------------- + */ diff --git a/board/mousse/flash.h b/board/mousse/flash.h new file mode 100755 index 0000000..b7e4619 --- /dev/null +++ b/board/mousse/flash.h @@ -0,0 +1,78 @@ +#ifndef FLASH_LIB_H +#define FLASH_LIB_H + +#include <common.h> + +/* PIO operations max */ +#define FLASH_PROGRAM_POLLS 100000 + +/* 10 Seconds default */ +#define FLASH_ERASE_SECTOR_TIMEOUT (10*1000 /*SEC*/ ) + +/* Flash device info structure */ +typedef struct flash_dev_s { + char name[24]; /* Bank Name */ + int bank; /* Bank 0 or 1 */ + unsigned int base; /* Base address */ + int sectors; /* Sector count */ + int lgSectorSize; /* Log2(usable bytes/sector) */ + int vendorID; /* Expected vendor ID */ + int deviceID; /* Expected device ID */ + int found; /* Set if found by flashLibInit */ + int swap; /* Set for bank 1 if byte swap req'd */ +} flash_dev_t; + +#define FLASH_MAX_POS(dev) \ + ((dev)->sectors << (dev)->lgSectorSize) + +#define FLASH_SECTOR_POS(dev, sector) \ + ((sector) << (dev)->lgSectorSize) + +/* AMD 29F040 */ +#define FLASH0_BANK 0 +#define FLASH0_VENDOR_ID 0x01 +#define FLASH0_DEVICE_ID 0x49 + +/* AMD29LV160DB */ +#define FLASH1_BANK 1 +#define FLASH1_VENDOR_ID 0x0001 +#define FLASH1_DEVICE_ID 0x2249 + +extern flash_dev_t flashDev[]; +extern int flashDevCount; + +/* + * Device pointers + * + * These must be kept in sync with the table in flashLib.c. + */ +#define FLASH_DEV_BANK0_SA0 (&flashDev[0]) +#define FLASH_DEV_BANK0_SA1 (&flashDev[1]) +#define FLASH_DEV_BANK0_SA2 (&flashDev[2]) +#define FLASH_DEV_BANK0_LOW (&flashDev[3]) /* 960K */ +#define FLASH_DEV_BANK0_BOOT (&flashDev[4]) /* PLCC */ +#define FLASH_DEV_BANK0_HIGH (&flashDev[5]) /* 512K PLCC shadow */ + +unsigned long flash_init(void); +int flashEraseSector(flash_dev_t *dev, int sector); +int flashErase(flash_dev_t *dev); +int flashRead(flash_dev_t *dev, int pos, char *buf, int len); +int flashWrite(flash_dev_t *dev, int pos, char *buf, int len); +int flashWritable(flash_dev_t *dev, int pos, int len); +int flashDiag(flash_dev_t *dev); +int flashDiagAll(void); + +ulong flash_get_size (vu_long *addr, flash_info_t *info); +void flash_print_info (flash_info_t *info); +int flash_erase (flash_info_t *info, int s_first, int s_last); +int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt); + +/* + * Flash info indices. + */ +#define FLASH_BANK_KERNEL 0 +#define FLASH_BANK_BOOT 1 +#define FLASH_BANK_AUX 2 +#define FIRST_SECTOR 0 + +#endif /* !FLASH_LIB_H */ diff --git a/board/mousse/m48t59y.c b/board/mousse/m48t59y.c new file mode 100755 index 0000000..37a6244 --- /dev/null +++ b/board/mousse/m48t59y.c @@ -0,0 +1,322 @@ +/* + * SGS M48-T59Y TOD/NVRAM Driver + * + * (C) Copyright 2000 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * (C) Copyright 1999, by Curt McDowell, 08-06-99, Broadcom Corp. + * + * (C) Copyright 2001, James Dougherty, 07/18/01, Broadcom Corp. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +/* + * SGS M48-T59Y TOD/NVRAM Driver + * + * The SGS M48 an 8K NVRAM starting at offset M48_BASE_ADDR and + * continuing for 8176 bytes. After that starts the Time-Of-Day (TOD) + * registers which are used to set/get the internal date/time functions. + * + * This module implements Y2K compliance by taking full year numbers + * and translating back and forth from the TOD 2-digit year. + * + * NOTE: for proper interaction with an operating system, the TOD should + * be used to store Universal Coordinated Time (GMT) and timezone + * conversions should be used. + * + * Here is a diagram of the memory layout: + * + * +---------------------------------------------+ 0xffe0a000 + * | Non-volatile memory | . + * | | . + * | (8176 bytes of Non-volatile memory) | . + * | | . + * +---------------------------------------------+ 0xffe0bff0 + * | Flags | + * +---------------------------------------------+ 0xffe0bff1 + * | Unused | + * +---------------------------------------------+ 0xffe0bff2 + * | Alarm Seconds | + * +---------------------------------------------+ 0xffe0bff3 + * | Alarm Minutes | + * +---------------------------------------------+ 0xffe0bff4 + * | Alarm Date | + * +---------------------------------------------+ 0xffe0bff5 + * | Interrupts | + * +---------------------------------------------+ 0xffe0bff6 + * | WatchDog | + * +---------------------------------------------+ 0xffe0bff7 + * | Calibration | + * +---------------------------------------------+ 0xffe0bff8 + * | Seconds | + * +---------------------------------------------+ 0xffe0bff9 + * | Minutes | + * +---------------------------------------------+ 0xffe0bffa + * | Hours | + * +---------------------------------------------+ 0xffe0bffb + * | Day | + * +---------------------------------------------+ 0xffe0bffc + * | Date | + * +---------------------------------------------+ 0xffe0bffd + * | Month | + * +---------------------------------------------+ 0xffe0bffe + * | Year (2 digits only) | + * +---------------------------------------------+ 0xffe0bfff + */ +#include <common.h> +#include <rtc.h> +#include "mousse.h" + +/* + * Imported from mousse.h: + * + * TOD_REG_BASE Base of m48t59y TOD registers + * SYS_TOD_UNPROTECT() Disable NVRAM write protect + * SYS_TOD_PROTECT() Re-enable NVRAM write protect + */ + +#define YEAR 0xf +#define MONTH 0xe +#define DAY 0xd +#define DAY_OF_WEEK 0xc +#define HOUR 0xb +#define MINUTE 0xa +#define SECOND 0x9 +#define CONTROL 0x8 +#define WATCH 0x7 +#define INTCTL 0x6 +#define WD_DATE 0x5 +#define WD_HOUR 0x4 +#define WD_MIN 0x3 +#define WD_SEC 0x2 +#define _UNUSED 0x1 +#define FLAGS 0x0 + +#define M48_ADDR ((volatile unsigned char *) TOD_REG_BASE) + +int m48_tod_init(void) +{ + SYS_TOD_UNPROTECT(); + + M48_ADDR[CONTROL] = 0; + M48_ADDR[WATCH] = 0; + M48_ADDR[INTCTL] = 0; + + /* + * If the oscillator is currently stopped (as on a new part shipped + * from the factory), start it running. + * + * Here is an example of the TOD bytes on a brand new M48T59Y part: + * 00 00 00 00 00 00 00 00 00 88 8c c3 bf c8 f5 01 + */ + + if (M48_ADDR[SECOND] & 0x80) + M48_ADDR[SECOND] = 0; + + /* Is battery low */ + if ( M48_ADDR[FLAGS] & 0x10) { + printf("NOTICE: Battery low on Real-Time Clock (replace SNAPHAT).\n"); + } + + SYS_TOD_PROTECT(); + + return 0; +} + +/* + * m48_tod_set + */ + +static int to_bcd(int value) +{ + return value / 10 * 16 + value % 10; +} + +static int from_bcd(int value) +{ + return value / 16 * 10 + value % 16; +} + +static int day_of_week(int y, int m, int d) /* 0-6 ==> Sun-Sat */ +{ + static int t[] = {0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4}; + y -= m < 3; + return (y + y/4 - y/100 + y/400 + t[m-1] + d) % 7; +} + +/* + * Note: the TOD should store the current GMT + */ + +int m48_tod_set(int year, /* 1980-2079 */ + int month, /* 01-12 */ + int day, /* 01-31 */ + int hour, /* 00-23 */ + int minute, /* 00-59 */ + int second) /* 00-59 */ + +{ + SYS_TOD_UNPROTECT(); + + M48_ADDR[CONTROL] |= 0x80; /* Set WRITE bit */ + + M48_ADDR[YEAR] = to_bcd(year % 100); + M48_ADDR[MONTH] = to_bcd(month); + M48_ADDR[DAY] = to_bcd(day); + M48_ADDR[DAY_OF_WEEK] = day_of_week(year, month, day) + 1; + M48_ADDR[HOUR] = to_bcd(hour); + M48_ADDR[MINUTE] = to_bcd(minute); + M48_ADDR[SECOND] = to_bcd(second); + + M48_ADDR[CONTROL] &= ~0x80; /* Clear WRITE bit */ + + SYS_TOD_PROTECT(); + + return 0; +} + +/* + * Note: the TOD should store the current GMT + */ + +int m48_tod_get(int *year, /* 1980-2079 */ + int *month, /* 01-12 */ + int *day, /* 01-31 */ + int *hour, /* 00-23 */ + int *minute, /* 00-59 */ + int *second) /* 00-59 */ +{ + int y; + + SYS_TOD_UNPROTECT(); + + M48_ADDR[CONTROL] |= 0x40; /* Set READ bit */ + + y = from_bcd(M48_ADDR[YEAR]); + *year = y < 80 ? 2000 + y : 1900 + y; + *month = from_bcd(M48_ADDR[MONTH]); + *day = from_bcd(M48_ADDR[DAY]); + /* day_of_week = M48_ADDR[DAY_OF_WEEK] & 0xf; */ + *hour = from_bcd(M48_ADDR[HOUR]); + *minute = from_bcd(M48_ADDR[MINUTE]); + *second = from_bcd(M48_ADDR[SECOND] & 0x7f); + + M48_ADDR[CONTROL] &= ~0x40; /* Clear READ bit */ + + SYS_TOD_PROTECT(); + + return 0; +} + +int m48_tod_get_second(void) +{ + return from_bcd(M48_ADDR[SECOND] & 0x7f); +} + +/* + * Watchdog function + * + * If usec is 0, the watchdog timer is disarmed. + * + * If usec is non-zero, the watchdog timer is armed (or re-armed) for + * approximately usec microseconds (if the exact requested usec is + * not supported by the chip, the next higher available value is used). + * + * Minimum watchdog timeout = 62500 usec + * Maximum watchdog timeout = 124 sec (124000000 usec) + */ + +void m48_watchdog_arm(int usec) +{ + int mpy, res; + + SYS_TOD_UNPROTECT(); + + if (usec == 0) { + res = 0; + mpy = 0; + } else if (usec < 2000000) { /* Resolution: 1/16s if below 2s */ + res = 0; + mpy = (usec + 62499) / 62500; + } else if (usec < 8000000) { /* Resolution: 1/4s if below 8s */ + res = 1; + mpy = (usec + 249999) / 250000; + } else if (usec < 32000000) { /* Resolution: 1s if below 32s */ + res = 2; + mpy = (usec + 999999) / 1000000; + } else { /* Resolution: 4s up to 124s */ + res = 3; + mpy = (usec + 3999999) / 4000000; + if (mpy > 31) + mpy = 31; + } + + M48_ADDR[WATCH] = (0x80 | /* Steer to RST signal (IRQ = N/C) */ + mpy << 2 | + res); + + SYS_TOD_PROTECT(); +} + +/* + * U-Boot RTC support. + */ +void +rtc_get( struct rtc_time *tmp ) +{ + m48_tod_get(&tmp->tm_year, + &tmp->tm_mon, + &tmp->tm_mday, + &tmp->tm_hour, + &tmp->tm_min, + &tmp->tm_sec); + tmp->tm_yday = 0; + tmp->tm_isdst= 0; + +#ifdef RTC_DEBUG + printf( "Get DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n", + tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday, + tmp->tm_hour, tmp->tm_min, tmp->tm_sec ); +#endif +} + +void +rtc_set( struct rtc_time *tmp ) +{ + m48_tod_set(tmp->tm_year, /* 1980-2079 */ + tmp->tm_mon, /* 01-12 */ + tmp->tm_mday, /* 01-31 */ + tmp->tm_hour, /* 00-23 */ + tmp->tm_min, /* 00-59 */ + tmp->tm_sec); /* 00-59 */ + +#ifdef RTC_DEBUG + printf( "Set DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n", + tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday, + tmp->tm_hour, tmp->tm_min, tmp->tm_sec); +#endif + +} + +void +rtc_reset (void) +{ + m48_tod_init(); +} diff --git a/board/mousse/m48t59y.h b/board/mousse/m48t59y.h new file mode 100755 index 0000000..717300d --- /dev/null +++ b/board/mousse/m48t59y.h @@ -0,0 +1,57 @@ +/* + * SGS M48-T59Y TOD/NVRAM Driver + * + * (C) Copyright 2000 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * (C) Copyright 1999, by Curt McDowell, 08-06-99, Broadcom Corp. + * + * (C) Copyright 2001, James Dougherty, 07/18/01, Broadcom Corp. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public 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 __M48_T59_Y_H +#define __M48_T59_Y_H + +/* + * M48 T59Y -Timekeeping Battery backed SRAM. + */ + +int m48_tod_init(void); + +int m48_tod_set(int year, + int month, + int day, + int hour, + int minute, + int second); + +int m48_tod_get(int *year, + int *month, + int *day, + int *hour, + int *minute, + int *second); + +int m48_tod_get_second(void); + +void m48_watchdog_arm(int usec); + +#endif /*!__M48_T59_Y_H */ diff --git a/board/mousse/mousse.c b/board/mousse/mousse.c new file mode 100755 index 0000000..7208a17 --- /dev/null +++ b/board/mousse/mousse.c @@ -0,0 +1,86 @@ +/* + * MOUSSE Board Support + * + * (C) Copyright 2000 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * (C) Copyright 2001 + * James Dougherty, jfd@cs.stanford.edu + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <mpc824x.h> +#include <asm/processor.h> + +#include "mousse.h" +#include "m48t59y.h" +#include <pci.h> + + +int checkboard (void) +{ + ulong busfreq = get_bus_freq (0); + char buf[32]; + + puts ("Board: MOUSSE MPC8240/KAHLUA - CHRP (MAP B)\n"); + printf ("Built: %s at %s\n", __DATE__, __TIME__); + printf ("MPLD: Revision %d\n", SYS_REVID_GET ()); + printf ("Local Bus: %s MHz\n", strmhz (buf, busfreq)); + + return 0; +} + +int checkflash (void) +{ + printf ("checkflash\n"); + flash_init (); + return 0; +} + +long int initdram (int board_type) +{ + return CFG_RAM_SIZE; +} + + +void get_tod (void) +{ + int year, month, day, hour, minute, second; + + m48_tod_get (&year, &month, &day, &hour, &minute, &second); + + printf (" Current date/time: %d/%d/%d %d:%d:%d \n", + month, day, year, hour, minute, second); + +} + +/* + * EPIC, PCI, and I/O devices. + * Initialize Mousse Platform, probe for PCI devices, + * Query configuration parameters if not set. + */ +int misc_init_f (void) +{ + m48_tod_init (); /* Init SGS M48T59Y TOD/NVRAM */ + printf ("RTC: M48T589 TOD/NVRAM (%d) bytes\n", TOD_NVRAM_SIZE); + get_tod (); + return 0; +} diff --git a/board/mousse/mousse.h b/board/mousse/mousse.h new file mode 100755 index 0000000..5468314 --- /dev/null +++ b/board/mousse/mousse.h @@ -0,0 +1,259 @@ +/* + * MOUSSE/MPC8240 Board definitions. + * For more info, see http://www.vooha.com/ + * + * (C) Copyright 2000 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * (C) Copyright 2001 + * James Dougherty (jfd@cs.stanford.edu) + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef __MOUSSE_H +#define __MOUSSE_H + +/* System addresses */ + +#define PCI_SPECIAL_BASE 0xfe000000 +#define PCI_SPECIAL_SIZE 0x01000000 + +/* PORTX Device Addresses for Mousse */ + +#define PORTX_DEV_BASE 0xff000000 +#define PORTX_DEV_SIZE 0x01000000 + +#define ENET_DEV_BASE 0x80000000 + +#define PLD_REG_BASE (PORTX_DEV_BASE | 0xe09000) +#define PLD_REG(off) (*(volatile unsigned char *) \ + (PLD_REG_BASE + (off))) + +#define PLD_REVID_B1 0x7f +#define PLD_REVID_B2 0x01 + +/* MPLD */ +#define SYS_HARD_RESET() { for (;;) PLD_REG(0) = 0; } /* clr 0x80 bit */ +#define SYS_REVID_GET() ((int) PLD_REG(0) & 0x7f) +#define SYS_LED_OFF() (PLD_REG(1) |= 0x80) +#define SYS_LED_ON() (PLD_REG(1) &= ~0x80) +#define SYS_WATCHDOG_IRQ3() (PLD_REG(2) |= 0x80) +#define SYS_WATCHDOG_RESET() (PLD_REG(2) &= ~0x80) +#define SYS_TOD_PROTECT() (PLD_REG(3) |= 0x80) +#define SYS_TOD_UNPROTECT() (PLD_REG(3) &= ~0x80) + +/* SGS M48T59Y */ +#define TOD_BASE (PORTX_DEV_BASE | 0xe0a000) +#define TOD_REG_BASE (TOD_BASE | 0x1ff0) +#define TOD_NVRAM_BASE TOD_BASE +#define TOD_NVRAM_SIZE 0x1ff0 +#define TOD_NVRAM_LIMIT (TOD_NVRAM_BASE + TOD_NVRAM_SIZE) + +/* NS16552 SIO */ +#define SERIAL_BASE(_x) (PORTX_DEV_BASE | 0xe08000 | ((_x) ? 0 : 0x80)) +#define N_SIO_CHANNELS 2 +#define N_COM_PORTS N_SIO_CHANNELS + +/* + * On-board Dec21143 PCI Ethernet + * Note: The PCI MBAR chosen here was used from MPC8240UM which states + * that PCI memory is at: 0x80000 - 0xFDFFFFFF, if AMBOR[CPU_FD_ALIAS] + * is set, then PCI memory maps 1-1 with this address range in the + * correct byte order. + */ +#define PCI_ENET_IOADDR 0x80000000 +#define PCI_ENET_MEMADDR 0x80000000 + +/* + * Flash Memory Layout + * + * 2 MB Flash Bank 0 runs in 8-bit mode. In Flash Bank 0, the 32 kB + * sector SA3 is obscured by the 32 kB serial/TOD access space, and + * the 64 kB sectors SA19-SA26 are obscured by the 512 kB PLCC + * containing the fixed boot ROM. (If the 512 kB PLCC is + * deconfigured by jumper, this window to Flash Bank 0 becomes + * visible, but it still contains the fixed boot code and should be + * considered read-only). Flash Bank 0 sectors SA0 (16 kB), SA1 (8 + * kB), and SA2 (8 kB) are currently unused. + * + * 2 MB Flash Bank 1 runs in 16-bit mode. Flash Bank 1 is fully + * usable, but it's a 16-bit wide device on a 64-bit bus. Therefore + * 16-bit words only exist at addresses that are multiples of 8. All + * PROM data and control addresses must be multiplied by 8. + * + * See flashMap.c for description of flash filesystem layout. + */ + +/* + * FLASH memory address space: 8-bit wide FLASH memory spaces. + */ +#define FLASH0_SEG0_START 0xffe00000 /* Baby 32Kb segment */ +#define FLASH0_SEG0_END 0xffe07fff /* 16 kB + 8 kB + 8 kB */ +#define FLASH0_SEG0_SIZE 0x00008000 /* (sectors SA0-SA2) */ + +#define FLASH0_SEG1_START 0xffe10000 /* 1MB - 64Kb FLASH0 seg */ +#define FLASH0_SEG1_END 0xffefffff /* 960 kB */ +#define FLASH0_SEG1_SIZE 0x000f0000 + +#define FLASH0_SEG2_START 0xfff00000 /* Boot Loader stored here */ +#define FLASH0_SEG2_END 0xfff7ffff /* 512 kB FLASH0/PLCC seg */ +#define FLASH0_SEG2_SIZE 0x00080000 + +#define FLASH0_SEG3_START 0xfff80000 /* 512 kB FLASH0 seg */ +#define FLASH0_SEG3_END 0xffffffff +#define FLASH0_SEG3_SIZE 0x00080000 + +/* Where Kahlua starts */ +#define FLASH_RESET_VECT 0xfff00100 + +/* + * CHRP / PREP (MAP A/B) definitions. + */ + +#define PREP_REG_ADDR 0x80000cf8 /* MPC107 Config, Map A */ +#define PREP_REG_DATA 0x80000cfc /* MPC107 Config, Map A */ +/* MPC107 (MPC8240 internal EUMBBAR mapped) */ +#define CHRP_REG_ADDR 0xfec00000 /* MPC106 Config, Map B */ +#define CHRP_REG_DATA 0xfee00000 /* MPC106 Config, Map B */ + +/* + * Mousse PCI IDSEL Assignments (Device Number) + */ +#define MOUSSE_IDSEL_ENET 13 /* On-board 21143 Ethernet */ +#define MOUSSE_IDSEL_LPCI 14 /* On-board PCI slot */ +#define MOUSSE_IDSEL_82371 15 /* That other thing */ +#define MOUSSE_IDSEL_CPCI2 31 /* CPCI slot 2 */ +#define MOUSSE_IDSEL_CPCI3 30 /* CPCI slot 3 */ +#define MOUSSE_IDSEL_CPCI4 29 /* CPCI slot 4 */ +#define MOUSSE_IDSEL_CPCI5 28 /* CPCI slot 5 */ +#define MOUSSE_IDSEL_CPCI6 27 /* CPCI slot 6 */ + +/* + * Mousse Interrupt Mapping: + * + * IRQ1 Enet (intA|intB|intC|intD) + * IRQ2 CPCI intA (See below) + * IRQ3 Local PCI slot intA|intB|intC|intD + * IRQ4 COM1 Serial port (Actually higher addressed port on duart) + * + * PCI Interrupt Mapping in CPCI chassis: + * + * | CPCI Slot + * | 1 (CPU) 2 3 4 5 6 + * -----------+--------+-------+-------+-------+-------+-------+ + * intA | X X X + * intB | X X X + * intC | X X X + * intD | X X X + */ + + +#define EPIC_VECTOR_EXT0 0 +#define EPIC_VECTOR_EXT1 1 +#define EPIC_VECTOR_EXT2 2 +#define EPIC_VECTOR_EXT3 3 +#define EPIC_VECTOR_EXT4 4 +#define EPIC_VECTOR_TM0 16 +#define EPIC_VECTOR_TM1 17 +#define EPIC_VECTOR_TM2 18 +#define EPIC_VECTOR_TM3 19 +#define EPIC_VECTOR_I2C 20 +#define EPIC_VECTOR_DMA0 21 +#define EPIC_VECTOR_DMA1 22 +#define EPIC_VECTOR_I2O 23 + + +#define INT_VEC_IRQ0 0 +#define INT_NUM_IRQ0 INT_VEC_IRQ0 +#define MOUSSE_IRQ_ENET EPIC_VECTOR_EXT1 /* Hardwired */ +#define MOUSSE_IRQ_CPCI EPIC_VECTOR_EXT2 /* Hardwired */ +#define MOUSSE_IRQ_LPCI EPIC_VECTOR_EXT3 /* Hardwired */ +#define MOUSSE_IRQ_DUART EPIC_VECTOR_EXT4 /* Hardwired */ + +/* Onboard DEC 21143 Ethernet */ +#define PCI_ENET_MEMADDR 0x80000000 +#define PCI_ENET_IOADDR 0x80000000 + +/* Some other PCI device */ +#define PCI_SLOT_MEMADDR 0x81000000 +#define PCI_SLOT_IOADDR 0x81000000 + +/* Promise ATA66 PCI Device (ATA controller) */ +#define PROMISE_MBAR0 0xa0000000 +#define PROMISE_MBAR1 (PROMISE_MBAR0 + 0x1000) +#define PROMISE_MBAR2 (PROMISE_MBAR0 + 0x2000) +#define PROMISE_MBAR3 (PROMISE_MBAR0 + 0x3000) +#define PROMISE_MBAR4 (PROMISE_MBAR0 + 0x4000) +#define PROMISE_MBAR5 (PROMISE_MBAR0 + 0x5000) + +/* ATA/66 Controller offsets */ +#define CFG_ATA_BASE_ADDR PROMISE_MBAR0 +#define CFG_IDE_MAXBUS 2 /* ide0/ide1 */ +#define CFG_IDE_MAXDEVICE 2 /* 2 drives per controller */ +#define CFG_ATA_IDE0_OFFSET 0 +#define CFG_ATA_IDE1_OFFSET 0x3000 +/* + * Definitions for accessing IDE controller registers + */ +#define CFG_ATA_DATA_OFFSET 0 +#define CFG_ATA_REG_OFFSET 0 +#define CFG_ATA_ALT_OFFSET (0x1000) + +/* + * The constants ROM_TEXT_ADRS, ROM_SIZE, RAM_HIGH_ADRS, and RAM_LOW_ADRS + * are defined in config.h and Makefile. + * All definitions for these constants must be identical. + */ +#define ROM_BASE_ADRS 0xfff00000 /* base address of ROM */ +#define ROM_TEXT_ADRS (ROM_BASE_ADRS+0x0100) /* with PC & SP */ +#define ROM_WARM_ADRS (ROM_TEXT_ADRS+0x0004) /* warm reboot entry */ +#define ROM_SIZE 0x00080000 /* 512KB ROM space */ +#define RAM_LOW_ADRS 0x00010000 /* RAM address for vxWorks */ +#define RAM_HIGH_ADRS 0x00c00000 /* RAM address for bootrom */ + +/* + * NVRAM configuration + * NVRAM is implemented via the SGS Thomson M48T59Y + * 64Kbit (8Kbx8) Timekeeper SRAM. + * This 8KB NVRAM also has a TOD. See m48t59y.{h,c} for more information. + */ + +#define NV_RAM_ADRS TOD_NVRAM_BASE +#define NV_RAM_INTRVL 1 +#define NV_RAM_WR_ENBL SYS_TOD_UNPROTECT() +#define NV_RAM_WR_DSBL SYS_TOD_PROTECT() + +#define NV_OFF_BOOT0 0x0000 /* Boot string 0 (256b) */ +#define NV_OFF_BOOT1 0x0100 /* Boot string 1 (256b) */ +#define NV_OFF_BOOT2 0x0200 /* Boot string 2 (256b)*/ +#define NV_OFF_MACADDR 0x0400 /* 21143 MAC address (6b) */ +#define NV_OFF_ACTIVEBOOT 0x0406 /* Active boot string, 0 to 2 (1b) */ +#define NV_OFF_UNUSED1 0x0407 /* Unused (1b) */ +#define NV_OFF_BINDFIX 0x0408 /* See sysLib.c:sysBindFix() (1b) */ +#define NV_OFF_UNUSED2 0x0409 /* Unused (7b) */ +#define NV_OFF_TIMEZONE 0x0410 /* TIMEZONE env var (64b) */ +#define NV_OFF_VXWORKS_END 0x07FF /* 2047 VxWorks Total */ +#define NV_OFF_U_BOOT 0x0800 /* 2048 U-Boot boot-loader */ +#define NV_OFF_U_BOOT_ADDR (TOD_BASE + NV_OFF_U_BOOT) /* sysaddr*/ +#define NV_U_BOOT_ENV_SIZE 2048 /* 2K - U-Boot Total */ +#define NV_OFF__next_free (NV_U_BOOT_ENVSIZE +1) +#define NV_RAM_SIZE 8176 /* NVRAM End */ + +#endif /* __MOUSSE_H */ diff --git a/board/mousse/pci.c b/board/mousse/pci.c new file mode 100755 index 0000000..4f39398 --- /dev/null +++ b/board/mousse/pci.c @@ -0,0 +1,283 @@ +/* + * + * (C) Copyright 2000 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * (C) Copyright 2001 + * James Dougherty (jfd@cs.stanford.edu) + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +/* + * PCI Configuration space access support for MPC824x/MPC107 PCI Bridge + */ +#include <common.h> +#include <mpc824x.h> +#include <pci.h> + +#include "mousse.h" + +/* + * Promise ATA/66 support. + */ +#define XFER_PIO_4 0x0C /* 0000|1100 */ +#define XFER_PIO_3 0x0B /* 0000|1011 */ +#define XFER_PIO_2 0x0A /* 0000|1010 */ +#define XFER_PIO_1 0x09 /* 0000|1001 */ +#define XFER_PIO_0 0x08 /* 0000|1000 */ +#define XFER_PIO_SLOW 0x00 /* 0000|0000 */ + +/* Promise Regs */ +#define REG_A 0x01 +#define REG_B 0x02 +#define REG_C 0x04 +#define REG_D 0x08 + +void +pdc202xx_decode_registers (unsigned char registers, unsigned char value) +{ + unsigned char bit = 0, bit1 = 0, bit2 = 0; + switch(registers) { + case REG_A: + bit2 = 0; + printf(" A Register "); + if (value & 0x80) printf("SYNC_IN "); + if (value & 0x40) printf("ERRDY_EN "); + if (value & 0x20) printf("IORDY_EN "); + if (value & 0x10) printf("PREFETCH_EN "); + if (value & 0x08) { printf("PA3 ");bit2 |= 0x08; } + if (value & 0x04) { printf("PA2 ");bit2 |= 0x04; } + if (value & 0x02) { printf("PA1 ");bit2 |= 0x02; } + if (value & 0x01) { printf("PA0 ");bit2 |= 0x01; } + printf("PIO(A) = %d ", bit2); + break; + case REG_B: + bit1 = 0;bit2 = 0; + printf(" B Register "); + if (value & 0x80) { printf("MB2 ");bit1 |= 0x80; } + if (value & 0x40) { printf("MB1 ");bit1 |= 0x40; } + if (value & 0x20) { printf("MB0 ");bit1 |= 0x20; } + printf("DMA(B) = %d ", bit1 >> 5); + if (value & 0x10) printf("PIO_FORCED/PB4 "); + if (value & 0x08) { printf("PB3 ");bit2 |= 0x08; } + if (value & 0x04) { printf("PB2 ");bit2 |= 0x04; } + if (value & 0x02) { printf("PB1 ");bit2 |= 0x02; } + if (value & 0x01) { printf("PB0 ");bit2 |= 0x01; } + printf("PIO(B) = %d ", bit2); + break; + case REG_C: + bit2 = 0; + printf(" C Register "); + if (value & 0x80) printf("DMARQp "); + if (value & 0x40) printf("IORDYp "); + if (value & 0x20) printf("DMAR_EN "); + if (value & 0x10) printf("DMAW_EN "); + + if (value & 0x08) { printf("MC3 ");bit2 |= 0x08; } + if (value & 0x04) { printf("MC2 ");bit2 |= 0x04; } + if (value & 0x02) { printf("MC1 ");bit2 |= 0x02; } + if (value & 0x01) { printf("MC0 ");bit2 |= 0x01; } + printf("DMA(C) = %d ", bit2); + break; + case REG_D: + printf(" D Register "); + break; + default: + return; + } + printf("\n %s ", (registers & REG_D) ? "DP" : + (registers & REG_C) ? "CP" : + (registers & REG_B) ? "BP" : + (registers & REG_A) ? "AP" : "ERROR"); + for (bit=128;bit>0;bit/=2) + printf("%s", (value & bit) ? "1" : "0"); + printf("\n"); +} + +/* + * Promise ATA/66 Support: configure Promise ATA66 card in specified mode. + */ +int +pdc202xx_tune_chipset (pci_dev_t dev, int drive, unsigned char speed) +{ + unsigned short drive_conf; + int err = 0; + unsigned char drive_pci, AP, BP, CP, DP; + unsigned char TA = 0, TB = 0; + + switch (drive) { + case 0: drive_pci = 0x60; break; + case 1: drive_pci = 0x64; break; + case 2: drive_pci = 0x68; break; + case 3: drive_pci = 0x6c; break; + default: return -1; + } + + pci_read_config_word(dev, drive_pci, &drive_conf); + pci_read_config_byte(dev, (drive_pci), &AP); + pci_read_config_byte(dev, (drive_pci)|0x01, &BP); + pci_read_config_byte(dev, (drive_pci)|0x02, &CP); + pci_read_config_byte(dev, (drive_pci)|0x03, &DP); + + if ((AP & 0x0F) || (BP & 0x07)) { + /* clear PIO modes of lower 8421 bits of A Register */ + pci_write_config_byte(dev, (drive_pci), AP & ~0x0F); + pci_read_config_byte(dev, (drive_pci), &AP); + + /* clear PIO modes of lower 421 bits of B Register */ + pci_write_config_byte(dev, (drive_pci)|0x01, BP & ~0x07); + pci_read_config_byte(dev, (drive_pci)|0x01, &BP); + + pci_read_config_byte(dev, (drive_pci), &AP); + pci_read_config_byte(dev, (drive_pci)|0x01, &BP); + } + + pci_read_config_byte(dev, (drive_pci), &AP); + pci_read_config_byte(dev, (drive_pci)|0x01, &BP); + pci_read_config_byte(dev, (drive_pci)|0x02, &CP); + + switch(speed) { + case XFER_PIO_4: TA = 0x01; TB = 0x04; break; + case XFER_PIO_3: TA = 0x02; TB = 0x06; break; + case XFER_PIO_2: TA = 0x03; TB = 0x08; break; + case XFER_PIO_1: TA = 0x05; TB = 0x0C; break; + case XFER_PIO_0: + default: TA = 0x09; TB = 0x13; break; + } + + pci_write_config_byte(dev, (drive_pci), AP|TA); + pci_write_config_byte(dev, (drive_pci)|0x01, BP|TB); + + pci_read_config_byte(dev, (drive_pci), &AP); + pci_read_config_byte(dev, (drive_pci)|0x01, &BP); + pci_read_config_byte(dev, (drive_pci)|0x02, &CP); + pci_read_config_byte(dev, (drive_pci)|0x03, &DP); + + +#ifdef PDC202XX_DEBUG + pdc202xx_decode_registers(REG_A, AP); + pdc202xx_decode_registers(REG_B, BP); + pdc202xx_decode_registers(REG_C, CP); + pdc202xx_decode_registers(REG_D, DP); +#endif + return err; +} +/* + * Show/Init PCI devices on the specified bus number. + */ + +void pci_mousse_fixup_irq(struct pci_controller *hose, pci_dev_t dev) +{ + unsigned int line; + + switch(PCI_DEV(dev)) { + case 0x0d: + line = 0x00000101; + break; + + case 0x0e: + default: + line = 0x00000303; + break; + } + + pci_write_config_dword(dev, PCI_INTERRUPT_LINE, line); +} + +void pci_mousse_setup_pdc202xx(struct pci_controller *hose, pci_dev_t dev, + struct pci_config_table *_) +{ + unsigned short vendorId; + unsigned int mbar0, cmd; + int bar, a; + + pci_read_config_word(dev, PCI_VENDOR_ID, &vendorId); + + if(vendorId == PCI_VENDOR_ID_PROMISE || vendorId == PCI_VENDOR_ID_CMD){ + /* PDC 202xx card is handled differently, it is a bootable + * device and needs all 5 MBAR's configured + */ + for(bar = 0; bar < 5; bar++){ + pci_read_config_dword(dev, PCI_BASE_ADDRESS_0+bar*4, &mbar0); + pci_write_config_dword(dev, PCI_BASE_ADDRESS_0+bar*4, ~0); + pci_read_config_dword(dev, PCI_BASE_ADDRESS_0+bar*4, &mbar0); +#ifdef DEBUG + printf(" ATA_bar[%d] = %dbytes\n", bar, + ~(mbar0 & PCI_BASE_ADDRESS_MEM_MASK) + 1); +#endif + } + + /* Program all BAR's */ + pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, PROMISE_MBAR0); + pci_write_config_dword(dev, PCI_BASE_ADDRESS_1, PROMISE_MBAR1); + pci_write_config_dword(dev, PCI_BASE_ADDRESS_2, PROMISE_MBAR2); + pci_write_config_dword(dev, PCI_BASE_ADDRESS_3, PROMISE_MBAR3); + pci_write_config_dword(dev, PCI_BASE_ADDRESS_4, PROMISE_MBAR4); + pci_write_config_dword(dev, PCI_BASE_ADDRESS_5, PROMISE_MBAR5); + + for(bar = 0; bar < 5; bar++){ + pci_read_config_dword(dev, PCI_BASE_ADDRESS_0+bar*4, &mbar0); +#ifdef DEBUG + printf(" ATA_bar[%d]@0x%x\n", bar, mbar0); +#endif + } + + /* Enable ROM Expansion base */ + pci_write_config_dword(dev, PCI_ROM_ADDRESS, PROMISE_MBAR5|1); + + /* Io enable, Memory enable, master enable */ + pci_read_config_dword(dev, PCI_COMMAND, &cmd); + cmd &= ~0xffff0000; + cmd |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY | PCI_COMMAND_IO; + pci_write_config_dword(dev, PCI_COMMAND, cmd); + + /* Breath some life into the controller */ + for( a = 0; a < 4; a++) + pdc202xx_tune_chipset(dev, a, XFER_PIO_0); + } +} + +static struct pci_config_table pci_sandpoint_config_table[] = { + { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, 0x00, 0x0e, 0x00, + pci_mousse_setup_pdc202xx }, +#ifndef CONFIG_PCI_PNP + { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, 0x00, 0x0d, 0x00, + pci_cfgfunc_config_device, {PCI_ENET_IOADDR, + PCI_ENET_MEMADDR, + PCI_COMMAND_MEMORY | + PCI_COMMAND_MASTER}}, + { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, + pci_cfgfunc_config_device, {PCI_SLOT_IOADDR, + PCI_SLOT_MEMADDR, + PCI_COMMAND_MEMORY | + PCI_COMMAND_MASTER}}, +#endif + { } +}; + +struct pci_controller hose = { + config_table: pci_sandpoint_config_table, + fixup_irq: pci_mousse_fixup_irq, +}; + +void pci_init_board(void) +{ + pci_mpc824x_init(&hose); +} diff --git a/board/mousse/u-boot.lds b/board/mousse/u-boot.lds new file mode 100755 index 0000000..57358b8 --- /dev/null +++ b/board/mousse/u-boot.lds @@ -0,0 +1,131 @@ +/* + * (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) + + *(.fixup) + *(.got1) + . = ALIGN(16); + *(.rodata) + *(.rodata1) + *(.rodata.str1.4) + *(.eh_frame) + } + .fini : { *(.fini) } =0 + .ctors : { *(.ctors) } + .dtors : { *(.dtors) } + + /* Read-write section, merged into data segment: */ + . = (. + 0x0FF) & 0xFFFFFF00; + _erotext = .; + PROVIDE (erotext = .); + .reloc : + { + *(.got) + _GOT2_TABLE_ = .; + *(.got2) + _FIXUP_TABLE_ = .; + *(.fixup) + } + __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >> 2; + __fixup_entries = (. - _FIXUP_TABLE_) >> 2; + + .data : + { + *(.data) + *(.data1) + *(.sdata) + *(.sdata2) + *(.dynamic) + CONSTRUCTORS + } + _edata = .; + PROVIDE (edata = .); + + . = .; + __u_boot_cmd_start = .; + .u_boot_cmd : { *(.u_boot_cmd) } + __u_boot_cmd_end = .; + + + . = .; + __start___ex_table = .; + __ex_table : { *(__ex_table) } + __stop___ex_table = .; + + . = ALIGN(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 = .); +} diff --git a/board/mousse/u-boot.lds.ram b/board/mousse/u-boot.lds.ram new file mode 100755 index 0000000..eb47ae6 --- /dev/null +++ b/board/mousse/u-boot.lds.ram @@ -0,0 +1,105 @@ +/* + * (C) Copyright 2000 + * Rob Taylor, Flying Pig Systems Ltd. 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 + */ + +OUTPUT_ARCH(powerpc) +SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/local/powerpc-any-elf/lib); + +MEMORY { + ram (!rx) : org = 0x00000000 , LENGTH = 8M + code (!rx) : org = 0x00002000 , LENGTH = (4M - 0x2000) + rom (rx) : org = 0xfff00000 , LENGTH = 512K +} + +SECTIONS +{ + _f_init = .; + PROVIDE(_f_init = .); + _f_init_rom = .; + PROVIDE(_f_init_rom = .); + + .init : { + cpu/mpc824x/start.o (.text) + *(.init) + } > ram + _init_size = SIZEOF(.init); + PROVIDE(_init_size = SIZEOF(.init)); + + ENTRY(_start) + +/* _ftext = .; + _ftext_rom = .; + _text_size = SIZEOF(.text); + */ + .text : { + *(.text) + *(.got1) + } > ram + .rodata : { *(.rodata) } > ram + .dtors : { *(.dtors) } > ram + .data : { *(.data) } > ram + .sdata : { *(.sdata) } > ram + .sdata2 : { *(.sdata2) + *(.got) + _GOT2_TABLE_ = .; + *(.got2) + _FIXUP_TABLE_ = .; + *(.fixup) + } > ram + __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2; + __fixup_entries = (. - _FIXUP_TABLE_)>>2; + + .sbss : { *(.sbss) } > ram + .sbss2 : { *(.sbss2) } > ram + .bss : { *(.bss) } > ram + .debug : { *(.debug) } > ram + .line : { *(.line) } > ram + .symtab : { *(.symtab) } > ram + .shrstrtab : { *(.shstrtab) } > ram + .strtab : { *(.strtab) } > ram + /* .reloc : + { + *(.got) + _GOT2_TABLE_ = .; + *(.got2) + _FIXUP_TABLE_ = .; + *(.fixup) + } > ram + */ + + __u_boot_cmd_start = .; + .u_boot_cmd : { *(.u_boot_cmd) } + __u_boot_cmd_end = .; + + __start___ex_table = .; + __ex_table : { *(__ex_table) } > ram + __stop___ex_table = .; + + + .ppcenv : + { + common/environment.o (.ppcenv) + } > ram + + _end = . ; + PROVIDE (end = .); +} diff --git a/board/mousse/u-boot.lds.rom b/board/mousse/u-boot.lds.rom new file mode 100755 index 0000000..5a5722e --- /dev/null +++ b/board/mousse/u-boot.lds.rom @@ -0,0 +1,133 @@ +/* + * (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) + common/board.o (.text) + lib_ppc/ppcstring.o (.text) + lib_generic/vsprintf.o (.text) + lib_generic/crc32.o (.text) + lib_generic/zlib.o (.text) + + . = env_offset; + common/environment.o (.text) + + *(.text) + + *(.fixup) + *(.got1) + . = ALIGN(16); + *(.rodata) + *(.rodata1) + *(.rodata.str1.4) + *(.eh_frame) + } + .fini : { *(.fini) } =0 + .ctors : { *(.ctors) } + .dtors : { *(.dtors) } + + /* Read-write section, merged into data segment: */ + . = (. + 0x0FF) & 0xFFFFFF00; + _erotext = .; + PROVIDE (erotext = .); + .reloc : + { + *(.got) + _GOT2_TABLE_ = .; + *(.got2) + _FIXUP_TABLE_ = .; + *(.fixup) + } + __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >> 2; + __fixup_entries = (. - _FIXUP_TABLE_) >> 2; + + .data : + { + *(.data) + *(.data1) + *(.sdata) + *(.sdata2) + *(.dynamic) + CONSTRUCTORS + } + _edata = .; + PROVIDE (edata = .); + + __u_boot_cmd_start = .; + .u_boot_cmd : { *(.u_boot_cmd) } + __u_boot_cmd_end = .; + + __start___ex_table = .; + __ex_table : { *(__ex_table) } + __stop___ex_table = .; + + . = ALIGN(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 = .); +} |