From: wdenk Date: Mon, 10 Sep 2001 13:51:30 +0000 (+0000) Subject: Added port to MOUSSE board X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=d70b129f8563777facdbeb3b4da3d7945630e90d;p=users%2Frw%2Fppcboot.git Added port to MOUSSE board Patch by James F Dougherty, 10 Sep 2001 --- diff --git a/CHANGELOG b/CHANGELOG index bd46866..6a86d27 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -56,6 +56,12 @@ To do: Modifications for 1.0.5: ====================================================================== +* Added port to MOUSSE board + Patch by James F Dougherty, 10 Sep 2001 + +* Add etags Make target + Patch by James F Dougherty, 10 Sep 2001 + * PPCBoot stores all clock information in Hz internally. #################################################################### diff --git a/CREDITS b/CREDITS index 0b6dc08..e451f8a 100644 --- a/CREDITS +++ b/CREDITS @@ -59,6 +59,10 @@ N: Dan A. Dickey E: ddickey@charter.net D: FADS Support +N: James F. Dougherty +E: jfd@GigabitNetworks.COM +D: Port to the MOUSSE board + N: Dave Ellis E: DGE@sixnetio.com D: EEPROM Speedup, SXNI855T port diff --git a/MAKEALL b/MAKEALL index f9e6cdd..d460bd9 100755 --- a/MAKEALL +++ b/MAKEALL @@ -43,6 +43,7 @@ LIST="$LIST \ LIST="$LIST \ CU824 \ + MOUSSE \ Sandpoint8240 \ " diff --git a/Makefile b/Makefile index 0bdf76a..ae06d46 100644 --- a/Makefile +++ b/Makefile @@ -107,6 +107,10 @@ tags: ctags -w `find $(SUBDIRS) include \ \( -name CVS -prune \) -o \( -name '*.[ch]' -print \)` +etags: + etags -a `find $(SUBDIRS) include \ + \( -name CVS -prune \) -o \( -name '*.[ch]' -print \)` + ######################################################################### else all install ppcboot ppcboot.srec depend dep: @@ -427,6 +431,14 @@ CU824_config: unconfig echo "CPU = mpc8240" >>config.mk ; \ echo "#include " >config.h +MOUSSE_config: unconfig + @echo "Configuring for $(@:_config=) Board..." ; \ + cd include ; \ + echo "ARCH = ppc" > config.mk ; \ + echo "BOARD = mousse" >>config.mk ; \ + echo "CPU = mpc8240" >>config.mk ; \ + echo "#include " >config.h + Sandpoint8240_config: unconfig @echo "Configuring for $(@:_config=) Board..." ; \ cd include ; \ diff --git a/board/mousse/Makefile b/board/mousse/Makefile new file mode 100644 index 0000000..f24ec6c --- /dev/null +++ b/board/mousse/Makefile @@ -0,0 +1,42 @@ +# +# (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 ns16550.o serial.o speed.o dc2114x.o\ + m48t59y.o pci.o flash.o +#pci.o + +$(LIB): .depend $(OBJS) + $(AR) crv $@ $^ + +######################################################################### + +.depend: Makefile $(SOBJS:.o=.S) $(OBJS:.o=.c) + $(CC) -M $(CFLAGS) $(SOBJS:.o=.S) $(OBJS:.o=.c) > $@ + +sinclude .depend + +######################################################################### diff --git a/board/mousse/README b/board/mousse/README new file mode 100644 index 0000000..3b9dabb --- /dev/null +++ b/board/mousse/README @@ -0,0 +1,350 @@ + +PPCBoot 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 PPCBoot to onboard and PLCC boot region. +* Kernel command line options from NVRAM is supported. +* IP PNP options supported. + +PPCBoot Loading... + + + +PPCBoot 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= +netmask= +hostname= +serverip= +ethaddr=00:00:10:20:30:44 +nfsroot=:/boot/root-fs +gateway= +root=/dev/nfs +stdin=serial +stdout=serial +stderr=serial + +NVRAM environment variables. + +use the command: + +setenv + +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= +netmask= +hostname=mousse +ethaddr=00:00:10:20:30:44 +gateway= + + +IV. IP Options which configure NFS Root/Boot Support + +root=/dev/nfs +serverip= +nfsroot=:/boot/root-fs + +V. PPCBoot Image Support + +The PPCBoot boot loader assumes that after you build +your kernel (vmlinux), you will create a PPCBoot image +using the following commands or script: + +#!/bin/csh +/bin/touch vmlinux.img +/bin/rm vmlinux.img +set path=($TOOLBASE/bin $path) +set path=($PPCBOOT/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. +PPCBoot 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 ppcboot.bin or ppcboot.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 +(ppcboot.bin) image into the onboard bootrom region (AMD29LV160DB): + +tftp 100000 ppcboot.bin +protect off FFF00000 FFF7FFFF +erase FFF00000 FFF7FFFF +cp.b 100000 FFF00000 \$(filesize)\ + + +Here is an example: + +=>tftp 100000 ppcboot.bin +eth_halt +eth0: DC21143 Ethernet adapter(bus=0, device=13, func=0) +DEC Ethernet iobase=0x80000000 +ARP broadcast 1 +Filename 'ppcboot.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 (ppcboot.bin) image +into the onboard FLASH region (AMD29LV160DB 2MB FLASH): + +tftp 100000 ppcboot.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 PPCboot 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 100644 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/dc2114x.c b/board/mousse/dc2114x.c new file mode 100644 index 0000000..2931ead --- /dev/null +++ b/board/mousse/dc2114x.c @@ -0,0 +1,918 @@ +/* + * MOUSSE Onboard DEC 21143-TD (DC1096B) Ethernet support. + * + * (C) Copyright 2000, 2001 + * 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 + */ +/* + * DEC 21143 Ethernet driver. + */ +#include +#include +#include +#include "pci.h" +#include "mousse.h" +/* + * PCI Registers. + */ +#define PCI_VENDOR_ID PCI_CFG_VENDOR_ID +#define PCI_COMMAND PCI_CFG_COMMAND +#define PCI_CLASS_REVISION PCI_CFG_REVISION +#define PCI_BASE_ADDRESS_0 PCI_CFG_BASE_ADDRESS_0 +#define PCI_CFDA_PSM PCI_CFG_MODE + +#define PCI_COMMAND_IO PCI_CMD_IO_ENABLE +#define PCI_COMMAND_MASTER PCI_CMD_MASTER_ENABLE + +#define CFRV_RN 0x000000f0 /* Revision Number */ +#define CBIO_MASK -128 + +#define WAKEUP 0x00 /* Power Saving Wakeup */ +#define SLEEP 0x80 /* Power Saving Sleep Mode */ + +#define DC21140_VENDOR_ID 0x1011 +#define DC21140_DEVICE_ID 0x0009 +#define DC21143_VENDOR_ID 0x1011 +#define DC21143_DEVICE_ID 0x0019 + + +#define DC2114x_VID 0x1011 /* DC2114[23] Manufacturer */ +#define DC2114x_DID 0x1900 /* Unique Device ID # */ +#define DC2114x_BRK 0x0020 /* CFRV break between DC21142 & DC21143 */ +#define DC21142 (DC2114x_DID | 0x0010) +#define DC21143 (DC2114x_DID | 0x0030) + +#define is_DC2114x ((vendor == DC21143_VENDOR_ID) &&\ + (device == DC21143_DEVICE_ID)) + +/* + * DEC 2114x Ethernet chip registers. + */ +#define DE4X5_BMR iobase + 0x000 /* Bus Mode Register */ +#define DE4X5_TPD iobase + 0x008 /* Transmit Poll Demand Reg */ +#define DE4X5_RRBA iobase + 0x018 /* RX Ring Base Address Reg */ +#define DE4X5_TRBA iobase + 0x020 /* TX Ring Base Address Reg */ +#define DE4X5_STS iobase + 0x028 /* Status Register */ +#define DE4X5_OMR iobase + 0x030 /* Operation Mode Register */ +#define DE4X5_SICR iobase + 0x068 /* SIA Connectivity Register */ +#define DE4X5_TXRX iobase + 0x070 /* SIA Transmit and Receive Register */ +#define DE4X5_GPPR iobase + 0x078 /* General Purpose Port register */ +#define DE4X5_APROM iobase + 0x048 /* Ethernet Address PROM */ + +/* Defines for Bus mode register */ +#define DE_BMR_BE 0x00000080 /* CSR0: Big Endian mode (bit 7) */ +#define DE_BMR_TAP_02 0x00000002 /* CSR0: Tx poll every 200 usec */ +#define DE_BMR_TAP_08 0x00000004 /* CSR0: Tx poll every 800 usec */ +#define DE_BMR_TAP_16 0x00000006 /* CSR0: Tx poll every 1.6 msec */ +#define DE_BMR_TAP_012 0x00000008 /* CSR0: Tx poll every 12.8 usec */ +#define DE_BMR_TAP_025 0x0000000A /* CSR0: Tx poll every 25.6 usec */ +#define DE_BMR_TAP_051 0x0000000C /* CSR0: Tx poll every 51.2 usec */ +#define DE_BMR_TAP_102 0x0000000E /* CSR0: Tx poll every 102.4 usec */ +#define DE_BMR_TAP_MSK 0x0000000E +#define DE_BMR_TAP_SHF 16 + +#define DE_BMR_CAL_08 0x00000010 /* CSR0: Cache adrs aligned 8 lwords */ +#define DE_BMR_CAL_16 0x00000020 /* CSR0: Cache adrs aligned 16 lwords */ +#define DE_BMR_CAL_32 0x00000030 /* CSR0: Cache adrs aligned 32 lwords */ +#define DE_BMR_CAL_MSK 0x00000030 +#define DE_BMR_CAL_SHF 10 + +#define DE_BMR_PBL_01 0x00000040 /* CSR0: DMA burst len 1 lword */ +#define DE_BMR_PBL_02 0x00000080 /* CSR0: DMA burst len 2 lwords */ +#define DE_BMR_PBL_04 0x00000100 /* CSR0: DMA burst len 4 lwords */ +#define DE_BMR_PBL_08 0x00000200 /* CSR0: DMA burst len 8 lwords */ +#define DE_BMR_PBL_16 0x00000400 /* CSR0: DMA burst len 16 lwords */ +#define DE_BMR_PBL_32 0x00000800 /* CSR0: DMA burst len 32 lwords */ +#define DE_BMR_PBL_MSK 0x00000FC0 +#define DE_BMR_PBL_SHF 2 +#define DE_BMR_RML 0x00002000 /* CSR0: PCI memory-read-multiple */ + + +/* + * Descriptor RDES0/TDES0 (status) Error summary bit defines + */ +#define ES_RX_FF (1<<30) +#define ES_RX_FL (1<<23) +#define ES_TX_FL (1<<23) +#define ES_TX_ES (1<<15) +#define ES_RX_DE (1<<14) +#define ES_TX_TO (1<<14) +#define ES_RX_RF (1<<11) +#define ES_TX_LI (1<<11) +#define ES_RX_TL (1<<7) +#define ES_TX_LC (1<<9) +#define ES_TX_EC (1<<8) +#define ES_TX_TL (1<<7) +#define ES_RX_CS (1<<6) +#define ES_RX_RW (1<<4) +#define ES_RX_RE (1<<3) +#define ES_RX_DB (1<<2) +#define ES_TX_LF (1<<2) +#define ES_RX_CE (1<<1) +#define ES_TX_UF (1<<1) +#define ES_RX_Z (1<<0) +#define ES_TX_DE (1<<0) + +/* + * Defines for status bits in STS status register. + */ +#define STS_LC (1<<27) +#define STS_GPI (1<<26) +#define STS_NIS (1<<16) +#define STS_AIS (1<<15) +#define STS_ERI (1<<14) +#define STS_FBE (1<<13) +#define STS_LNF (1<<12) +#define STS_GTE (1<<11) +#define STS_ETI (1<<10) +#define STS_RWT (1<<9) +#define STS_RPS (1<<8) +#define STS_RU (1<<7) +#define STS_RI (1<<6) +#define STS_UNF (1<<5) +#define STS_ANC (1<<4) +#define STS_TJT (1<<3) +#define STS_TU (1<<2) +#define STS_TPS (1<<1) +#define STS_TI (1<<0) + +/* + * Masks for STS receive/transmit process state, error bits + * See Also: Intel 21143 H/W Ref: Table 3-67 + */ +#define STS_ES_EB_MASK 0x03800000 +#define STS_ES_EB_SHIFT 20 +#define STS_ES_TS_MASK 0x00700000 +#define STS_ES_TS_SHIFT 20 +#define STS_ES_RS_MASK 0x000E0000 +#define STS_ES_RS_SHIFT 16 + +/* + * Misc Register bits. + */ +#define BMR_SWR 0x00000001 /* Software Reset */ +#define STS_TS 0x00700000 /* Transmit Process State */ +#define STS_RS 0x000e0000 /* Receive Process State */ + +/* OMR : (CSR6) Operation Mode Register bit defines */ +#define OMR_ST 0x00002000 /* Start/Stop Transmission Command */ +#define OMR_PS 0x00040000 /* Port Select */ +#define OMR_SDP 0x02000000 /* SD Polarity - MUST BE ASSERTED */ +#define OMR_SC 0x80000000 /* special capture effect enable */ +#define OMR_RA 0x40000000 /* receive all */ +#define OMR_SCR 0x01000000 /* scrambler mode */ +#define OMR_PCS 0x00800000 /* PCS function */ +#define OMR_TTM 0x00400000 /* tx threshold mode */ +#define OMR_SF 0x00200000 /* store and forward */ +#define OMR_HBD 0x00080000 /* heartbeat disable */ +#define OMR_CAE 0x00020000 /* capture effect enable */ +#define OMR_THR_072 0x00000000 /* threshold bytes 72 */ +#define OMR_THR_096 0x00004000 /* threshold bytes 96 */ +#define OMR_THR_128 0x00008000 /* threshold bytes 128 */ +#define OMR_THR_160 0x0000C000 /* threshold bytes 160 */ + +#define OMR_ST 0x00002000 /* start/stop Xmit command */ +#define OMR_FC 0x00001000 /* Force collision mode */ +#define OMR_OM_EL 0x00000800 /* External loopback mode */ +#define OMR_OM_IL 0x00000400 /* Internal loopback mode */ +#define OMR_OM_NOR 0x00000000 /* normal mode */ +#define OMR_FD 0x00000200 /* Full Duplex mode */ +#define OMR_PM 0x00000080 /* Pass All Multicast */ +#define OMR_PR 0x00000040 /* promiscuous mode */ +#define OMR_SB 0x00000020 /* Start/Stop Back off counter */ +#define OMR_IF 0x00000010 /* inverse filtering [RO] */ +#define OMR_PB 0x00000008 /* pass bad frames */ +#define OMR_HO 0x00000004 /* hash only filter mode [RO] */ +#define OMR_SR 0x00000002 /* Start/Stop Receive */ +#define OMR_HP 0x00000001 /* hash/perfect filter mode [RO] */ + +/* + * DMA Descriptor bits. + */ +#define R_OWN 0x80000000 /* Own Bit */ +#define RD_RER 0x02000000 /* Receive End Of Ring */ +#define RD_LS 0x00000100 /* Last Descriptor */ +#define RD_ES 0x00008000 /* Error Summary */ +#define TD_TER 0x02000000 /* Transmit End Of Ring */ +#define T_OWN 0x80000000 /* Own Bit */ +#define TD_LS 0x40000000 /* Last Segment */ +#define TD_FS 0x20000000 /* First Segment */ +#define TD_ES 0x00008000 /* Error Summary */ +#define TD_SET 0x08000000 /* Setup Packet */ +#define TD_AC (1<<26) /* Add CRC Disable: Disable CRC Addition */ +#define TD_DPD (1<<23) /* Disable padding on frames < 64 */ + +#define SROM_HWADD 0x0014 /* Hardware Address offset in SROM */ +#define SROM_RD 0x00004000 /* Read from Boot ROM */ +#define SROM_SR 0x00000800 /* Select Serial ROM when set */ + +#define DT_IN 0x00000004 /* Serial Data In */ +#define DT_CLK 0x00000002 /* Serial ROM Clock */ +#define DT_CS 0x00000001 /* Serial ROM Chip Select */ + +#define POLL_DEMAND 1 + +#define RESET_DE4X5 {\ + int i;\ + i=inl(DE4X5_BMR);\ + udelay(1000);\ + outl(i | BMR_SWR, DE4X5_BMR);\ + udelay(1000);\ + outl(i, DE4X5_BMR);\ + udelay(1000);\ + for (i=0;i<5;i++) {inl(DE4X5_BMR); udelay(10000);}\ + udelay(1000);\ +} + +#define START_DE4X5 {\ + s32 omr; \ + omr = inl(DE4X5_OMR);\ + omr |= OMR_ST | OMR_SR;\ + outl(omr, DE4X5_OMR); /* Enable the TX and/or RX */\ +} + +#define STOP_DE4X5 {\ + s32 omr; \ + omr = inl(DE4X5_OMR);\ + omr &= ~(OMR_ST|OMR_SR);\ + outl(omr, DE4X5_OMR); /* Disable the TX and/or RX */ \ +} + +#define NUM_RX_DESC PKTBUFSRX +#define NUM_TX_DESC 1 /* Number of TX descriptors */ +#define RX_BUFF_SZ PKTSIZE_ALIGN + +#define TOUT_LOOP 1000000 + +#define SETUP_FRAME_LEN 192 +#define ETH_ALEN 6 + +struct de4x5_desc { + volatile s32 status; +#define tdes0 status +#define rdes0 status + u32 des1; +#define tdes1 des1 +#define rdes1 des1 + u32 buf; +#define tdes2 buf +#define rdes2 buf + u32 next; +#define tdes3 next +#define rdes3 next +}; + + +static struct de4x5_desc rx_ring[NUM_RX_DESC]; /* RX descriptor ring */ +static struct de4x5_desc tx_ring[NUM_TX_DESC]; /* TX descriptor ring */ +static int rx_new; /* RX descriptor ring pointer */ +static int tx_new; /* TX descriptor ring pointer */ + +static char rxRingSize; +static char txRingSize; + +static u32 iobase, eth_online; +static int device=0, vendor=0, devno=0xd, bus=0, func=0; + +static void send_setup_frame(bd_t * bis); +static void check_hw_addr(bd_t * bis); +static short srom_rd(u_long address, u_char offset); +static void srom_latch(u_int command, u_long address); +static void srom_command(u_int command, u_long address); +static void srom_address(u_int command, u_long address, u_char offset); +static short srom_data(u_int command, u_long address); +static void sendto_srom(u_int command, u_long addr); +static int getfrom_srom(u_long addr); + +static inline int inl(u_long addr) +{ + return le32_to_cpu(*(volatile u_long *)(addr)); +} + +static inline void outl (int command, u_long addr) +{ + *(volatile u_long *)(addr) = cpu_to_le32(command); +} + + +void dc21x4x_init(bd_t *bis) +{ + int cfrv; + uint32 tmp; + + /* Find PCI device */ + if ( OK != pci_dev_find(DC21143_VENDOR_ID, + DC21143_DEVICE_ID,0, + &bus,&devno,&func)){ + printf("Error: Can not find an ethernet card on the PCI bus\n"); + goto Done; + } + printf("eth0: DC21143 Ethernet adapter @0x%x" + "(bus=%d, device=%d, func=%d)\n", + PCI_ENET_MEMADDR, bus,devno,func); + + /* Check revision */ + pci_config_inl(bus,devno,func, PCI_CFG_VENDOR_ID,&vendor); + device = (vendor >> 16) & 0x0000ffff; + vendor = vendor & 0x0000ffff; + if (! is_DC2114x){ + printf("Error: The chip is not DC2114x.\n"); + goto Done; + } + + pci_config_inl(bus,devno,func, PCI_CFG_REVISION, &cfrv); + /* Get the chip configuration revision register. + */ + device = ((cfrv & CFRV_RN) < DC2114x_BRK ? DC21142 : DC21143); + + if (device != DC21143){ + printf("Error: The chip is not DC21143.\n"); + goto Done; + } + + if(OK != pci_dev_config(bus, devno, func, + PCI_ENET_IOADDR, + PCI_ENET_MEMADDR, + PCI_CMD_MEM_ENABLE | + PCI_CMD_MEM_ENABLE | + PCI_CMD_MASTER_ENABLE)){ + + printf("DEC 21143 PCI Device configuration failed.\n"); + goto Done; + } + + /* Set IRQ (ILINE) */ + pci_config_outl(bus, devno, func, + PCI_CFG_DEV_INT_LINE, MOUSSE_IRQ_ENET); + + /* + * Turn off snooze mode. + */ + pci_config_inl(bus,devno,func,0x40, &tmp); + if(tmp) + pci_config_outl(bus,devno,func,0x40,0x0); + + /* Read back memory base address */ + pci_config_inl(bus, devno, func, + PCI_CFG_BASE_ADDRESS_0, &iobase); + if (iobase == 0xffffffff){ + printf("Error: Can not set I/O base register (MBAR0).\n"); + goto Done; + } + + /* Clear status bits */ + iobase &= CBIO_MASK; + + /* Disable doze mode */ + pci_config_outl(bus, devno, func, PCI_CFG_MODE, WAKEUP); + + check_hw_addr(bis); + udelay(10 * 1000); + + /* Reset Chip */ + RESET_DE4X5; + + /* + * Initialization + * + * Full Duplex Mode: MII/SYM Mode: Port Select Procedure. + * CSR13<15:0> = 0 (DE4X5_SICR) + * CSR14<15:0> = 0 (DE4X5_TXRX) + * CSR15<15:0> = 0008 (DE4X5_GPPR) + * CSR6 = 1,1 (DE4X5_OMR) + * CSR6 = 00 + * + */ + /* CSR13, CSR14 */ + tmp = inl(DE4X5_SICR); + tmp &= 0xffff0000; + outl(tmp, DE4X5_SICR); + tmp = inl(DE4X5_TXRX); + tmp &= 0xffff0000; + outl(tmp, DE4X5_TXRX); + + /* AUI/BNC Mode */ + tmp = inl(DE4X5_GPPR); + tmp &= 0xffff0000; + tmp |= 0x8; + outl(tmp, DE4X5_GPPR); + + /* + * CSR6: Setup to work with transmit threshold mode, + * port select, pass all multicast, full-duplex. + */ + + tmp = inl(DE4X5_OMR); + tmp |= (OMR_SF|OMR_SDP|OMR_TTM|OMR_PS|OMR_PM|OMR_FD); + outl(tmp, DE4X5_OMR); + + eth_online = 1; + /* pci_dev_show(0); */ + Done: + return; +} + +void +dc21x4x_log_error(void) +{ + u32 stat = le32_to_cpu(tx_ring[tx_new].tdes0); + printf("TX (TDES0) error status = 0x%08X\n", stat); + if(stat & T_OWN) + printf("TXO "); + if(stat & R_OWN) + printf("RXO "); + if(stat & ES_TX_ES) + printf("ES "); + if(stat & ES_TX_DE) + printf("DE "); + if(stat & ES_TX_UF) + printf("UF "); + if(stat & ES_TX_EC) + printf("EC "); + if(stat & ES_TX_LI) + printf("Lost Carrier "); + if(stat & ES_TX_LC) + printf("LC "); + if(stat & ES_TX_TO) + printf("TJBR Timeout "); + if(stat & ES_TX_LF) + printf("Link Fail "); + printf("\nTX TDES1=0x%x (tbs1=%d tbs2=%d) TDES2=0x%x TDES3=0x%x\n", + le32_to_cpu(tx_ring[tx_new].tdes1), + le32_to_cpu(tx_ring[tx_new].tdes1) & 0x000007ff, + (le32_to_cpu(tx_ring[tx_new].tdes1) & 0x003ff800) >> 11, + le32_to_cpu(tx_ring[tx_new].tdes2), + le32_to_cpu(tx_ring[tx_new].tdes3) + ); +#if RX_DEBUG + u32 stat = le32_to_cpu(rx_ring[rx_new].status); + printf("RX (RDES0) error status = 0x%08X\n", stat); + if(stat & T_OWN) + printf("TXO "); + if(stat & R_OWN) + printf("RXO "); + if(stat & ES_RX_FF) + printf("FF "); + if(stat & ES_RX_FL) + printf("FL "); + if(stat & ES_RX_DE) + printf("DE "); + if(stat & ES_RX_RF) + printf("RF "); + if(stat & ES_RX_TL) + printf("TL "); + if(stat & ES_RX_CS) + printf("CS "); + if(stat & ES_RX_RW) + printf("RW "); + if(stat & ES_RX_RE) + printf("MII "); + if(stat & ES_RX_DB) + printf("DB "); + if(stat & ES_RX_CE) + printf("CE "); +#endif + + printf("status: "); + stat = inl(DE4X5_STS); + + if(stat & STS_LC) + printf("lc "); + if(stat & STS_GPI) + printf("gpi "); + if(stat & STS_NIS) + printf("nis "); + if(stat & STS_AIS) + printf("ais "); + if(stat & STS_ERI) + printf("eri "); + if(stat & STS_FBE) + printf("fbe "); + if(stat & STS_LNF) + printf("lnf "); + if(stat & STS_GTE) + printf("gte "); + if(stat & STS_ETI) + printf("eti "); + if(stat & STS_RWT) + printf("rwt "); + if(stat & STS_RPS) + printf("rps "); + if(stat & STS_RU) + printf("ru "); + if(stat & STS_RI) + printf("ri "); + if(stat & STS_UNF) + printf("unf "); + if(stat & STS_ANC) + printf("link "); + if(stat & STS_TJT) + printf("tjt "); + if(stat & STS_TU) + printf("tu "); + if(stat & STS_TPS) + printf("tps "); + if(stat & STS_TI) + printf("ti "); + printf("\n"); + + printf("eb=%d tps=%d rps=%d\n", + (stat & STS_ES_EB_MASK) >> STS_ES_EB_SHIFT, + (stat & STS_ES_TS_MASK) >> STS_ES_TS_SHIFT, + (stat & STS_ES_RS_MASK) >> STS_ES_RS_SHIFT); +} + + + + +int eth_init(bd_t *bis) +{ + int i; + + dc21x4x_init(bis); + + if ((inl(DE4X5_STS) & (STS_TS | STS_RS)) != 0) + { + printf("Error: Can not reset ethernet controller.\n"); + goto Done; + } + + outl(OMR_SDP | OMR_PS | OMR_PM, DE4X5_OMR); + + for (i = 0; i < NUM_RX_DESC; i++) + { + rx_ring[i].status = cpu_to_le32(R_OWN); + rx_ring[i].des1 = cpu_to_le32(RX_BUFF_SZ); + rx_ring[i].buf = cpu_to_le32((u_long)NetRxPackets[i]); + rx_ring[i].next = 0; + } + + for (i=0; i < NUM_TX_DESC; i++) + { + tx_ring[i].status = 0; + tx_ring[i].des1 = 0; + tx_ring[i].buf = 0; + tx_ring[i].next = 0; + } + + rxRingSize = NUM_RX_DESC; + txRingSize = NUM_TX_DESC; + + /* Write the end of list marker to the descriptor lists. + */ + rx_ring[rxRingSize - 1].des1 |= cpu_to_le32(RD_RER); + tx_ring[txRingSize - 1].des1 |= cpu_to_le32(TD_TER); + + /* Tell the adapter where the TX/RX rings are located. + */ + outl((u_long)&rx_ring, DE4X5_RRBA); + outl((u_long)&tx_ring, DE4X5_TRBA); + + START_DE4X5; + + tx_new = 0; + rx_new = 0; + + send_setup_frame(bis); + +Done: + + return 0; +} + +int eth_send(volatile void *packet, int length) +{ + int status = 0; + int i; + +#if TX_DEBUG + unsigned char* pkt = (unsigned char*)packet; + printf("\neth_send: frame data follows ...\n============\n"); + for( i = 0; i < length; i++){ + printf("%d ", pkt[i]); + if(i > 0 && ((i % 16) == 0)) + printf("\n"); + } + printf("\n=============\n"); +#endif + + if (length <= 0) + { + printf("eth: bad packet size: %d\n", length); + goto out; + } + + for(i = 0; tx_ring[tx_new].status & cpu_to_le32(T_OWN); i++) + { + if (i >= TOUT_LOOP) + { + printf("eth: tx error buffer not ready\n"); + goto out; + } + } + tx_ring[tx_new].next = 0; + tx_ring[tx_new].buf = cpu_to_le32((u_long)packet); + tx_ring[tx_new].des1 = cpu_to_le32(TD_TER | TD_LS | TD_FS | length); + tx_ring[tx_new].status = cpu_to_le32(T_OWN); + + outl(inl(DE4X5_STS), DE4X5_STS); /* Clear status bits */ + outl(POLL_DEMAND, DE4X5_TPD); + + for(i = 0; tx_ring[tx_new].status & cpu_to_le32(T_OWN); i++) + { + if (i >= TOUT_LOOP) + { + printf("eth: tx buffer not ready\n"); + goto out; + } + } +#if 0 + if(inl(DE4X5_STS) & STS_TU){ + printf("Transmit buffer unavailable. Retrying ...\n"); + outl(inl(DE4X5_STS), DE4X5_STS); /* Clear status bits */ + goto start; + } +#endif + + /* Determine which error, if any, we detected. + * See also: Intel 21143 Hardware Reference + * Table 3-66 + * Ignore: Transmit Process stopped due to Buffer Unavailable. + */ +#if 1 + if ((le32_to_cpu(tx_ring[tx_new].status) & TD_ES) && + !(inl(DE4X5_STS) & STS_TU)) +#else + if ((le32_to_cpu(tx_ring[tx_new].status) & TD_ES)) +#endif + { + dc21x4x_log_error(); + status++; + } + + out: + return status; +} + +int eth_rx(void) +{ + s32 status; + int length = 0; + + for ( ; ; ) + { + status = (s32)le32_to_cpu(rx_ring[rx_new].status); + + if (status & R_OWN) + { + break; + } + + if (status & RD_LS) + { + /* Valid frame status. + */ + if (status & RD_ES) + { + /* There was an error. + */ + printf("RX error status = 0x%08X\n", status); + } + else + { + /* A valid frame received. + */ + length = (le32_to_cpu(rx_ring[rx_new].status) >> + 16); + + /* Pass the packet up to the protocol + * layers. + */ + NetReceive(NetRxPackets[rx_new], length - 4); + } + + /* Change buffer ownership for this frame, back + * to the adapter. + */ + rx_ring[rx_new].status = cpu_to_le32(R_OWN); + } + + /* Update entry information. + */ + rx_new = (++rx_new) % rxRingSize; + } + + return length; +} + +void eth_halt(void) +{ + if(eth_online){ + STOP_DE4X5; + outl(0, DE4X5_SICR); + pci_config_outb(bus, device, func, PCI_CFG_MODE, SLEEP); + eth_online = 0; + } +} + +static void check_hw_addr(bd_t *bis) +{ + unsigned char hw_addr[ETH_ALEN]; + u_short tmp, *p = (short *)(&hw_addr[0]); + int i, j = 0; + + for (i = 0; i < (ETH_ALEN >> 1); i++) + { + tmp = srom_rd(DE4X5_APROM, (SROM_HWADD >> 1) + i); + *p = le16_to_cpu(tmp); + j += *p++; + } + + if ((j == 0) || (j == 0x2fffd)) + { + // printf("Warning: can't read HW address from SROM.\n"); + goto Done; + } + + for (i = 0; i < ETH_ALEN; i++) + { + if (hw_addr[i] != bis->bi_enetaddr[i]) + { + printf("Warning: HW addresses don't match:\n"); + printf("Address in SROM is " + "%02X:%02X:%02X:%02X:%02X:%02X\n", + hw_addr[0], hw_addr[1], hw_addr[2], + hw_addr[3], hw_addr[4], hw_addr[5]); + printf("Address used by ppcboot is " + "%02X:%02X:%02X:%02X:%02X:%02X\n", + bis->bi_enetaddr[0], bis->bi_enetaddr[1], + bis->bi_enetaddr[2], bis->bi_enetaddr[3], + bis->bi_enetaddr[4], bis->bi_enetaddr[5]); + goto Done; + } + } + + Done: +} + +static void send_setup_frame(bd_t *bis) +{ + int i; + char setup_frame[SETUP_FRAME_LEN]; + char * pa = &setup_frame[0]; + + memset(pa, 0xff, SETUP_FRAME_LEN); + + for (i = 0; i < ETH_ALEN; i++) + { + *(pa + (i & 1)) = bis->bi_enetaddr[i]; + if (i & 0x01) + { + pa += 4; + } + } + + for(i = 0; tx_ring[tx_new].status & cpu_to_le32(T_OWN); i++) + { + if (i >= TOUT_LOOP) + { + printf("eth: tx error buffer not ready\n"); + goto out; + } + } + + tx_ring[tx_new].buf = cpu_to_le32((u_long)&setup_frame[0]); + tx_ring[tx_new].des1 = cpu_to_le32(TD_TER | TD_SET| SETUP_FRAME_LEN); + tx_ring[tx_new].status = cpu_to_le32(T_OWN); + + outl(POLL_DEMAND, DE4X5_TPD); + + for(i = 0; tx_ring[tx_new].status & cpu_to_le32(T_OWN); i++) + { + if (i >= TOUT_LOOP) + { + printf("eth: tx buffer not ready\n"); + goto out; + } + } + + if (le32_to_cpu(tx_ring[tx_new].status) != 0x7FFFFFFF) + { + printf("Setup Frame TX error status = 0x%08X\n", + le32_to_cpu(tx_ring[tx_new].status)); + } + out: +} + + /* SROM Read. + */ +static short +srom_rd(u_long addr, u_char offset) +{ + sendto_srom(SROM_RD | SROM_SR, addr); + + srom_latch(SROM_RD | SROM_SR | DT_CS, addr); + srom_command(SROM_RD | SROM_SR | DT_IN | DT_CS, addr); + srom_address(SROM_RD | SROM_SR | DT_CS, addr, offset); + + return srom_data(SROM_RD | SROM_SR | DT_CS, addr); +} + +static void +srom_latch(u_int command, u_long addr) +{ + sendto_srom(command, addr); + sendto_srom(command | DT_CLK, addr); + sendto_srom(command, addr); + + return; +} + +static void +srom_command(u_int command, u_long addr) +{ + srom_latch(command, addr); + srom_latch(command, addr); + srom_latch((command & 0x0000ff00) | DT_CS, addr); + + return; +} + +static void +srom_address(u_int command, u_long addr, u_char offset) +{ + int i; + signed char a; + + a = (char)(offset << 2); + for (i=0; i<6; i++, a <<= 1) { + srom_latch(command | ((a < 0) ? DT_IN : 0), addr); + } + udelay(1); + + i = (getfrom_srom(addr) >> 3) & 0x01; + + return; +} + +static short +srom_data(u_int command, u_long addr) +{ + int i; + short word = 0; + s32 tmp; + + for (i=0; i<16; i++) { + sendto_srom(command | DT_CLK, addr); + tmp = getfrom_srom(addr); + sendto_srom(command, addr); + + word = (word << 1) | ((tmp >> 3) & 0x01); + } + + sendto_srom(command & 0x0000ff00, addr); + + return word; +} + +static void +sendto_srom(u_int command, u_long addr) +{ + outl(command, addr); + udelay(1); + + return; +} + +static int +getfrom_srom(u_long addr) +{ + s32 tmp; + + tmp = inl(addr); + udelay(1); + + return tmp; +} + diff --git a/board/mousse/flash.c b/board/mousse/flash.c new file mode 100644 index 0000000..594ce75 --- /dev/null +++ b/board/mousse/flash.c @@ -0,0 +1,932 @@ +/* + * MOUSSE/MPC8240 Board definitions. + * Flash Routines for MOUSSE onboard AMD29LV106DB devices + * + * (C) Copyright 2000 + * Marius Groeger + * Sysgo Real-Time Solutions, GmbH + * + * (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 +#include +#include +#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) { + 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; + + 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 (erase) + polls = FLASH_ERASE_SECTOR_TIMEOUT; /* Ticks */ + else + polls = FLASH_PROGRAM_POLLS; /* Loops */ + + for (i = 0; i < polls; i++) { + if (erase) + udelay(SLEEP_DELAY); + + if (dev->bank == FLASH0_BANK) + 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. + */ + + if (dev->bank == FLASH0_BANK) + 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); + 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) { + 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 (PPCBoot) + */ + 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 (PPCBoot) + */ + 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 PPCBoot 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; isector_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. + */ +void 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; + } + + 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; + } + } + } + } + printf (" done\n"); +} + +/*----------------------------------------------------------------------- + * 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; i0; ++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 100644 index 0000000..bfd203d --- /dev/null +++ b/board/mousse/flash.h @@ -0,0 +1,78 @@ +#ifndef FLASH_LIB_H +#define FLASH_LIB_H + +#include + +/* 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); +void 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 100644 index 0000000..beda53b --- /dev/null +++ b/board/mousse/m48t59y.c @@ -0,0 +1,323 @@ +/* + * 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 +#include +#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(); +} + +/* + * PPCBoot 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 100644 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 100644 index 0000000..36810af --- /dev/null +++ b/board/mousse/mousse.c @@ -0,0 +1,103 @@ +/* + * 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 +#include +#include + +#include "mousse.h" +#include "m48t59y.h" +#include "pci.h" + + +int checkboard(void) +{ + ulong busfreq = get_bus_freq(0); + char buf[32]; + + printf("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; +} + + +/* + * Initialize PCI Devices, report devices found. + */ +int pci_init(void) +{ + pci_dev_init(0); + return 0; +} diff --git a/board/mousse/mousse.h b/board/mousse/mousse.h new file mode 100644 index 0000000..c826449 --- /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_PPCBOOT 0x0800 /* 2048 PPCBoot boot-loader */ +#define NV_OFF_PPCBOOT_ADDR (TOD_BASE + NV_OFF_PPCBOOT) /* sysaddr*/ +#define NV_PPCBOOT_ENV_SIZE 2048 /* 2K - PPCBoot Total */ +#define NV_OFF__next_free (NV_PPCBOOT_ENVSIZE +1) +#define NV_RAM_SIZE 8176 /* NVRAM End */ + +#endif /* __MOUSSE_H */ diff --git a/board/mousse/ns16550.c b/board/mousse/ns16550.c new file mode 100644 index 0000000..6f3ed70 --- /dev/null +++ b/board/mousse/ns16550.c @@ -0,0 +1,310 @@ +/* + * (C) Copyright 2001 + * 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 + */ +/* + * COM1 NS16550 support for the MOUSSE Processor card. + */ +#include +#include "ns16550.h" +#include "mousse.h" + +#define NS16550_FIFO + +#define UART ((void *) 0xffe08080) /* COM1 */ +#define NS16550_CLOCK_SPEED (115200 * 16 * 10) + +/* + * Baud rate conversation table for 16550 + */ +static const +ns16550_baud_rate_table speed_table[] = { + { B50, (unsigned short) (NS16550_CLOCK_SPEED/(16*B50)) }, + { B75, (unsigned short) (NS16550_CLOCK_SPEED/(16*B75)) }, + { B110, (unsigned short) (NS16550_CLOCK_SPEED/(16*B110)) }, + { B150, (unsigned short) (NS16550_CLOCK_SPEED/(16*B150)) }, + { B300, (unsigned short) (NS16550_CLOCK_SPEED/(16*B300)) }, + { B600, (unsigned short) (NS16550_CLOCK_SPEED/(16*B600)) }, + { B1200, (unsigned short) (NS16550_CLOCK_SPEED/(16*B1200)) }, + { B1800, (unsigned short) (NS16550_CLOCK_SPEED/(16*B1800)) }, + { B2000, (unsigned short) (NS16550_CLOCK_SPEED/(16*B2000)) }, + { B2400, (unsigned short) (NS16550_CLOCK_SPEED/(16*B2400)) }, + { B3600, (unsigned short) (NS16550_CLOCK_SPEED/(16*B3600)) }, + { B4800, (unsigned short) (NS16550_CLOCK_SPEED/(16*B4800)) }, + { B7200, (unsigned short) (NS16550_CLOCK_SPEED/(16*B7200)) }, + { B9600, (unsigned short) (NS16550_CLOCK_SPEED/(16*B9600)) }, + { B14400, (unsigned short) (NS16550_CLOCK_SPEED/(16*B14400)) }, + { B19200, (unsigned short) (NS16550_CLOCK_SPEED/(16*B19200)) }, + { B28800, (unsigned short) (NS16550_CLOCK_SPEED/(16*B28800)) }, + { B38400, (unsigned short) (NS16550_CLOCK_SPEED/(16*B38400)) }, + { B56000, (unsigned short) (NS16550_CLOCK_SPEED/(16*B56000)) }, + { B57600, (unsigned short) (NS16550_CLOCK_SPEED/(16*B57600)) }, + { B115200, (unsigned short) (NS16550_CLOCK_SPEED/(16*B115200)) }, + { B128000, (unsigned short) (NS16550_CLOCK_SPEED/(16*B128000)) }, + { 0 ,0 }, +}; + +static void set_speed (unsigned int code) +{ + unsigned char scratch_pad; + volatile ns16550_uart *uart = UART; + + scratch_pad = uart->LCR; + uart->LCR = LCR_DLAB | scratch_pad; + uart->DLL = (unsigned char) (code & 0xff); + uart->DLM = (code >> 8); + uart->LCR = scratch_pad; + + return; +} + +static unsigned short get_speed (void) +{ + volatile ns16550_uart *uart = UART; + unsigned int code; + code = uart->DLL; + return (uart->DLL | (uart->DLM << 8)); +} + +/* + * Given the baud rate, convert the baud rate to a value, that has + * to be loaded into the DLL and DLM register. The caller, can set the + * baud rate once the DLAB bit has been set high, by writing the value + * returned into the DLL and DLM latches. + * + * Returns: + * - a 0, if the baudrate is not one of the known baudrates. + * - a positive number, which can be loaded into the Divisor latch register + * for setting the baudrate. + */ + +static unsigned short +ns16550_baud2code (unsigned int baudrate) +{ + int count = 0; + + for (count = 0; speed_table[count].baudrate > 0; count++) { + if (speed_table[count].baudrate == baudrate) { + return (speed_table[count].value); + } + } + return (0); /* baudrate not found in table */ +} + +static unsigned short +ns16550_code2baud (unsigned int code) +{ + int count = 0; + + for (count = 0; speed_table[count].baudrate > 0; count++) { + if (speed_table[count].value == code) { + return (speed_table[count].baudrate); + } + } + return (0); /* baudrate not found in table */ +} + +/* + * + * This routine will initialize the UART to a known state of speed,stopbits + * etc., + * + * Things to do in this routine : + * ----------------------------- + * + * 2. Reset the TX and RX FIFO's. + * 3. Set default speed. + * 4. Set the data 8 bits / character. + * 5. Set the parity to nothing. + * 6. Set the number of stop bits to 2. + * 7. Set the receive trigger level. + * 8. Enable the Rx and Tx FIFO's. + * 9. Raise the DTR. + * 10. Set the interrupt for Rx, LSR and MSR. Transmit holding register empty + * is generated as and when necessary. + * + * NOTE : The interrupt hadnler must be set in the calling routine for the + * UART ports. + * + */ +void +ns16550_init (int baud) +{ + volatile ns16550_uart *uart = UART; + unsigned char scratch_pad; + + /* Disable all interrupts before setting the interrupt handler. */ + scratch_pad = 0; + uart->IER = scratch_pad; + + /* Clear the FIFO's, set speed to 9600 baud */ + uart->FCR = (FCR_RX_CLR | FCR_TX_CLR); + ns16550_setspeed(baud); + /* + * Set the data bits, stop bits and parity. By Default 8 data bits/char, + * 2 stop bits and no parity. + */ + uart->LCR = ((LCR_8BITS | LCR_2_SB) & ~LCR_PARITY_ENABLE); + +#ifdef NS16550_FIFO + /* + * For now set the trigger level to 14. This we might have to change + * after some initial testing. + */ + uart->FCR = (TRIGGER_ON_14 | FCR_ENABLE | FCR_DMA_MODE); +#endif + + /* + * Raise the DTR & DTR in case of AUX/Console port. + */ + uart->MCR = (MCR_DTR | MCR_RTS); + scratch_pad = uart->IIR; + scratch_pad = uart->MSR; + + scratch_pad = IER_ENABLE_RX_DATA | + IER_ENABLE_RX_LSR | + IER_ENABLE_MODEM_STAT; + uart->IER = scratch_pad; +} + +/* + * Set the speed on the UART. Return the new speed, or zero if one + * cannot be set. If zero is passed in, do not change the speed, + * just return the current speed. + */ +int +ns16550_setspeed (int speed) +{ + int code; + + if (!speed) { + return (ns16550_code2baud (get_speed ())); + } + + /* + * Translate speeds to codes. Change baud rates if codes are good + * and are different from what we were already running with: + */ + code = ns16550_baud2code(speed); + if (!code) { /* Unknown speed being set */ + return(0); + } + + set_speed (code); + + return (speed); +} + +/* + * Read a byte from the console. + */ +int +ns16550_getc (void) +{ + unsigned char ch; + char lsr_stat; + volatile ns16550_uart *uart = UART; + + lsr_stat = uart->LSR; + while ((lsr_stat & LSR_DATAREADY) == 0) { + lsr_stat = uart->LSR; /* Loop for a character */ + } + + ch = uart->RxBuf; /* Get the character */ + + return(ch); +} + + +int +ns16550_tstc(void) +{ + volatile ns16550_uart *uart = UART; + return ((uart->LSR & LSR_DATAREADY) != 0); +} + +/* + * + * Write a byte to the console. + * + */ +unsigned char +ns16550_putc (unsigned char ch) +{ + volatile ns16550_uart *uart = UART; + unsigned char lsr_stat; + + lsr_stat = uart->LSR; + while (((lsr_stat & LSR_THRE) == 0) || ((lsr_stat & LSR_TEMT) == 0)) { + lsr_stat = uart->LSR; /* Wait for transmitter ready */ + } + + uart->TxBuf = ch; /* Store the character */ + return (ch); +} + +/* + * Return TRUE if a break has been recieved, else return FALSE. + * + */ +int +ns16550_check_char (void) +{ + volatile ns16550_uart *uart = UART; + + if (uart->LSR & LSR_DATAREADY) { + return 1; + } + + return 0; +} + +/* + * Return TRUE if a break has been recieved, else return FALSE. + * + */ +int +ns16550_check_break (void) +{ + volatile ns16550_uart *uart = UART; + static int break_recvd = 0; + volatile int i; + + if (uart->LSR & LSR_BREAK_INTR) { + while (uart->LSR & LSR_DATAREADY) { + i = uart->RxBuf; + } + break_recvd = 1; + return 1; + } + + if (break_recvd) { + while (uart->LSR & LSR_DATAREADY) { + i = uart->RxBuf; + } + break_recvd = 0; + } + + return 0; +} diff --git a/board/mousse/ns16550.h b/board/mousse/ns16550.h new file mode 100644 index 0000000..e72b61a --- /dev/null +++ b/board/mousse/ns16550.h @@ -0,0 +1,243 @@ +/* + * (C) Copyright 2001 + * 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 __NS16552_H +#define __NS16552_H + +/* + * NS16552D Serial Port + */ + +typedef struct ns16550_uart_ { + +/* + * The register is selected by + * 1. If the DLAB bit is set to 1, then the Divisor_Latch_LSB will be active. + * 2. If the DLAB bit is reset, then + * a. A read is performed from the Rx_Buffer_Register. + * b. A write to is performed on the Tx_Holding_Register. + */ + union + { + volatile unsigned char Rx_Buffer; /* Rx buffer ready reg RD only */ + volatile unsigned char Tx_Holding; /* Tx holding register WR only */ + volatile unsigned char DLL; /* Divisor latch LS Byte */ + } RBS_THR_DLAB1; +#define RxBuf RBS_THR_DLAB1.Rx_Buffer +#define TxBuf RBS_THR_DLAB1.Tx_Holding +#define DLL RBS_THR_DLAB1.DLL +/* + * The register is selected by + * + * If the DLAB bit is set to 1, then the Divisor_Latch_LSB will be active, else + * Interrupt enable register is active. + */ + union + { + volatile unsigned char DLM; /* Divisor latch MS Byte */ + volatile unsigned char IER; /* Intr. enable register */ + } IER_DLAB2; +#define DLM IER_DLAB2.DLM +#define IER IER_DLAB2.IER + +/* + * If the DLAB bit is 1, then Alternate function register is selected. + * If the DLAB bit is 0, then + * 1. A read is always performed from the Interrupt Indentification register. + * 2. A write is always performed on the FIFO control register. + */ + union{ + volatile unsigned char IIR; /* Intr. identification RD */ + volatile unsigned char FCR; /* FIFO control WR only */ + volatile unsigned char AFR; /* When DLAB is 1 */ + } IIR_FCR_AFR; +#define IIR IIR_FCR_AFR.IIR +#define FCR IIR_FCR_AFR.FCR +#define AFR IIR_FCR_AFR.AFR + volatile unsigned char LCR; /* Line Control register */ + volatile unsigned char MCR; /* Modem Control register */ + volatile unsigned char LSR; /* Line Status register */ + volatile unsigned char MSR; /* Modem Status register */ + volatile unsigned char SR; /* Scratch pad register */ +} ns16550_uart; + + + +/* NSC 16550 Interrupt Enable register definitions */ +#define IER_ENABLE_RX_DATA 0x01 /* Enable Recevied Data available intr*/ +#define IER_ENABLE_THRE 0x02 /* Enable Tx holding reg empty intr */ +#define IER_ENABLE_RX_LSR 0x04 /* Enable receiver Line status intr */ +#define IER_ENABLE_MODEM_STAT 0x08 /* Enable receiver Modem status intr*/ + +/* NSC 16550 Interrupt Identification register bit settings */ +#define IIR_MSTAT 0x00 /* Modem changed status indication */ +#define IIR_NOPENDING_INTR 0x01 /* Interrupt not pending, indication */ +#define IIR_THRE 0x02 /* Tx holding reg empty indication */ +#define IIR_CHAR_TIMEOUT 0x0c /* Character timeout indication */ +#define IIR_RX_DATA_AVAIL 0x04 /* Received data available indication */ +#define IIR_RLS 0x06 /* Receiver line status (either OE, PE, + FE or BI received) */ + +/* NSC 16550 FIFO Control register bit settings */ +#define FCR_ENABLE 0x01 /* Rx and Tx FIFO's enabler */ +#define FCR_RX_CLR 0x02 /* Clear the Rx FIFO and set offset to 0 */ +#define FCR_TX_CLR 0x04 /* Clear the Rx FIFO and set offset to 0 */ +#define FCR_DMA_MODE 0x08 /* Will enable DMA transfers for Rx and Tx */ + +/* + * Receiver FIFO trigger level, is the number characters needed to be in the + * FIFO, before an interrupt is generated. Bits ( 7 & 8 ) of the above + * register. + */ +#define TRIGGER_ON_1 0x00 /* Trigger after receiving 1 byte */ +#define TRIGGER_ON_4 0x01 /* Trigger after receiving 4 byte */ +#define TRIGGER_ON_8 0x02 /* Trigger after receiving 8 byte */ +#define TRIGGER_ON_14 0x03 /* Trigger after receiving 14 byte */ +#define FIFO_COUNT 16 /* 16 byte deep FIFO */ + +/* NSC 16550 Line control register bit settings */ +/* + * Bits + * 0 1 - Character length + * 2 - Stops bit length (used along with the bits 0 & 1) + * 3 - Parity enable bit + * 4 - Even parity select bit (only active when parity is enabled. + * = 0, Odd parity + * = 1, Even Parity + * 5 - Sticky bit parity. + * 6 - Break control bit, causes break condition to be transmitted + * 7 - Divisor latch access bit for setting the baud rate divisor + */ +#define LCR_5BITS 0x00 /* Character length is 5 bits */ +#define LCR_6BITS 0x01 /* Character length is 6 bits */ +#define LCR_7BITS 0x02 /* Character length is 7 bits */ +#define LCR_8BITS 0x03 /* Character length is 8 bits */ +#define LCR_1_SB 0x00 /* Bit 2 should be 0, for 1 stop bit */ +#define LCR_15_SB 0x04 /* Bit 2 should be 1 and LCR_5BITS + must be selected for 1.5 bits */ +#define LCR_2_SB 0x04 /* When character length is 6,7 or 8 */ +#define LCR_PARITY_ENABLE 0x08 /* Enable parity on Rx and Tx */ +#define LCR_EVEN_PARITY 0x10 /* When parity enabled */ +#define LCR_STICKY_PARITY 0x20 /* Sticky parity enable */ +#define LCR_BREAK_CTRL 0x40 /* Break control bit */ +#define LCR_DLAB 0x80 /* Divisor latch access bit */ + +/* NSC 16550 Modem Control register bit definitions */ +#define MCR_DTR 0x01 /* Data terminal ready */ +#define MCR_RTS 0x02 /* Request to send */ +#define MCR_OUT1 0x04 /* Out1 */ +#define MCR_OUT2 0x08 /* Out1 */ +#define MCR_LOOP 0x10 /* Set loop mode */ + +/* NSC 16550 Line status register bit definitions */ +#define LSR_DATAREADY 0x01 /* Data ready */ +#define LSR_OVERRUN_ERR 0x02 /* Overrun Error */ +#define LSR_PARITY_ERR 0x04 /* Parity Error */ +#define LSR_FRAME_ERR 0x08 /* Framing Error */ +#define LSR_BREAK_INTR 0x10 /* Break Interrupt */ +#define LSR_THRE 0x20 /* Transmit holding register empty */ +#define LSR_TEMT 0x40 /* Transmiter empty */ +#define LSR_RX_FIFO_ERR 0x80 /* Error on Receiver FIFO */ + +/* NSC 16550 Modem status register bit definitions */ +#define MSR_DELTA_CTS 0x01 /* Delta CTS */ +#define MSR_DELTA_DSR 0x02 /* Delta DSR */ +#define MSR_TERI 0x04 /* Trailing Edge ring indicator */ +#define MSR_DELTA_DCD 0x08 /* Delta DCD */ +#define MSR_CTS 0x10 /* CTS */ +#define MSR_DSR 0x20 /* DSR */ +#define MSR_RI 0x40 /* RI */ +#define MSR_DCD 0x80 /* DCD */ + +#define HIGH_WATER_MARK 1664 /* High water mark, at which the h/w flow control + will take affect */ + +/* Baud Rate settings */ +/* + * This particular chip can set the baud rate by writing to the Divisor latch. + * This divisor latch is a 16 bit latch and can be written only when DLAB bit + * is set. The baud rate depends on the input clock frequency. + * + * To calculate the number to be loaded into the latch use the following + * formula + * + * Divisor # = (Clock Freq) / (16 * Speed in bauds). + * Eg. On a 18.432 MHz to get a baud rate of 115.2kbps ... + * Divisor # = (18432000)/(115200*16) + * Divisor # = 10 + * + * NOTE: If the clock frequency is changed new values for these variables have + * to be calculated. + */ + +#define B50 50 +#define B75 75 +#define B110 110 +#define B150 150 +#define B300 300 +#define B600 600 +#define B1200 1200 +#define B1800 1800 +#define B2000 2000 +#define B2400 2400 +#define B3600 3600 +#define B4800 4800 +#define B7200 7200 +#define B9600 9600 +#define B14400 14400 +#define B19200 19200 +#define B28800 28800 +#define B38400 38400 +#define B56000 56000 +#define B57600 57600 +#define B115200 115200 +#define B128000 128000 +/* + * Possible only with a 24 MHz crystal clock input. + */ +#define B250k 250000 +#define B300k 300000 +#define B375k 375000 +#define B500k 500000 +#define B750k 750000 +#define B1500k 1500000 + +typedef struct ns16550_baud_rate_table_ { + int baudrate; + unsigned short value; +} ns16550_baud_rate_table; + + +int ns16550_check_break (void); +int ns16550_check_char (void); +unsigned char ns16550_putc (unsigned char ch); +int ns16550_getc (void); +int ns16550_setspeed (int speed); +void ns16550_init (int baud); +int ns16550_tstc(void); + + +#endif /* __NS16552_H */ diff --git a/board/mousse/pci.c b/board/mousse/pci.c new file mode 100644 index 0000000..7b3af19 --- /dev/null +++ b/board/mousse/pci.c @@ -0,0 +1,851 @@ +/* + * + * (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 MPC8240/MPC107 PCI Bridge + */ +#include +#include "mpc8240.h" +#include "pci.h" +#include "mousse.h" + +int numPciBus = 1; /* One bus: MPC107 Internal bridge */ + +/* + * + * pci_dev_find - find the nth device with the given device & vendor ID + * + */ +int pci_dev_find(int vendorId, /* vendor ID */ + int deviceId, /* device ID */ + int index, /* desired instance of device */ + int* pBusNo, /* bus number */ + int* pDeviceNo, /* device number */ + int* pFuncNo) /* function number */ +{ + int status = ERROR; + int cont = TRUE; + int busNo; + int deviceNo; + int funcNo; + uint32 device; + uint32 vendor; + char header; + + for (busNo = 0; cont == TRUE && busNo <= numPciBus; busNo++) + for (deviceNo = 0; + ((cont == TRUE) && (deviceNo < PCI_MAX_DEV)); + ++deviceNo) + for (funcNo = 0; cont == TRUE && funcNo < PCI_MAX_FUNC; funcNo++){ + /* avoid a special bus cycle */ + + if ((deviceNo == 0x1f) && (funcNo == 0x07)) + continue; + + pci_config_inl (busNo, deviceNo, funcNo, PCI_CFG_VENDOR_ID, + &vendor); + + /* + * If nonexistent device, skip to next, only look at + * vendor ID field for existence check + */ + if (((vendor & 0x0000ffff) == 0x0000FFFF) && (funcNo == 0)) + break; + device = vendor >> 16; + device &= 0x0000FFFF; + vendor &= 0x0000FFFF; + if ((vendor == (uint32)vendorId) && + (device == (uint32)deviceId) && + (index-- == 0)){ + *pBusNo = busNo; + *pDeviceNo = deviceNo; + *pFuncNo = funcNo; + status = OK; + cont = FALSE; /* terminate all loops */ + continue; + } + + /* goto next if current device is single function */ + + pci_config_inb (busNo, deviceNo, funcNo, PCI_CFG_HEADER_TYPE, + &header); + if ((header & PCI_HEADER_MULTI_FUNC) != + PCI_HEADER_MULTI_FUNC && funcNo == 0) + break; + } + + return status; +} + +/* + * + * pci_class_find - find the nth occurence of a device by PCI class code. + * + * RETURNS: + * OK, or ERROR if the class didn't match. + */ + +int pci_class_find(int classCode, /* 24-bit class code */ + int index, /* desired instance of device */ + int * pBusNo, /* bus number */ + int * pDeviceNo, /* device number */ + int * pFuncNo) /* function number */ +{ + int status = ERROR; + int cont = TRUE; + int busNo; + int deviceNo; + int funcNo; + int classCodeReg; + int vendor; + char header; + + + for (busNo = 0; cont == TRUE && busNo <= numPciBus; busNo++) + for (deviceNo = 0; + ((cont == TRUE) && (deviceNo < PCI_MAX_DEV)); + ++deviceNo) + for (funcNo = 0; cont == TRUE && funcNo < PCI_MAX_FUNC; funcNo++){ + + /* avoid a special bus cycle */ + if ((deviceNo == 0x1f) && (funcNo == 0x07)) + continue; + + pci_config_inl (busNo, deviceNo, funcNo, PCI_CFG_VENDOR_ID, + &vendor); + + /* + * If nonexistent device, skip to next, only look at + * vendor ID field for existence check + */ + if (((vendor & 0x0000ffff) == 0x0000FFFF) && (funcNo == 0)) + break; + + pci_config_inl (busNo, deviceNo, funcNo, PCI_CFG_REVISION, + &classCodeReg); + + if ((((classCodeReg >> 8) & 0x00ffffff) == classCode) && + (index-- == 0)) + { + *pBusNo = busNo; + *pDeviceNo = deviceNo; + *pFuncNo = funcNo; + status = OK; + cont = FALSE; /* terminate all loops */ + continue; + } + + /* goto next if current device is single function */ + + pci_config_inb (busNo, deviceNo, funcNo, PCI_CFG_HEADER_TYPE, + &header); + if ((header & PCI_HEADER_MULTI_FUNC) != + PCI_HEADER_MULTI_FUNC && funcNo == 0) + break; + } + return status; +} + + +/* + * + * pci_dev_config - configure a device on a PCI bus + * + * This routine configures a device that is on a Peripheral Component + * Interconnect (PCI) bus by writing to the configuration header of the + * selected device. + * + * It first disables the device by clearing the command register in the + * configuration header. It then sets the I/O and/or memory space base + * address registers, the latency timer value and the cache line size. + * Finally, it re-enables the device by loading the command register with + * the specified command. + * + * NOTE: This routine is designed for Type 0 PCI Configuration Headers ONLY. + * It is NOT usable for configuring, for example, a PCI-to-PCI bridge. + * + * RETURNS: OK always. + */ +int pci_dev_config(int pciBusNo, /* PCI bus number */ + int pciDevNo, /* PCI device number */ + int pciFuncNo, /* PCI function number */ + uint32 devIoBaseAdrs, /* device IO base address */ + uint32 devMemBaseAdrs, /* device memory base address */ + uint32 command) /* command to issue */ +{ + int ix; + uint32 tmp32; + + /* + * Disable device by clearing its command register field in its + * configuration header. Write 0 clears command and preserves status. + */ + pci_config_outl (pciBusNo, pciDevNo, pciFuncNo, PCI_CFG_COMMAND, 0x0); + + for (ix = PCI_CFG_BASE_ADDRESS_0; ix <= PCI_CFG_BASE_ADDRESS_5; ix+=4){ + + /* Write all f's and read back value */ + pci_config_outl (pciBusNo, pciDevNo, pciFuncNo, ix, 0xffffffff); + pci_config_inl (pciBusNo, pciDevNo, pciFuncNo, ix, &tmp32); + + if (tmp32 == 0){ + /* No bar */ + break; + } + + /* I/O space requested */ + if (tmp32 & 0x1){ + pci_config_outl (pciBusNo, pciDevNo, pciFuncNo, ix, + devIoBaseAdrs | 0x1); + } else{ + /* Memory space required, set specified base address */ + pci_config_outl (pciBusNo, pciDevNo, pciFuncNo, ix, + devMemBaseAdrs & ~0x1); + } + } + + /* Configure Cache Line Size Register */ + pci_config_outb (pciBusNo, pciDevNo, pciFuncNo, + PCI_CFG_CACHE_LINE_SIZE, + PCI_CACHE_LINE_SIZE); + + /* Configure Latency Timer */ + pci_config_outb (pciBusNo, pciDevNo, pciFuncNo, + PCI_CFG_LATENCY_TIMER, + PCI_LATENCY_TIMER); + + /* + * Enable the device's capabilities as specified, do not + * reset any status bits in doing so. + */ + pci_config_modl (pciBusNo, pciDevNo, pciFuncNo, + PCI_CFG_COMMAND, + (PCI_CMD_MASK | command), command); + + return OK; +} + + +/* + * + * pci_config_bdf_pack - pack parameters for the Configuration Address Register + * + * This routine packs three parameters into one integer for accessing the + * Configuration Address Register + * + */ + +int pci_config_bdf_pack(int busNo, /* bus number */ + int deviceNo, /* device number */ + int funcNo) /* function number */ +{ + return (((busNo << 16) & 0x00ff0000) | + ((deviceNo << 11) & 0x0000f800) | + ((funcNo << 8) & 0x00000700)); +} + +/* + * pci_config_inb - read one byte from the PCI configuration space + * + * This routine reads one byte from the PCI configuration space + * + */ +int pci_config_inb(int busNo, /* bus number */ + int deviceNo, /* device number */ + int funcNo, /* function number */ + int offset, /* offset into config space */ + uint8 * pData) /* data read from the offset */ +{ + uint8 retval = 0; + int retStat = ERROR; + + mpc8240_mpc107_write32 (CHRP_REG_ADDR, + pci_config_bdf_pack (busNo, deviceNo, funcNo) | + (offset & 0xfc) | 0x80000000); + retval = mpc8240_mpc107_read8 (CHRP_REG_DATA + (offset & 0x3)); + retStat = OK; + + *pData = retval; + + return retStat; +} + +/* + * + * pci_config_inw - read one word from the PCI configuration space + * + * This routine reads one word from the PCI configuration space + * + */ +int pci_config_inw(int busNo, /* bus number */ + int deviceNo, /* device number */ + int funcNo, /* function number */ + int offset, /* offset into config space */ + uint16 * pData) /* data read from the offset */ +{ + int retStat = ERROR; + uint16 retval = 0; + + if (((offset & (int)0x1) > 0) ) { + return (retStat); + } + + mpc8240_mpc107_write32 (CHRP_REG_ADDR, + pci_config_bdf_pack (busNo, deviceNo, funcNo) | + (offset & 0xfc) | 0x80000000); + retval = mpc8240_mpc107_read16 (CHRP_REG_DATA + (offset & 0x2)); + retStat = OK; + *pData = retval; + + return retStat; +} + +/* + * + * pci_config_inl - read one longword from the PCI configuration space + * + * This routine reads one longword from the PCI configuration space + * + */ +int pci_config_inl(int busNo, /* bus number */ + int deviceNo, /* device number */ + int funcNo, /* function number */ + int offset, /* offset into config space */ + uint32 * pData) /* data read from the offset */ +{ + int retStat = ERROR; + uint32 retval = 0; + + if (((offset & (int)0x3) > 0) ) { + return (retStat); + } + mpc8240_mpc107_write32 (CHRP_REG_ADDR, + pci_config_bdf_pack (busNo, deviceNo, funcNo) | + (offset & 0xfc) | 0x80000000); + retval = mpc8240_mpc107_read32 (CHRP_REG_DATA); + asm volatile ("eieio"); + retStat = OK; + *pData = retval; + return retStat; +} + +/* + * pci_config_outb - write one byte to the PCI configuration space + * + * This routine writes one byte to the PCI configuration space. + * + */ +int pci_config_outb(int busNo, /* bus number */ + int deviceNo, /* device number */ + int funcNo, /* function number */ + int offset, /* offset into config space */ + uint8 data) /* data written to the offset */ +{ + + mpc8240_mpc107_write32 (CHRP_REG_ADDR, + pci_config_bdf_pack (busNo, deviceNo, funcNo) | + (offset & 0xfc) | 0x80000000); + mpc8240_mpc107_write8 ((CHRP_REG_DATA + (offset & 0x3)), data); + return OK; +} + +/* + * pci_config_outw - write one 16-bit word to the PCI configuration space + * + * This routine writes one 16-bit word to the PCI configuration space. + * + * RETURNS: OK, or ERROR if this library is not initialized + */ +int pci_config_outw(int busNo, /* bus number */ + int deviceNo, /* device number */ + int funcNo, /* function number */ + int offset, /* offset into config space */ + uint16 data) /* data written to the offset */ +{ + if (((offset & (int)0x1) > 0) ){ + return (ERROR); + } + + mpc8240_mpc107_write32 (CHRP_REG_ADDR, + pci_config_bdf_pack (busNo, deviceNo, funcNo) | + (offset & 0xfc) | 0x80000000); + mpc8240_mpc107_write16 ((CHRP_REG_DATA + (offset & 0x2)), data); + return OK; +} + + +/* + * + * pci_config_outl - write one longword to the PCI configuration space + * + * This routine writes one longword to the PCI configuration space. + * + */ +int pci_config_outl(int busNo, /* bus number */ + int deviceNo, /* device number */ + int funcNo, /* function number */ + int offset, /* offset into config space */ + uint32 data) /* data written to the offset */ +{ + if (((offset & (int)0x3) > 0) ){ + return (ERROR); + } + mpc8240_mpc107_write32 (CHRP_REG_ADDR, + pci_config_bdf_pack (busNo, deviceNo, funcNo) | + (offset & 0xfc) | 0x80000000); + mpc8240_mpc107_write32 (CHRP_REG_DATA, data); + asm volatile ("eieio"); + return OK; +} + + +/* + * + * pci_config_modl - Perform a masked longword register update + * + * This function writes a field into a PCI configuration header without + * altering any bits not present in the field. It does this by first + * doing a PCI configuration read (into a temporary location) of the PCI + * configuration header word which contains the field to be altered. + * It then alters the bits in the temporary location to match the desired + * value of the field. It then writes back the temporary location with + * a configuration write. All configuration accesses are long and the + * field to alter is specified by the "1" bits in the 'bitMask' parameter. + * + */ + +int pci_config_modl(int busNo, /* bus number */ + int deviceNo, /* device number */ + int funcNo, /* function number */ + int offset, /* offset into config space */ + uint32 bitMask, /* Mask of bits to alter */ + uint32 data) /* data written to the offset */ + +{ + uint32 temp; + int stat; + + if (((offset & (int)0x3) > 0) ){ + return (ERROR); + } + + stat = pci_config_inl (busNo, deviceNo, funcNo, offset, &temp); + if (stat == OK){ + temp = (temp & ~bitMask) | (data & bitMask); + stat = pci_config_outl (busNo, deviceNo, funcNo, offset, temp); + } + return stat; +} + + +/* + * + * pci_config_modw - Perform a masked short register update + * + */ +int pci_config_modw(int busNo, /* bus number */ + int deviceNo, /* device number */ + int funcNo, /* function number */ + int offset, /* offset into config space */ + uint16 bitMask, /* Mask of bits to alter */ + uint16 data) /* data written to the offset */ +{ + uint16 temp; + int stat; + if (((offset & (int)0x1) > 0) ){ + return (ERROR); + } + stat = pci_config_inw (busNo, deviceNo, funcNo, offset, &temp); + if (stat == OK){ + temp = (temp & ~bitMask) | (data & bitMask); + stat = pci_config_outw (busNo, deviceNo, funcNo, offset, temp); + } + return stat; +} + + + +/* + * pci_config_modb - Perform a masked byte register update + * + */ +int pci_config_modb(int busNo, /* bus number */ + int deviceNo, /* device number */ + int funcNo, /* function number */ + int offset, /* offset into config space */ + uint8 bitMask, /* Mask of bits to alter */ + uint8 data) /* data written to the offset */ +{ + uint8 temp; + int stat; + stat = pci_config_inb (busNo, deviceNo, funcNo, offset, &temp); + if (stat == OK){ + temp = (temp & ~bitMask) | (data & bitMask); + stat = pci_config_outb (busNo, deviceNo, funcNo, offset, temp); + } + return stat; +} + +/* + * pci_special_cycle - generate a special cycle with a message + */ +int +pci_special_cycle(int busNo, /* bus number */ + uint32 message) /* data driven onto AD[31:0] */ +{ + int deviceNo = 0x0000001f; + int funcNo = 0x00000007; + + mpc8240_mpc107_write32 (CHRP_REG_ADDR, + pci_config_bdf_pack (busNo, deviceNo, funcNo) | + 0x80000000); + mpc8240_mpc107_write32 (CHRP_REG_DATA, message); + return OK; +} + + +/* + * Find the extent of a PCI decode.. + */ +unsigned int +pci_size_bar(unsigned int base, unsigned long mask) +{ + uint32 size = mask & base; /* Find the significant bits */ + size = size & ~(size-1); /* Get the lowest of them to find the decode size */ + return size-1; /* extent = size - 1 */ +} + + +/* + * 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 (int bus, int dev, int func, + int drive, unsigned char speed) +{ + unsigned short drive_conf; + int err; + 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_config_inw(bus,dev,func, drive_pci, &drive_conf); + pci_config_inb(bus,dev,func, (drive_pci), &AP); + pci_config_inb(bus,dev,func, (drive_pci)|0x01, &BP); + pci_config_inb(bus,dev,func, (drive_pci)|0x02, &CP); + pci_config_inb(bus,dev,func, (drive_pci)|0x03, &DP); + + if ((AP & 0x0F) || (BP & 0x07)) { + /* clear PIO modes of lower 8421 bits of A Register */ + pci_config_outb(bus,dev,func, (drive_pci), AP & ~0x0F); + pci_config_inb(bus,dev,func, (drive_pci), &AP); + + /* clear PIO modes of lower 421 bits of B Register */ + pci_config_outb(bus,dev,func, (drive_pci)|0x01, BP & ~0x07); + pci_config_inb(bus,dev,func, (drive_pci)|0x01, &BP); + + pci_config_inb(bus,dev,func, (drive_pci), &AP); + pci_config_inb(bus,dev,func, (drive_pci)|0x01, &BP); + } + + pci_config_inb(bus,dev,func, (drive_pci), &AP); + pci_config_inb(bus,dev,func, (drive_pci)|0x01, &BP); + pci_config_inb(bus,dev,func, (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_config_outb(bus,dev,func, (drive_pci), AP|TA); + pci_config_outb(bus,dev,func, (drive_pci)|0x01, BP|TB); + + pci_config_inb(bus,dev,func, (drive_pci), &AP); + pci_config_inb(bus,dev,func, (drive_pci)|0x01, &BP); + pci_config_inb(bus,dev,func, (drive_pci)|0x02, &CP); + pci_config_inb(bus,dev,func, (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. + */ +int pci_dev_init(int busNo) +{ + int deviceNo, a; + uint32 cmd, bar; + int devices; + uint16 vendorId; + uint16 deviceId; + uint32 mbar0; + uint32 mbar1; + uint32 revId; + uint32 iline,ipin; + + union { + int classCode; + char array[4]; + } u; + + printf("PCI: scanning bus%d ...\n", busNo); + printf(" bus dev fn venID devID class" + " rev MBAR0 MBAR1 IPIN ILINE\n"); + + devices = 0x1f; + for (deviceNo=0; deviceNo < devices; deviceNo++) { + + /* Get device and vendor ID */ + pci_config_inw (busNo, deviceNo, 0, PCI_CFG_VENDOR_ID, &vendorId); + pci_config_inw (busNo, deviceNo, 0, PCI_CFG_DEVICE_ID, &deviceId); + + /* MPC107 Bridge */ + if( deviceNo == 0x0){ + /* Don't do anything */ + } + + /* Make sure IRQ's on PCI devices get configured correctly */ + if( deviceNo == 0x0d){ + /* Onboard */ + pci_dev_config(busNo, deviceNo, 0, + PCI_ENET_IOADDR, + PCI_ENET_MEMADDR, + PCI_CMD_MEM_ENABLE | + PCI_CMD_MEM_ENABLE | + PCI_CMD_MASTER_ENABLE); + /* DEC get's IRQ=1 */ + pci_config_outl(busNo, deviceNo, 0, PCI_CFG_DEV_INT_LINE, 0x00000101); + } /* PCI Slot */ + else if (deviceNo == 0x0e){ + + if(vendorId == PCI_VENDOR_ID_PROMISE|| + vendorId == 0x1095){ + /* 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_config_inl(busNo, deviceNo, 0, + PCI_CFG_BASE_ADDRESS_0+bar*4, + &mbar0); + pci_config_outl(busNo, deviceNo, 0, + PCI_CFG_BASE_ADDRESS_0+bar*4, + ~0); + pci_config_inl(busNo, deviceNo, 0, + PCI_CFG_BASE_ADDRESS_0+bar*4, + &mbar0); + /* printf(" ATA_bar[%d] = %dbytes\n", + bar,pci_size(mbar0,PCI_BASE_ADDRESS_MEM_MASK)); */ + } + /* Program all BAR's */ + pci_config_outl(busNo, deviceNo, 0, PCI_CFG_BASE_ADDRESS_0, + PROMISE_MBAR0); + pci_config_outl(busNo, deviceNo, 0, PCI_CFG_BASE_ADDRESS_1, + PROMISE_MBAR1); + pci_config_outl(busNo, deviceNo, 0, PCI_CFG_BASE_ADDRESS_2, + PROMISE_MBAR2); + pci_config_outl(busNo, deviceNo, 0, PCI_CFG_BASE_ADDRESS_3, + PROMISE_MBAR3); + pci_config_outl(busNo, deviceNo, 0, PCI_CFG_BASE_ADDRESS_4, + PROMISE_MBAR4); + pci_config_outl(busNo, deviceNo, 0, PCI_CFG_BASE_ADDRESS_5, + PROMISE_MBAR5); + for(bar = 0; bar < 5; bar++){ + + pci_config_inl(busNo, deviceNo, 0, + PCI_CFG_BASE_ADDRESS_0+bar*4, + &mbar0); + /* printf(" ATA_bar[%d]@0x%x\n", bar,mbar0);*/ + + } + /* Enable ROM Expansion base */ + pci_config_outl(busNo, deviceNo, 0, PCI_CFG_ROM_BASE, + PROMISE_MBAR5|1); + + /* IRQ 3 */ + pci_config_outl(busNo, deviceNo, 0, PCI_CFG_DEV_INT_LINE, + 0x00000303); + + /* Io enable, Memory enable, master enable */ + cmd = PCI_CMD_MASTER_ENABLE | PCI_CMD_MEM_ENABLE|PCI_CMD_IO_ENABLE; + pci_config_modl (busNo, deviceNo, 0, PCI_CFG_COMMAND, + (PCI_CMD_MASK | cmd),cmd); + + /* Breath some life into the controller */ + for( a = 0; a < 4; a++) + pdc202xx_tune_chipset(busNo,deviceNo, 0, a, XFER_PIO_0); + + } else { + /* Other PCI Devices */ + + pci_dev_config(busNo, deviceNo, 0, + PCI_SLOT_IOADDR, + PCI_SLOT_MEMADDR, + PCI_CMD_MEM_ENABLE | + PCI_CMD_MEM_ENABLE | + PCI_CMD_MASTER_ENABLE); + /* PCI slot get's IRQ=3 */ + pci_config_outl(busNo, deviceNo, 0, PCI_CFG_DEV_INT_LINE, 0x00000303); + pci_config_outl(busNo, deviceNo, 0, PCI_LATENCY_TIMER, 127); + } + + + } + + pci_config_inb (busNo, deviceNo, 0, PCI_CFG_PROGRAMMING_IF, + &u.array[3]); + pci_config_inb (busNo, deviceNo, 0, PCI_CFG_SUBCLASS, &u.array[2]); + pci_config_inb (busNo, deviceNo, 0, PCI_CFG_CLASS, &u.array[1]); + u.array[0] = 0; + + pci_config_inl(busNo, deviceNo, 0, PCI_CFG_BASE_ADDRESS_0, &mbar0); + pci_config_inl(busNo, deviceNo, 0, PCI_CFG_BASE_ADDRESS_1, &mbar1); + + pci_config_inl(busNo, deviceNo, 0, PCI_CFG_REVISION, &revId); + revId &= 0x000000ff; + + pci_config_inl(busNo, deviceNo, 0, PCI_CFG_DEV_INT_LINE, &iline); + iline &= 0x000000ff; + + pci_config_inl(busNo, deviceNo, 0, PCI_CFG_DEV_INT_LINE, &ipin); + ipin &= 0x0000ff00; + ipin >>= 8; + + + /* There are two ways to find out an empty device. + * 1. check Master Abort bit after the access. + * 2. check whether the read value is 0xffff. + * Since I didn't see the Master Abort bit of the host/PCI bridge + * changing, I use the second method. + */ + if (vendorId != 0xffff) + + printf(" %02x %02x %02x %04x %04x " + "%06x %02x %08x %08x %02x %02x\n", + busNo, deviceNo, 0, + vendorId, deviceId, u.classCode, revId, + mbar0, mbar1, ipin, iline); + } + return OK; +} + + diff --git a/board/mousse/pci.h b/board/mousse/pci.h new file mode 100644 index 0000000..60f770e --- /dev/null +++ b/board/mousse/pci.h @@ -0,0 +1,302 @@ +/* + * (C) Copyright 2001 + * 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 __MPC8240_PCI +#define __MPC8240_PCI + +/* + * PCI Configuration space Library and constants for MPC8240 based + * systems. + */ + +typedef unsigned char uint8; +typedef unsigned int uint32; +typedef unsigned short uint16; +typedef int INT32; +#define LOCAL static +#define IMPORT extern + +#ifndef NULL +#define NULL 0 +#endif + +#define OK 1 +#define NONE 0 +#define ERROR -1 +#define TRUE 1 +#define FALSE (!TRUE) + + +#define PCI_MAX_BUS 255 +#define PCI_MAX_DEV 32 +#define PCI_MAX_FUNC 8 + + +/* PCI Configuration I/O Addresses */ +#define PCI_CONFIG_ADDR 0x0cf8 /* write 32 bits to set address */ +#define PCI_CONFIG_DATA 0x0cfc /* 8, 16, or 32 bit accesses */ +#define PCI_CONFIG_CSE 0x0cf8 /* CSE register */ +#define PCI_CONFIG_FORWARD 0x0cfa /* forward register */ +#define PCI_CONFIG_BASE 0xc000 /* base register */ + +/* PCI command bits */ +#define PCI_CMD_IO_ENABLE 0x0001 /* IO access enable */ +#define PCI_CMD_MEM_ENABLE 0x0002 /* memory access enable */ +#define PCI_CMD_MASTER_ENABLE 0x0004 /* bus master enable */ +#define PCI_CMD_MON_ENABLE 0x0008 /* monitor special cycles enable */ +#define PCI_CMD_WI_ENABLE 0x0010 /* write and invalidate enable */ +#define PCI_CMD_SNOOP_ENABLE 0x0020 /* palette snoop enable */ +#define PCI_CMD_PERR_ENABLE 0x0040 /* parity error enable */ +#define PCI_CMD_WC_ENABLE 0x0080 /* wait cycle enable */ +#define PCI_CMD_SERR_ENABLE 0x0100 /* system error enable */ +#define PCI_CMD_FBTB_ENABLE 0x0200 /* fast back to back enable */ + +/* PCI base address mask bits */ + +#define PCI_MEMBASE_MASK ~0xf /* mask for memory base address */ +#define PCI_IOBASE_MASK ~0x3 /* mask for IO base address */ +#define PCI_BASE_IO 0x1 /* IO space indicator */ +#define PCI_BASE_BELOW_1M 0x2 /* memory locate below 1MB */ +#define PCI_BASE_IN_64BITS 0x4 /* memory locate anywhere in 64 bits */ +#define PCI_BASE_PREFETCH 0x8 /* memory prefetchable */ + +/* Base Address Register Memory/IO Attribute bits */ + +#define PCI_BAR_SPACE_MASK (0x01) +#define PCI_BAR_SPACE_IO (0x01) +#define PCI_BAR_SPACE_MEM (0x00) + +#define PCI_BAR_MEM_TYPE_MASK (0x06) +#define PCI_BAR_MEM_ADDR32 (0x00) +#define PCI_BAR_MEM_BELOW_1MB (0x02) +#define PCI_BAR_MEM_ADDR64 (0x04) +#define PCI_BAR_MEM_RESERVED (0x06) + +#define PCI_BAR_MEM_PREF_MASK (0x08) +#define PCI_BAR_MEM_PREFETCH (0x08) +#define PCI_BAR_MEM_NON_PREF (0x00) + +#define PCI_BAR_ALL_MASK (PCI_BAR_SPACE_MASK | \ + PCI_BAR_MEM_TYPE_MASK | \ + PCI_BAR_MEM_PREF_MASK) + +/* PCI header type bits */ + +#define PCI_HEADER_TYPE_MASK 0x7f /* mask for header type */ +#define PCI_HEADER_PCI_PCI 0x01 /* PCI to PCI bridge */ +#define PCI_HEADER_TYPE0 0x00 /* normal device header */ +#define PCI_HEADER_MULTI_FUNC 0x80 /* multi function device */ + +/* PCI configuration device and driver */ + +#define SNOOZE_MODE 0x40 /* snooze mode */ +#define SLEEP_MODE_DIS 0x00 /* sleep mode disable */ + +/* Standard device configuration register offsets */ +/* Note that only modulo-4 addresses are written to the address register */ + +#define PCI_CFG_VENDOR_ID 0x00 +#define PCI_CFG_DEVICE_ID 0x02 +#define PCI_CFG_COMMAND 0x04 +#define PCI_CFG_STATUS 0x06 +#define PCI_CFG_REVISION 0x08 +#define PCI_CFG_PROGRAMMING_IF 0x09 +#define PCI_CFG_SUBCLASS 0x0a +#define PCI_CFG_CLASS 0x0b +#define PCI_CFG_CACHE_LINE_SIZE 0x0c +#define PCI_CFG_LATENCY_TIMER 0x0d +#define PCI_CFG_HEADER_TYPE 0x0e +#define PCI_CFG_BIST 0x0f +#define PCI_CFG_BASE_ADDRESS_0 0x10 +#define PCI_CFG_BASE_ADDRESS_1 0x14 +#define PCI_CFG_BASE_ADDRESS_2 0x18 +#define PCI_CFG_BASE_ADDRESS_3 0x1c +#define PCI_CFG_BASE_ADDRESS_4 0x20 +#define PCI_CFG_BASE_ADDRESS_5 0x24 +#define PCI_CFG_CIS 0x28 +#define PCI_CFG_SUB_VENDER_ID 0x2c +#define PCI_CFG_SUB_SYSTEM_ID 0x2e +#define PCI_CFG_EXPANSION_ROM 0x30 +#define PCI_CFG_RESERVED_0 0x34 +#define PCI_CFG_RESERVED_1 0x38 +#define PCI_CFG_DEV_INT_LINE 0x3c +#define PCI_CFG_DEV_INT_PIN 0x3d +#define PCI_CFG_MIN_GRANT 0x3e +#define PCI_CFG_MAX_LATENCY 0x3f +#define PCI_CFG_SPECIAL_USE 0x41 +#define PCI_CFG_MODE 0x43 + + +/* PCI-to-PCI bridge configuration register offsets */ +/* Note that only modulo-4 addresses are written to the address register */ + +#define PCI_CFG_PRIMARY_BUS 0x18 +#define PCI_CFG_SECONDARY_BUS 0x19 +#define PCI_CFG_SUBORDINATE_BUS 0x1a +#define PCI_CFG_SEC_LATENCY 0x1b +#define PCI_CFG_IO_BASE 0x1c +#define PCI_CFG_IO_LIMIT 0x1d +#define PCI_CFG_SEC_STATUS 0x1e +#define PCI_CFG_MEM_BASE 0x20 +#define PCI_CFG_MEM_LIMIT 0x22 +#define PCI_CFG_PRE_MEM_BASE 0x24 +#define PCI_CFG_PRE_MEM_LIMIT 0x26 +#define PCI_CFG_PRE_MEM_BASE_U 0x28 +#define PCI_CFG_PRE_MEM_LIMIT_U 0x2c +#define PCI_CFG_IO_BASE_U 0x30 +#define PCI_CFG_IO_LIMIT_U 0x32 +#define PCI_CFG_ROM_BASE 0x38 +#define PCI_CFG_BRG_INT_LINE 0x3c +#define PCI_CFG_BRG_INT_PIN 0x3d +#define PCI_CFG_BRIDGE_CONTROL 0x3e + +/* PCI Class definitions for find by class function */ + +#define PCI_CLASS_PRE_PCI20 0x00 +#define PCI_CLASS_MASS_STORAGE 0x01 +#define PCI_CLASS_NETWORK_CTLR 0x02 +#define PCI_CLASS_DISPLAY_CTLR 0x03 +#define PCI_CLASS_MMEDIA_DEVICE 0x04 +#define PCI_CLASS_MEM_CTLR 0x05 +#define PCI_CLASS_BRIDGE_CTLR 0x06 +#define PCI_CLASS_COMM_CTLR 0x07 +#define PCI_CLASS_BASE_PERIPH 0x08 +#define PCI_CLASS_INPUT_DEVICE 0x09 +#define PCI_CLASS_DOCK_DEVICE 0x0A +#define PCI_CLASS_PROCESSOR 0x0B +#define PCI_CLASS_SERIAL_BUS 0x0C +#define PCI_CLASS_UNDEFINED 0xFF + +/* PCI Subclass definitions */ + +#define PCI_SUBCLASS_00 0x00 +#define PCI_SUBCLASS_01 0x01 +#define PCI_SUBCLASS_02 0x02 +#define PCI_SUBCLASS_03 0x03 +#define PCI_SUBCLASS_04 0x04 +#define PCI_SUBCLASS_05 0x05 +#define PCI_SUBCLASS_06 0x06 +#define PCI_SUBCLASS_07 0x07 +#define PCI_SUBCLASS_10 0x10 +#define PCI_SUBCLASS_20 0x20 +#define PCI_SUBCLASS_80 0x80 + +/* Bridge Device subclasses */ + +#define PCI_SUBCLASS_HOST_PCI_BRIDGE (PCI_SUBCLASS_00) +#define PCI_SUBCLASS_ISA_BRIDGE (PCI_SUBCLASS_01) +#define PCI_SUBCLASS_P2P_BRIDGE (PCI_SUBCLASS_04) +#define PCI_SUBCLASS_PCMCIA_BRIDGE (PCI_SUBCLASS_05) +#define PCI_SUBCLASS_CARDBUS_BRIDGE (PCI_SUBCLASS_07) + +/* Processor subclasses */ + +#define PCI_SUBCLASS_PROCESSOR_386 (PCI_SUBCLASS_00) +#define PCI_SUBCLASS_PROCESSOR_486 (PCI_SUBCLASS_01) +#define PCI_SUBCLASS_PROCESSOR_PENTIUM (PCI_SUBCLASS_02) +#define PCI_SUBCLASS_PROCESSOR_ALPHA (PCI_SUBCLASS_10) +#define PCI_SUBCLASS_PROCESSOR_POWERPC (PCI_SUBCLASS_20) + +/* Serial bus subclasses */ + +#define PCI_SUBCLASS_SERBUS_FIREWIRE (PCI_SUBCLASS_00) +#define PCI_SUBCLASS_SERBUS_USB (PCI_SUBCLASS_03) + +/* Network subclasses */ + +#define PCI_SUBCLASS_NET_ETHERNET (PCI_SUBCLASS_00) +#define PCI_SUBCLASS_NET_TOKEN_RING (PCI_SUBCLASS_01) +#define PCI_SUBCLASS_NET_FDDI (PCI_SUBCLASS_02) +#define PCI_SUBCLASS_NET_ATM (PCI_SUBCLASS_03) + +/* Conditional defines for new configuration definitions */ + +#define PCI_CMD_MASK 0xffff0000 +#define PCI_BASE_ADDRESS_MEM_MASK (~0x0fUL) +#define PCI_BASE_ADDRESS_IO_MASK (~0x03UL) + +/* Vendor and Device ID's */ + +/* Promise ATA */ +#define PCI_VENDOR_ID_PROMISE 0x105a +#define PCI_DEVICE_ID_PROMISE_20265 0x0d30 +#define PCI_DEVICE_ID_PROMISE_20267 0x4d30 +#define PCI_DEVICE_ID_PROMISE_20246 0x4d33 +#define PCI_DEVICE_ID_PROMISE_20262 0x4d38 +#define PCI_DEVICE_ID_PROMISE_5300 0x5300 + +/* DEC Ethernet */ +#define PCI_VENDOR_ID_DEC 0x1011 +#define PCI_DEVICE_ID_DEC_BRD 0x0001 +#define PCI_DEVICE_ID_DEC_TULIP 0x0002 +#define PCI_DEVICE_ID_DEC_TGA 0x0004 +#define PCI_DEVICE_ID_DEC_TULIP_FAST 0x0009 +#define PCI_DEVICE_ID_DEC_TGA2 0x000D +#define PCI_DEVICE_ID_DEC_FDDI 0x000F +#define PCI_DEVICE_ID_DEC_TULIP_PLUS 0x0014 +#define PCI_DEVICE_ID_DEC_21142 0x0019 +#define PCI_DEVICE_ID_DEC_21052 0x0021 +#define PCI_DEVICE_ID_DEC_21150 0x0022 +#define PCI_DEVICE_ID_DEC_21152 0x0024 +#define PCI_DEVICE_ID_DEC_21153 0x0025 +#define PCI_DEVICE_ID_DEC_21154 0x0026 +#define PCI_DEVICE_ID_DEC_21285 0x1065 +#define PCI_DEVICE_ID_COMPAQ_42XX 0x0046 + + + +/* Cache Line Size - 32 32-bit value = 128 bytes */ +#ifndef PCI_CACHE_LINE_SIZE +#define PCI_CACHE_LINE_SIZE 0x20 +#endif /* PCI_CACHE_LINE_SIZE */ + +/* Latency Timer value - 255 PCI clocks */ +#ifndef PCI_LATENCY_TIMER +#define PCI_LATENCY_TIMER 0xff +#endif /* PCI_LATENCY_TIMER */ + +#ifndef _ASMLANGUAGE +int pci_dev_init(int b); +int pci_dev_find(int vid, int devId, int idx,int *bus, int* dev, int* func); +int pci_class_find(int class, int idx, int* bus, int* dev, int *func); +int pci_config_inb(int b, int d, int f, int address, uint8 * pData); +int pci_config_inw(int b, int d, int f, int address, uint16 * pData); +int pci_config_inl(int b, int d, int f, int address, uint32 * pData); +int pci_config_outb(int b, int d, int f, int address, uint8 data); +int pci_config_outw(int b, int d, int f, int address, uint16 data); +int pci_config_outl(int b, int d, int f, int address, uint32 data); +int pci_special_cycle(int b, uint32 message); +int pci_config_bdf_pack(int b, int d, int f); +int pci_dev_config(int b, int d, int f, uint32 iobar, uint32 mbar, uint32 cm ); +int pci_config_modl(int b, int d, int f, int offset, + uint32 bitMask, uint32 data ); +int pci_config_modw(int b, int d, int f, int off, + uint16 bitMask, uint16 data ); +int pci_config_modb(int b, int d, int f, int offset, + uint8 bitMask, uint8 data ); +unsigned int pci_size_bar(unsigned int, unsigned long mask); +#endif /* _ASMLANGUAGE */ + +#endif /* __MPC8240_PCI */ diff --git a/board/mousse/ppcboot.lds b/board/mousse/ppcboot.lds new file mode 100644 index 0000000..3ab75dd --- /dev/null +++ b/board/mousse/ppcboot.lds @@ -0,0 +1,123 @@ +/* + * (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/mpc8240/start.o (.text) + common/board.o (.text) + ppc/ppcstring.o (.text) + ppc/vsprintf.o (.text) + ppc/crc32.o (.text) + ppc/zlib.o (.text) + + *(.fixup) + *(.got1) + . = ALIGN(16); + *(.rodata) + *(.rodata1) + } + .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 = .); + + __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/ppcboot.lds.ram b/board/mousse/ppcboot.lds.ram new file mode 100644 index 0000000..1e4b417 --- /dev/null +++ b/board/mousse/ppcboot.lds.ram @@ -0,0 +1,101 @@ +/* + * (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/mpc8240/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 + */ + __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/ppcboot.lds.rom b/board/mousse/ppcboot.lds.rom new file mode 100644 index 0000000..763a5d3 --- /dev/null +++ b/board/mousse/ppcboot.lds.rom @@ -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/mpc8240/start.o (.text) + common/board.o (.text) + ppc/ppcstring.o (.text) + ppc/vsprintf.o (.text) + ppc/crc32.o (.text) + ppc/zlib.o (.text) + + . = 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: */ + . = (. + 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 = .); + + __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/serial.c b/board/mousse/serial.c new file mode 100644 index 0000000..1ef6ffa --- /dev/null +++ b/board/mousse/serial.c @@ -0,0 +1,76 @@ +/* + * (C) Copyright 2001 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * (C) Copyright 2000 + * Rob Taylor, Flying Pig Systems. robt@flyingpig.com. + * + * (C) Copyright 2000 + * 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 +#include "ns16550.h" + +volatile struct NS16550 *console; + +void +serial_init (unsigned long dummy, int baudrate) +{ + ns16550_init(baudrate); +} + +void +serial_putc(const char c) +{ + if (c == '\n') + { + serial_putc ('\r'); + } + ns16550_putc((unsigned char)c); +} + +void +serial_puts (const char *s) +{ + while (*s) { + serial_putc (*s++); + } +} + +int +serial_getc(void) +{ + return ns16550_getc(); +} + +int +serial_tstc(void) +{ + return ns16550_tstc(); +} + +void +serial_setbrg (unsigned long dummy, int baudrate) +{ + ns16550_init(baudrate); +} + diff --git a/board/mousse/speed.c b/board/mousse/speed.c new file mode 100644 index 0000000..d482122 --- /dev/null +++ b/board/mousse/speed.c @@ -0,0 +1,68 @@ +/* + * (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 +#include +#include + + +ulong get_bus_freq(ulong ignore) +{ + return 33000000; /* On Mousse, PCI is at least 33Mhz */ +} + +/* ------------------------------------------------------------------------- */ + +/* + * Measure CPU clock speed + */ + +/* Table to convert pllratio to actual processor clock scaling factor (*10) + */ +#ifdef CONFIG_MPC8240 +short pllratio_to_factor[] = { + 00, 00, 00, 10, 20, 20, 25, 00, 00, 00, 00, 00, 00, 00, 00, 00, + 00, 00, 00, 10, 00, 00, 00, 45, 60, 00, 40, 00, 00, 00, 35, 00, +}; +#endif + +ulong get_gclk_freq(void) +{ + uint hid1 = mfspr(HID1); + +#ifdef CONFIG_MPC8240 + + /* 5 bits for PLL ration on 8240 + */ + hid1 = (hid1 >> (32-5)) & 0x1f; +#else + + /* 4 bits on everythings else + */ + hid1 = (hid1 >> (32-4)) & 0xf; +#endif + return (pllratio_to_factor[hid1] * get_bus_freq(0)) / 10; +} + +/* ------------------------------------------------------------------------- */ + diff --git a/cpu/mpc8240/cpu.c b/cpu/mpc8240/cpu.c index d8411c4..313653d 100644 --- a/cpu/mpc8240/cpu.c +++ b/cpu/mpc8240/cpu.c @@ -44,7 +44,7 @@ int checkcpu(long clock) switch(revision) { default: /*currently no info on revision numbers*/ - printf(" Revsion %d.%d",revision>>8, revision & 0xff); + printf(" Revision %d.%d",revision>>8, revision & 0xff); } printf(" at %s MHz:", strmhz(buf, clock)); @@ -131,3 +131,150 @@ unsigned long get_tbclk (void) } /* ------------------------------------------------------------------------- */ + +/* + * The MPC8240 has an integrated PCI controller known as the MPC107. + * The following are MPC107 Bridge Controller and PCI Support functions + * + */ + +/* + * This procedure reads a 32-bit address MPC107 register, and returns + * a 32 bit value. It swaps the address to little endian before + * writing it to config address, and swaps the value to big endian + * before returning to the caller. + */ +unsigned int +mpc8240_mpc107_getreg(unsigned int regNum) +{ + unsigned int temp; + /* swap the addr. to little endian */ + *(volatile unsigned int *)CHRP_REG_ADDR = PCISWAP(regNum); + temp = *(volatile unsigned int *)CHRP_REG_DATA; + return PCISWAP(temp); /* swap the data upon return */ +} + +/* + * This procedure writes a 32-bit address MPC107 register, and returns + * a 32 bit value. It swaps the address to little endian before + * writing it to config address, and swaps the value to big endian + * before returning to the caller. + */ + +void +mpc8240_mpc107_setreg(unsigned int regNum, unsigned int regVal) +{ + /* swap the addr. to little endian */ + *(volatile unsigned int *)CHRP_REG_ADDR = PCISWAP(regNum); + *(volatile unsigned int *)CHRP_REG_DATA = PCISWAP(regVal); + return; +} + + +/* + * Write a byte (8 bits) to a memory location. + */ +void +mpc8240_mpc107_write8(unsigned int addr, unsigned char data) +{ + *(unsigned char*)addr = data; + __asm__("sync"); +} +/* + * Write a word (16 bits) to a memory location after the value + * has been byte swapped (big to little endian or vice versa) + */ + +void +mpc8240_mpc107_write16(unsigned int address, unsigned short data) +{ + *(volatile unsigned short *)address = BYTE_SWAP_16_BIT(data); + __asm__("sync"); +} + +/* + * Write a long word (32 bits) to a memory location after the value + * has been byte swapped (big to little endian or vice versa) + */ + +void +mpc8240_mpc107_write32(unsigned int address, unsigned int data) +{ + *(volatile unsigned int *)address = LONGSWAP(data); + __asm__("sync"); +} + +/* + * Read a byte (8 bits) from a memory location. + */ +unsigned char +mpc8240_mpc107_read8(unsigned int addr) +{ + return *(volatile unsigned char*)addr; +} + + +/* + * Read a word (16 bits) from a memory location, and byte swap the + * value before returning to the caller. + */ +unsigned short +mpc8240_mpc107_read16(unsigned int address) +{ + unsigned short retVal; + retVal = BYTE_SWAP_16_BIT(*(unsigned short*)address); + return retVal; +} + + +/* + * Read a long word (32 bits) from a memory location, and byte + * swap the value before returning to the caller. + */ +unsigned int +mpc8240_mpc107_read32(unsigned int address) +{ + unsigned int retVal; + retVal = LONGSWAP(*(unsigned int *)address); + return (retVal); +} + + +/* + * Read a register in the Embedded Utilities Memory Block address + * space. + * Input: regNum - register number + utility base address. Example, + * the base address of EPIC is 0x40000, the register number + * being passed is 0x40000+the address of the target register. + * (See epic.h for register addresses). + * Output: The 32 bit little endian value of the register. + */ + +unsigned int +mpc8240_eummbar_read(unsigned int regNum) +{ + unsigned int temp; + temp = *(volatile unsigned int *) (EUMBBAR_VAL + regNum) ; + temp = PCISWAP(temp); + return temp; +} + + +/* + * Write a value to a register in the Embedded Utilities Memory + * Block address space. + * Input: regNum - register number + utility base address. Example, + * the base address of EPIC is 0x40000, the register + * number is 0x40000+the address of the target register. + * (See epic.h for register addresses). + * regVal - value to be written to the register. + */ + +void +mpc8240_eummbar_write(unsigned int regNum, unsigned int regVal) +{ + *(volatile unsigned int *) (EUMBBAR_VAL + regNum) = PCISWAP(regVal); + return; +} + +/* ------------------------------------------------------------------------- */ diff --git a/cpu/mpc8240/cpu_init.c b/cpu/mpc8240/cpu_init.c index c3f67fb..1593774 100644 --- a/cpu/mpc8240/cpu_init.c +++ b/cpu/mpc8240/cpu_init.c @@ -34,6 +34,7 @@ void cpu_init_f (void) { +#ifndef CONFIG_MOUSSE /* Mousse initialized in asm */ register unsigned long val; CONFIG_WRITE_HALFWORD(PCICR, 0x06); /* Bus Master, respond to PCI memory space acesses*/ /* CONFIG_WRITE_HALFWORD(PCISR, 0xffff); *//*reset PCISR*/ @@ -171,14 +172,91 @@ cpu_init_f (void) */ for (val = 0; val < 0x20000; val+=0x1000) tlbie(val); - +#endif /* CONFIG_MOUSSE */ } + +#ifdef CONFIG_MOUSSE +#ifdef INCLUDE_MPC107_REPORT +struct MPC107_s{ + unsigned int iobase; + char desc[120]; +} MPC107Regs[] ={ + {BMC_BASE+0x0, "MPC107 Vendor/Device ID"}, + {BMC_BASE+0x4, "MPC107 PCI Command/Status Register"}, + {BMC_BASE+0x8, "MPC107 Revision"}, + {BMC_BASE+0xC, "MPC107 Cache Line Size"}, + {BMC_BASE+0x10, "MPC107 LMBAR"}, + {BMC_BASE+0x14, "MPC8240 PCSR"}, + {BMC_BASE+0xA8, "MPC8240 PICR1"}, + {BMC_BASE+0xAC, "MPC8240 PICR2"}, + {BMC_BASE+0x46, "MPC8240 PACR"}, + {BMC_BASE+0x310, "MPC8240 ITWR"}, + {BMC_BASE+0x300, "MPC8240 OMBAR"}, + {BMC_BASE+0x308, "MPC8240 OTWR"}, + {BMC_BASE+0x14, "MPC107 Peripheral Control and Status Register"}, + {BMC_BASE+0x78, "MPC107 EUMBAR"}, + {BMC_BASE+0xC0, "MPC107 Processor Bus Error Status"}, + {BMC_BASE+0xC4, "MPC107 PCI Bus Error Status"}, + {BMC_BASE+0xC8, "MPC107 Processor/PCI Error Address"}, + {BMC_BASE+0xE0, "MPC107 AMBOR Register"}, + {BMC_BASE+0xF0, "MPC107 MCCR1 Register"}, + {BMC_BASE+0xF4, "MPC107 MCCR2 Register"}, + {BMC_BASE+0xF8, "MPC107 MCCR3 Register"}, + {BMC_BASE+0xFC, "MPC107 MCCR4 Register"} +}; +#define N_MPC107_Regs (sizeof(MPC107Regs)/sizeof(MPC107Regs[0])) +#endif /* INCLUDE_MPC107_REPORT */ +#endif /* CONFIG_MOUSSE */ + /* * initialize higher level parts of CPU like time base and timers */ void cpu_init_r (bd_t *bd) { +#ifdef CONFIG_MOUSSE +#ifdef INCLUDE_MPC107_REPORT + unsigned int tmp = 0, i; +#endif + /* + * Initialize the EUMBBAR (Embedded Util Mem Block Base Addr Reg). + * This is necessary before the EPIC, DMA ctlr, I2C ctlr, etc. can + * be accessed. + */ + mpc8240_mpc107_setreg(EUMBBAR, EUMBBAR_VAL); + + /* MOT/SPS: Issue #10002, PCI (FD Alias enable)*/ + mpc8240_mpc107_setreg(AMBOR, 0x000000C0); + + +#ifdef INCLUDE_MPC107_REPORT + /* Check MPC8240 PCI Device and Vendor ID */ + while((tmp = mpc8240_mpc107_getreg(BMC_BASE)) != 0x31057){ + printf(" MPC107: offset=0x%x, val = 0x%x\n", BMC_BASE, tmp); + } + for( i = 0; i < N_MPC107_Regs; i++){ + printf(" 0x%x/%s = 0x%x\n", MPC107Regs[i].iobase, + MPC107Regs[i].desc, mpc8240_mpc107_getreg(MPC107Regs[i].iobase)); + } + + printf("IBAT0L = 0x%08X\n", mfspr(IBAT0L)); + printf("IBAT0U = 0x%08X\n", mfspr(IBAT0U)); + printf("IBAT1L = 0x%08X\n", mfspr(IBAT1L)); + printf("IBAT1U = 0x%08X\n", mfspr(IBAT1U)); + printf("IBAT2L = 0x%08X\n", mfspr(IBAT2L)); + printf("IBAT2U = 0x%08X\n", mfspr(IBAT2U)); + printf("IBAT3L = 0x%08X\n", mfspr(IBAT3L)); + printf("IBAT3U = 0x%08X\n", mfspr(IBAT3U)); + printf("DBAT0L = 0x%08X\n", mfspr(DBAT0L)); + printf("DBAT0U = 0x%08X\n", mfspr(DBAT0U)); + printf("DBAT1L = 0x%08X\n", mfspr(DBAT1L)); + printf("DBAT1U = 0x%08X\n", mfspr(DBAT1U)); + printf("DBAT2L = 0x%08X\n", mfspr(DBAT2L)); + printf("DBAT2U = 0x%08X\n", mfspr(DBAT2U)); + printf("DBAT3L = 0x%08X\n", mfspr(DBAT3L)); + printf("DBAT3U = 0x%08X\n", mfspr(DBAT3U)); +#endif /* INCLUDE_MPC107_REPORT */ +#endif /* CONFIG_MOUSSE */ } diff --git a/cpu/mpc8240/drivers/epic/epic1.c b/cpu/mpc8240/drivers/epic/epic1.c index 5d14078..c5333d5 100644 --- a/cpu/mpc8240/drivers/epic/epic1.c +++ b/cpu/mpc8240/drivers/epic/epic1.c @@ -10,9 +10,6 @@ #define PRINT(format, args...) printf(format , ## args) -#define LONGSWAP(x) ((((x) & 0x000000ff) << 24) | (((x) & 0x0000ff00) << 8)|\ - (((x) & 0x00ff0000) >> 8) | (((x) & 0xff000000) >> 24) ) - typedef void (*VOIDFUNCPTR) (void); /* ptr to function returning void */ struct SrcVecTable SrcVecTable[MAXVEC] = /* Addr/Vector cross-reference tbl */ { diff --git a/include/config_MOUSSE.h b/include/config_MOUSSE.h new file mode 100644 index 0000000..d1cf085 --- /dev/null +++ b/include/config_MOUSSE.h @@ -0,0 +1,309 @@ +/* + * (C) Copyright 2000, 2001 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * (C) Copyright 2001 + * James F. 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 + */ + +/* + * + * Configuration settings for the MOUSSE board. + * See also: http://www.vooha.com/ + * + */ + +/* ------------------------------------------------------------------------- */ + +/* + * board/config.h - configuration options, board specific + */ + +#ifndef __CONFIG_H +#define __CONFIG_H + +/* + * High Level Configuration Options + * (easy to change) + */ + +#define CONFIG_MPC8240 1 +#define CONFIG_MOUSSE 1 +#define CFG_ADDR_MAP_B 1 +#define CONFIG_PCI 1 +#define CONFIG_CONS_INDEX 1 +#define CONFIG_BAUDRATE 9600 +#if 1 +#define CONFIG_BOOTCOMMAND "tftp 100000 vmlinux.img;bootm" /* autoboot command */ +#else +#define CONFIG_BOOTCOMMAND "bootm ffe10000" +#endif +#define CONFIG_BOOTARGS "console=ttyS0 root=/dev/nfs rw nfsroot=209.128.93.133:/boot nfsaddrs=209.128.93.133:209.128.93.138" +#define CONFIG_BOOTDELAY 3 +#define CONFIG_COMMANDS (CONFIG_CMD_DFL|CFG_CMD_ASKENV|CFG_CMD_DATE) +#define CONFIG_ENV_OVERWRITE 1 +#define CONFIG_ETH_ADDR "00:10:18:10:00:06" + +#define CONFIG_DOS_PARTITION 1 /* MSDOS bootable partitiion support */ +/* This must be included AFTER the definition of CONFIG_COMMANDS (if any) + */ +#include +#include "../board/mousse/mousse.h" + +/* + * Miscellaneous configurable options + */ +#undef CFG_LONGHELP /* undef to save memory */ +#define CFG_PROMPT "=>" /* Monitor Command Prompt */ +#define CFG_CBSIZE 256 /* Console I/O Buffer Size */ +#define CFG_PBSIZE (CFG_CBSIZE + sizeof(CFG_PROMPT) + 16) +#define CFG_MAXARGS 8 /* Max number of command args */ + +#define CFG_BARGSIZE CFG_CBSIZE /* Boot Argument Buffer Size */ +#define CFG_LOAD_ADDR 0x00100000 /* Default load address */ + +/*----------------------------------------------------------------------- + * Start addresses for the final memory configuration + * (Set up by the startup code) + * Please note that CFG_SDRAM_BASE _must_ start at 0 + */ +#define CFG_SDRAM_BASE 0x00000000 + +#ifdef DEBUG +#define CFG_MONITOR_BASE CFG_SDRAM_BASE +#else +#define CFG_MONITOR_BASE CFG_FLASH_BASE +#endif + +#ifdef DEBUG +#define CFG_MONITOR_LEN (4 << 20) /* lots of mem ... */ +#else +#define CFG_MONITOR_LEN (512 << 10) /* 512K PLCC bootrom */ +#endif +#define CFG_MALLOC_LEN (2*(4096 << 10)) /* 2*4096kB for malloc() */ + +#define CFG_MEMTEST_START 0x00004000 /* memtest works on */ +#define CFG_MEMTEST_END 0x02000000 /* 0 ... 32 MB in DRAM */ + + +#define CFG_EUMB_ADDR 0xFC000000 + +#define CFG_ISA_MEM 0xFD000000 +#define CFG_ISA_IO 0xFE000000 + +#define CFG_FLASH_BASE 0xFFF00000 +#define CFG_FLASH_SIZE ((uint)(512 * 1024)) +#define CFG_RESET_ADDRESS 0xFFF00100 +#define FLASH_BASE0_PRELIM 0xFFF00000 /* 512K PLCC FLASH/AM29F040*/ +#define FLASH_BASE0_SIZE 0x80000 /* 512K */ +#define FLASH_BASE1_PRELIM 0xFFE10000 /* AMD 29LV160DB + 1MB - 64K FLASH0 SEG =960K + (size=0xf0000)*/ + +#define CFG_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 } + + +/*----------------------------------------------------------------------- + * Definitions for initial stack pointer and data area (in DPRAM) + */ +#define CFG_INIT_RAM_ADDR CFG_SDRAM_BASE + CFG_MONITOR_LEN +#define CFG_INIT_RAM_END 0x3000 /* End of used area in DPRAM */ +#define CFG_INIT_DATA_SIZE 64 /* size in bytes reserved for initial data */ +#define CFG_INIT_DATA_OFFSET (CFG_INIT_RAM_END - CFG_INIT_DATA_SIZE) +#define CFG_INIT_SP_OFFSET CFG_INIT_DATA_OFFSET + +/* + * Low Level Configuration Settings + * (address mappings, register initial values, etc.) + * You should know what you are doing if you make changes here. + * For the detail description refer to the MPC8240 user's manual. + */ + +#define CONFIG_SYS_CLK_FREQ 200000000 +#define CFG_HZ 1000 + +#define CFG_ETH_DEV_FN 0x00 +#define CFG_ETH_IOBASE 0x00104000 + + + /* Bit-field values for MCCR1. + */ +#define CFG_ROMNAL 8 +#define CFG_ROMFAL 8 + + /* Bit-field values for MCCR2. + */ +#define CFG_REFINT 0xf5 /* Refresh interval */ + + /* Burst To Precharge. Bits of this value go to MCCR3 and MCCR4. + */ +#define CFG_BSTOPRE 0x79 + +#ifdef INCLUDE_ECC +#define USE_ECC 1 +#else /* INCLUDE_ECC */ +#define USE_ECC 0 +#endif /* INCLUDE_ECC */ + + + /* Bit-field values for MCCR3. + */ +#define CFG_REFREC 8 /* Refresh to activate interval */ +#define CFG_RDLAT (4+USE_ECC) /* Data latancy from read command */ + + /* Bit-field values for MCCR4. + */ +#define CFG_PRETOACT 3 /* Precharge to activate interval */ +#define CFG_ACTTOPRE 5 /* Activate to Precharge interval */ +#define CFG_SDMODE_CAS_LAT 3 /* SDMODE CAS latancy */ +#define CFG_SDMODE_WRAP 0 /* SDMODE wrap type */ +#define CFG_SDMODE_BURSTLEN 2 /* SDMODE Burst length */ +#define CFG_ACTORW 2 +#define CFG_REGISTERD_TYPE_BUFFER (1-USE_ECC) + +/* Memory bank settings. + * Only bits 20-29 are actually used from these vales to set the + * start/end addresses. The upper two bits will always be 0, and the lower + * 20 bits will be 0x00000 for a start address, or 0xfffff for an end + * address. Refer to the MPC8240 book. + */ +#define CFG_RAM_SIZE 0x04000000 /* 64MB */ + + +#define CFG_BANK0_START 0x00000000 +#define CFG_BANK0_END (CFG_RAM_SIZE - 1) +#define CFG_BANK0_ENABLE 1 +#define CFG_BANK1_START 0x3ff00000 +#define CFG_BANK1_END 0x3fffffff +#define CFG_BANK1_ENABLE 0 +#define CFG_BANK2_START 0x3ff00000 +#define CFG_BANK2_END 0x3fffffff +#define CFG_BANK2_ENABLE 0 +#define CFG_BANK3_START 0x3ff00000 +#define CFG_BANK3_END 0x3fffffff +#define CFG_BANK3_ENABLE 0 +#define CFG_BANK4_START 0x3ff00000 +#define CFG_BANK4_END 0x3fffffff +#define CFG_BANK4_ENABLE 0 +#define CFG_BANK5_START 0x3ff00000 +#define CFG_BANK5_END 0x3fffffff +#define CFG_BANK5_ENABLE 0 +#define CFG_BANK6_START 0x3ff00000 +#define CFG_BANK6_END 0x3fffffff +#define CFG_BANK6_ENABLE 0 +#define CFG_BANK7_START 0x3ff00000 +#define CFG_BANK7_END 0x3fffffff +#define CFG_BANK7_ENABLE 0 + +#define CFG_ODCR 0x7f + + +#define CFG_PGMAX 0x32 /* how long the 8240 reatins the currently accessed page in memory + see 8240 book for details*/ +#define PCI_MEM_SPACE1_START 0x80000000 +#define PCI_MEM_SPACE2_START 0xfd000000 + +/* IBAT/DBAT Configuration */ +/* Ram: 64MB, starts at address-0, r/w instruction/data */ +#define CFG_IBAT0U (CFG_SDRAM_BASE | BATU_BL_64M | BATU_VS | BATU_VP) +#define CFG_IBAT0L (CFG_SDRAM_BASE | BATL_PP_10 | BATL_MEMCOHERENCE) +#define CFG_DBAT0U CFG_IBAT0U +#define CFG_DBAT0L CFG_IBAT0L + +/* MPLD/Port-X I/O Space : data and instruction read/write, cache-inhibit */ +#define CFG_IBAT1U (PORTX_DEV_BASE | BATU_BL_128M | BATU_VS | BATU_VP) +#if 0 +#define CFG_IBAT1L (PORTX_DEV_BASE | BATL_PP_10 | BATL_MEMCOHERENCE |\ + BATL_WRITETHROUGH | BATL_CACHEINHIBIT) +#else +#define CFG_IBAT1L (PORTX_DEV_BASE | BATL_PP_10 |BATL_CACHEINHIBIT) +#endif +#define CFG_DBAT1U CFG_IBAT1U +#define CFG_DBAT1L CFG_IBAT1L + +/* PCI Memory region 1: 0x8XXX_XXXX PCI Mem space: EUMBAR, etc - 16MB */ +#define CFG_IBAT2U (PCI_MEM_SPACE1_START|BATU_BL_16M | BATU_VS | BATU_VP) +#define CFG_IBAT2L (PCI_MEM_SPACE1_START|BATL_PP_10 | BATL_GUARDEDSTORAGE|BATL_CACHEINHIBIT) +#define CFG_DBAT2U CFG_IBAT2U +#define CFG_DBAT2L CFG_IBAT2L + +/* PCI Memory region 2: PCI Devices in 0xFD space */ +#define CFG_IBAT3U (PCI_MEM_SPACE2_START|BATU_BL_16M | BATU_VS | BATU_VP) +#define CFG_IBAT3L (PCI_MEM_SPACE2_START|BATL_PP_10 | BATL_GUARDEDSTORAGE | BATL_CACHEINHIBIT) +#define CFG_DBAT3U CFG_IBAT3U +#define CFG_DBAT3L CFG_IBAT3L + + +/* + * For booting Linux, the board info and command line data + * have to be in the first 8 MB of memory, since this is + * the maximum mapped by the Linux kernel during initialization. + */ +#define CFG_BOOTMAPSZ (8 << 20) /* Initial Memory map for Linux */ + +/*----------------------------------------------------------------------- + * FLASH organization + */ +#define CFG_MAX_FLASH_BANKS 3 /* Max number of flash banks */ +#define CFG_MAX_FLASH_SECT 64 /* Max number of sectors in one bank */ + +#define CFG_FLASH_ERASE_TOUT 120000 /* Timeout for Flash Erase (in ms) */ +#define CFG_FLASH_WRITE_TOUT 500 /* Timeout for Flash Write (in ms) */ + +#if 0 +#define CFG_ENV_IS_IN_FLASH 1 +#define CFG_ENV_OFFSET 0x8000 /* Offset of the Environment Sector */ +#define CFG_ENV_SIZE 0x4000 /* Size of the Environment Sector */ +#else +#define CFG_ENV_IS_IN_NVRAM 1 +#define CFG_ENV_ADDR NV_OFF_PPCBOOT_ADDR /* PortX NVM Free addr*/ +#define CFG_ENV_OFFSET CFG_ENV_ADDR +#define CFG_ENV_SIZE NV_PPCBOOT_ENV_SIZE /* 2K */ +#endif +/*----------------------------------------------------------------------- + * Cache Configuration + */ +#define CFG_CACHELINE_SIZE 16 + + + +/* + * Internal Definitions + * + * Boot Flags + */ +#define BOOTFLAG_COLD 0x01 /* Normal Power-On: Boot from FLASH */ +#define BOOTFLAG_WARM 0x02 /* Software reboot */ + +/* Localizations */ +#if 0 +#define CONFIG_ETHADDR 0:0:0:0:1:d +#define CONFIG_IPADDR 172.16.40.113 +#define CONFIG_SERVERIP 172.16.40.111 +#else +#define CONFIG_ETHADDR 0:0:0:0:1:d +#define CONFIG_IPADDR 209.128.93.138 +#define CONFIG_SERVERIP 209.128.93.133 +#endif + +#endif /* __CONFIG_H */ + + diff --git a/include/flash.h b/include/flash.h index cd5710c..34b1810 100644 --- a/include/flash.h +++ b/include/flash.h @@ -160,6 +160,7 @@ int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt); #define FLASH_AM800T 0x0004 /* AMD AM29LV800 */ #define FLASH_AM800B 0x0005 #define FLASH_AM160T 0x0006 /* AMD AM29LV160 */ +#define FLASH_AM160LV 0x0046 /* AMD29LV160DB (2M = 2Mx8bit ) */ #define FLASH_AM160B 0x0007 #define FLASH_AM320T 0x0008 /* AMD AM29LV320 */ #define FLASH_AM320B 0x0009 diff --git a/include/mpc8240.h b/include/mpc8240.h index 6b620fe..85c59c6 100755 --- a/include/mpc8240.h +++ b/include/mpc8240.h @@ -1,5 +1,6 @@ /* * Copyright Rob Taylor, Flying Pig Systems Ltd. 2000. + * Copyright (C) 2001, James Dougherty, jfd@cs.stanford.edu * * See file CREDITS for list of people who contributed to this * project. @@ -23,65 +24,119 @@ #ifndef __MPC8240_H__ #define __MPC8240_H__ + +/* CPU Types */ +#define CPU_TYPE_601 0x01 /* PPC 601 CPU */ +#define CPU_TYPE_602 0x02 /* PPC 602 CPU */ +#define CPU_TYPE_603 0x03 /* PPC 603 CPU */ +#define CPU_TYPE_603E 0x06 /* PPC 603e CPU */ +#define CPU_TYPE_603P 0x07 /* PPC 603p CPU */ +#define CPU_TYPE_604 0x04 /* PPC 604 CPU */ +#define CPU_TYPE_604E 0x09 /* PPC 604e CPU */ +#define CPU_TYPE_604R 0x0a /* PPC 604r CPU */ +#define CPU_TYPE_750 0x08 /* PPC 750 CPU */ +#define CPU_TYPE_8240 0x81 /* PPC 8240 CPU */ +#define _CACHE_ALIGN_SIZE 32 /* cache line size */ + +/* spr976 - DMISS data tlb miss address register + * spr977 - DCMP data tlb miss compare register + * spr978 - HASH1 PTEG1 address register + * spr980 - HASH2 PTEG2 address register + * IMISS - instruction tlb miss address register + * ICMP - instruction TLB mis compare register + * RPA - real page address register + * HID0 - hardware implemntation register + * HID2 - instruction address breakpoint register + */ + +/* Kahlua/MPC8240 defines */ +#define VEN_DEV_ID 0x00021057 /* Vendor and Dev. ID for MPC106 */ +#define KAHLUA_ID 0x00031057 /* Vendor & Dev Id for Kahlua's PCI */ +#define BMC_BASE 0x80000000 /* Kahlua ID in PCI Memory space */ +#define CHRP_REG_ADDR 0xfec00000 /* MPC107 Config, Map B */ +#define CHRP_REG_DATA 0xfee00000 /* MPC107 Config, Map B */ +#define PREP_REG_ADDR 0x80000cf8 /* MPC107 Config, Map A */ +#define PREP_REG_DATA 0x80000cfc /* MPC107 Config, Map A */ +#define MPC107_PCI_CMD 0x80000004 /* MPC107 PCI cmd reg */ +#define MPC107_PCI_STAT 0x80000006 /* MPC107 PCI status reg */ +#define PROC_INT1_ADR 0x800000a8 /* MPC107 Processor i/f cfg1 */ +#define PROC_INT2_ADR 0x800000ac /* MPC107 Processor i/f cfg2 */ +#define MEM_CONT1_ADR 0x800000f0 /* MPC107 Memory control config. 1 */ +#define MEM_CONT2_ADR 0x800000f4 /* MPC107 Memory control config. 2 */ +#define MEM_CONT3_ADR 0x800000f8 /* MPC107 Memory control config. 3 */ +#define MEM_CONT4_ADR 0x800000fc /* MPC107 Memory control config. 4 */ +#define MEM_ERREN1_ADR 0x800000c0 /* MPC107 Memory error enable 1 */ +#define MEM_START1_ADR 0x80000080 /* MPC107 Memory starting addr */ +#define MEM_START2_ADR 0x80000084 /* MPC107 Memory starting addr-lo */ +#define XMEM_START1_ADR 0x80000088 /* MPC107 Extended mem. start addr-hi*/ +#define XMEM_START2_ADR 0x8000008c /* MPC107 Extended mem. start addr-lo*/ +#define MEM_END1_ADR 0x80000090 /* MPC107 Memory ending address */ +#define MEM_END2_ADR 0x80000094 /* MPC107 Memory ending addr-lo */ +#define XMEM_END1_ADR 0x80000098 /* MPC107 Extended mem. end addrs-hi */ +#define XMEM_END2_ADR 0x8000009c /* MPC107 Extended mem. end addrs-lo*/ +#define OUT_DRV_CONT 0x80000073 /* MPC107 Output Driver Control reg */ +#define MEM_EN_ADR 0x800000a0 /* Memory bank enable */ +#define PAGE_MODE 0x800000a3 /* MPC107 Page Mode Counter/Timer */ + /*----------------------------------------------------------------------- * Exception offsets (PowerPC standard) */ -#define EXC_OFF_RESERVED0 0x0000 /* Reserved */ -#define EXC_OFF_SYS_RESET 0x0100 /* System reset */ -#define EXC_OFF_MACH_CHCK 0x0200 /* Machine Check */ -#define EXC_OFF_DATA_STOR 0x0300 /* Data Storage */ -#define EXC_OFF_INS_STOR 0x0400 /* Instruction Storage */ -#define EXC_OFF_EXTERNAL 0x0500 /* External */ -#define EXC_OFF_ALIGN 0x0600 /* Alignment */ -#define EXC_OFF_PROGRAM 0x0700 /* Program */ -#define EXC_OFF_FPUNAVAIL 0x0800 /* Floating-point Unavailable */ -#define EXC_OFF_DECR 0x0900 /* Decrementer */ -#define EXC_OFF_RESERVED1 0x0A00 /* Reserved */ -#define EXC_OFF_RESERVED2 0x0B00 /* Reserved */ -#define EXC_OFF_SYS_CALL 0x0C00 /* System Call */ -#define EXC_OFF_TRACE 0x0D00 /* Trace */ -#define EXC_OFF_FPUNASSIST 0x0E00 /* Floating-point Assist */ - - /* 0x0E10 - 0x0FFF are marked reserved in The PowerPC Architecture book */ - /* these found in DINK code - may not apply to 8240*/ -#define EXC_OFF_PMI 0x0F00 /* Performance Monitoring Interrupt */ -#define EXC_OFF_VMXUI 0x0F20 /* VMX (AltiVec) Unavailable Interrupt */ - - /* 0x1000 - 0x2FFF are implementation specific */ - /* these found in DINK code - may not apply to 8240 */ -#define EXC_OFF_ITME 0x1000 /* Instruction Translation Miss Exception */ -#define EXC_OFF_DLTME 0x1100 /* Data Load Translation Miss Exception */ -#define EXC_OFF_DSTME 0x1200 /* Data Store Translation Miss Exception */ -#define EXC_OFF_IABE 0x1300 /* Instruction Address Breakpoint Exception */ -#define EXC_OFF_SMIE 0x1400 /* System Management Interrupt Exception */ -#define EXC_OFF_JMDDI 0x1600 /* Java Mode denorm detection Interrupt -- WTF??*/ -#define EXC_OFF_RMTE 0x2000 /* Run Mode or Trace Exception */ - -#define MAP_A_CONFIG_ADDR_HIGH 0x8000 /* Upper half of CONFIG_ADDR for Map A */ -#define MAP_A_CONFIG_ADDR_LOW 0x0CF8 /* Lower half of CONFIG_ADDR for Map A */ -#define MAP_A_CONFIG_DATA_HIGH 0x8000 /* Upper half of CONFIG_DAT for Map A */ -#define MAP_A_CONFIG_DATA_LOW 0x0CFC /* Lower half of CONFIG_DAT for Map A */ -#define MAP_B_CONFIG_ADDR_HIGH 0xfec0 /* Upper half of CONFIG_ADDR for Map B */ -#define MAP_B_CONFIG_ADDR_LOW 0x0000 /* Lower half of CONFIG_ADDR for Map B */ -#define MAP_B_CONFIG_DATA_HIGH 0xfee0 /* Upper half of CONFIG_DAT for Map B */ -#define MAP_B_CONFIG_DATA_LOW 0x0000 /* Lower half of CONFIG_DAT for Map B */ +#define EXC_OFF_RESERVED0 0x0000 /* Reserved */ +#define EXC_OFF_SYS_RESET 0x0100 /* System reset */ +#define EXC_OFF_MACH_CHCK 0x0200 /* Machine Check */ +#define EXC_OFF_DATA_STOR 0x0300 /* Data Storage */ +#define EXC_OFF_INS_STOR 0x0400 /* Instruction Storage */ +#define EXC_OFF_EXTERNAL 0x0500 /* External */ +#define EXC_OFF_ALIGN 0x0600 /* Alignment */ +#define EXC_OFF_PROGRAM 0x0700 /* Program */ +#define EXC_OFF_FPUNAVAIL 0x0800 /* Floating-point Unavailable */ +#define EXC_OFF_DECR 0x0900 /* Decrementer */ +#define EXC_OFF_RESERVED1 0x0A00 /* Reserved */ +#define EXC_OFF_RESERVED2 0x0B00 /* Reserved */ +#define EXC_OFF_SYS_CALL 0x0C00 /* System Call */ +#define EXC_OFF_TRACE 0x0D00 /* Trace */ +#define EXC_OFF_FPUNASSIST 0x0E00 /* Floating-point Assist */ + + /* 0x0E10 - 0x0FFF are marked reserved in The PowerPC Architecture book */ + /* these found in DINK code - may not apply to 8240*/ +#define EXC_OFF_PMI 0x0F00 /* Performance Monitoring Interrupt */ +#define EXC_OFF_VMXUI 0x0F20 /* VMX (AltiVec) Unavailable Interrupt */ + + /* 0x1000 - 0x2FFF are implementation specific */ + /* these found in DINK code - may not apply to 8240 */ +#define EXC_OFF_ITME 0x1000 /* Instruction Translation Miss Exception */ +#define EXC_OFF_DLTME 0x1100 /* Data Load Translation Miss Exception */ +#define EXC_OFF_DSTME 0x1200 /* Data Store Translation Miss Exception */ +#define EXC_OFF_IABE 0x1300 /* Instruction Addr Breakpoint Exception */ +#define EXC_OFF_SMIE 0x1400 /* System Management Interrupt Exception */ +#define EXC_OFF_JMDDI 0x1600 /* Java Mode denorm detect Interr -- WTF??*/ +#define EXC_OFF_RMTE 0x2000 /* Run Mode or Trace Exception */ + +#define MAP_A_CONFIG_ADDR_HIGH 0x8000 /* Upper half of CONFIG_ADDR for Map A */ +#define MAP_A_CONFIG_ADDR_LOW 0x0CF8 /* Lower half of CONFIG_ADDR for Map A */ +#define MAP_A_CONFIG_DATA_HIGH 0x8000 /* Upper half of CONFIG_DAT for Map A */ +#define MAP_A_CONFIG_DATA_LOW 0x0CFC /* Lower half of CONFIG_DAT for Map A */ +#define MAP_B_CONFIG_ADDR_HIGH 0xfec0 /* Upper half of CONFIG_ADDR for Map B */ +#define MAP_B_CONFIG_ADDR_LOW 0x0000 /* Lower half of CONFIG_ADDR for Map B */ +#define MAP_B_CONFIG_DATA_HIGH 0xfee0 /* Upper half of CONFIG_DAT for Map B */ +#define MAP_B_CONFIG_DATA_LOW 0x0000 /* Lower half of CONFIG_DAT for Map B */ #if defined(CFG_ADDR_MAP_A) -#define CONFIG_ADDR_HIGH MAP_A_CONFIG_ADDR_HIGH /* Upper half of CONFIG_ADDR */ -#define CONFIG_ADDR_LOW MAP_A_CONFIG_ADDR_LOW /* Lower half of CONFIG_ADDR */ -#define CONFIG_DATA_HIGH MAP_A_CONFIG_DATA_HIGH /* Upper half of CONFIG_DAT */ -#define CONFIG_DATA_LOW MAP_A_CONFIG_DATA_LOW /* Lower half of CONFIG_DAT */ +#define CONFIG_ADDR_HIGH MAP_A_CONFIG_ADDR_HIGH /* Upper half of CONFIG_ADDR */ +#define CONFIG_ADDR_LOW MAP_A_CONFIG_ADDR_LOW /* Lower half of CONFIG_ADDR */ +#define CONFIG_DATA_HIGH MAP_A_CONFIG_DATA_HIGH /* Upper half of CONFIG_DAT */ +#define CONFIG_DATA_LOW MAP_A_CONFIG_DATA_LOW /* Lower half of CONFIG_DAT */ #else /* Assume Map B, default */ -#define CONFIG_ADDR_HIGH MAP_B_CONFIG_ADDR_HIGH /* Upper half of CONFIG_ADDR */ -#define CONFIG_ADDR_LOW MAP_B_CONFIG_ADDR_LOW /* Lower half of CONFIG_ADDR */ -#define CONFIG_DATA_HIGH MAP_B_CONFIG_DATA_HIGH /* Upper half of CONFIG_DAT */ -#define CONFIG_DATA_LOW MAP_B_CONFIG_DATA_LOW /* Lower half of CONFIG_DAT */ +#define CONFIG_ADDR_HIGH MAP_B_CONFIG_ADDR_HIGH /* Upper half of CONFIG_ADDR */ +#define CONFIG_ADDR_LOW MAP_B_CONFIG_ADDR_LOW /* Lower half of CONFIG_ADDR */ +#define CONFIG_DATA_HIGH MAP_B_CONFIG_DATA_HIGH /* Upper half of CONFIG_DAT */ +#define CONFIG_DATA_LOW MAP_B_CONFIG_DATA_LOW /* Lower half of CONFIG_DAT */ #endif -#define CONFIG_ADDR (CONFIG_ADDR_HIGH << 16 | CONFIG_ADDR_LOW) +#define CONFIG_ADDR (CONFIG_ADDR_HIGH << 16 | CONFIG_ADDR_LOW) -#define CONFIG_DATA (CONFIG_DATA_HIGH << 16 | CONFIG_DATA_LOW) +#define CONFIG_DATA (CONFIG_DATA_HIGH << 16 | CONFIG_DATA_LOW) /*macros to wite to conif registers. addr should be a constant in all cases */ @@ -161,179 +216,192 @@ Note that some of these registers aren't documented in the manual */ -#define PCICR 0x80000004 /* PCI Command Register */ -#define PCISR 0x80000006 /* PCI Status Register */ -#define PIR 0x80000009 /* PCI Programming Interface Register */ -#define PBCCR 0x8000000b /* PCI Base Class Code Register */ -#define PCLSR 0x8000000c /* Processor Cache Line Size Register */ -#define PLTR 0x8000000d /* PCI Latancy Timer Register */ -#define PHTR 0x8000000e /* PCI Header Type Register */ -#define BISTCTRL 0x8000000f /* BIST Control */ -#define LMBAR 0x80000010 /* Local Base Addres Register */ -#define PCSRBAR 0x80000014 /* PCSR Base Address Register */ -#define ILR 0x8000003c /* PCI Interrupt Line Register */ -#define IPR 0x8000003d /* Interrupt Pin Register */ -#define MINGNT 0x8000003e /* MIN GNI */ -#define MAXLAT 0x8000003f /* MAX LAT */ -#define PCIACR 0x80000046 /* PCI Arbiter Control Register */ -#define PMCR1 0x80000070 /* Power management config. 1 */ -#define PMCR2 0x80000072 /* Power management config. 2 */ -#define ODCR 0x80000073 /* Output Driver Control Register */ -#define CLKDCR 0x80000074 /* CLK Driver Control Register */ -#define EUMBBAR 0x80000078 /* Embedded Utilities Memory Block Base Address Register */ -#define MSAR1 0x80000080 /* Memory Starting Address Register 1 */ -#define MSAR2 0x80000084 /* Memory Starting Address Register 2 */ -#define EMSAR1 0x80000088 /* Extended Memory Starting Address Register 1*/ -#define EMSAR2 0x8000008c /* Extended Memory Starting Address Register 2*/ -#define MEAR1 0x80000090 /* Memory Ending Address Register 1 */ -#define MEAR2 0x80000094 /* Memory Ending Address Register 2 */ -#define EMEAR1 0x80000098 /* Extended Memory Ending Address Register 1 */ -#define EMEAR2 0x8000009c /* Extended Memory Ending Address Register 2 */ -#define MBER 0x800000a0 /* Memory bank Enable Register*/ -#define MPMR 0x800000a3 /* Memory Page Mode Register (stores PGMAX) */ -#define PICR1 0x800000a8 /* Processor Interface Configuration Register 1 */ -#define PICR2 0x800000ac /* Processor Interface Configuration Register 2 */ -#define ECCSBECR 0x800000b8 /* ECC Single-Bit Error Counter Register */ -#define ECCSBETR 0x800000b8 /* ECC Single-Bit Error Trigger Register */ -#define ERRENR1 0x800000c0 /* Error Enableing Register 1 */ -#define ERRENR2 0x800000c0 /* Error Enableing Register 2 */ -#define ERRDR1 0x800000c1 /* Error Detection Register 1 */ -#define IPBESR 0x800000c3 /* Internal Processor Error Status Register */ -#define ERRDR2 0x800000c5 /* Error Detection Register 2 */ -#define PBESR 0x800000c7 /* PCI Bus Error Status Register */ -#define PBEAR 0x800000c8 /* Processor/PCI Bus Error Status Register */ -#define AMBOR 0x800000e0 /* Address Map B Options Register */ -#define MCCR1 0x800000f0 /* Memory Control Configuration Register 1 */ -#define MCCR2 0x800000f4 /* Memory Control Configuration Register 2 */ -#define MCCR3 0x800000f8 /* Memory Control Configuration Register 3 */ -#define MCCR4 0x800000fc /* Memory Control Configuration Register 4 */ +#define PCICR 0x80000004 /* PCI Command Register */ +#define PCISR 0x80000006 /* PCI Status Register */ +#define PIR 0x80000009 /* PCI Programming Interface Register */ +#define PBCCR 0x8000000b /* PCI Base Class Code Register */ +#define PCLSR 0x8000000c /* Processor Cache Line Size Register */ +#define PLTR 0x8000000d /* PCI Latancy Timer Register */ +#define PHTR 0x8000000e /* PCI Header Type Register */ +#define BISTCTRL 0x8000000f /* BIST Control */ +#define LMBAR 0x80000010 /* Local Base Addres Register */ +#define PCSRBAR 0x80000014 /* PCSR Base Address Register */ +#define ILR 0x8000003c /* PCI Interrupt Line Register */ +#define IPR 0x8000003d /* Interrupt Pin Register */ +#define MINGNT 0x8000003e /* MIN GNI */ +#define MAXLAT 0x8000003f /* MAX LAT */ +#define PCIACR 0x80000046 /* PCI Arbiter Control Register */ +#define PMCR1 0x80000070 /* Power management config. 1 */ +#define PMCR2 0x80000072 /* Power management config. 2 */ +#define ODCR 0x80000073 /* Output Driver Control Register */ +#define CLKDCR 0x80000074 /* CLK Driver Control Register */ +#define EUMBBAR 0x80000078 /* Embedded Utilities Memory Block Base Address Register */ +#define EUMBBAR_VAL 0x80500000 /* PCI Relocation offset for EUMB region */ +#define EUMBSIZE 0x00100000 /* Size of EUMB region */ + +#define MSAR1 0x80000080 /* Memory Starting Address Register 1 */ +#define MSAR2 0x80000084 /* Memory Starting Address Register 2 */ +#define EMSAR1 0x80000088 /* Extended Memory Starting Address Register 1*/ +#define EMSAR2 0x8000008c /* Extended Memory Starting Address Register 2*/ +#define MEAR1 0x80000090 /* Memory Ending Address Register 1 */ +#define MEAR2 0x80000094 /* Memory Ending Address Register 2 */ +#define EMEAR1 0x80000098 /* Extended Memory Ending Address Register 1 */ +#define EMEAR2 0x8000009c /* Extended Memory Ending Address Register 2 */ +#define MBER 0x800000a0 /* Memory bank Enable Register*/ +#define MPMR 0x800000a3 /* Memory Page Mode Register (stores PGMAX) */ +#define PICR1 0x800000a8 /* Processor Interface Configuration Register 1 */ +#define PICR2 0x800000ac /* Processor Interface Configuration Register 2 */ +#define ECCSBECR 0x800000b8 /* ECC Single-Bit Error Counter Register */ +#define ECCSBETR 0x800000b8 /* ECC Single-Bit Error Trigger Register */ +#define ERRENR1 0x800000c0 /* Error Enableing Register 1 */ +#define ERRENR2 0x800000c0 /* Error Enableing Register 2 */ +#define ERRDR1 0x800000c1 /* Error Detection Register 1 */ +#define IPBESR 0x800000c3 /* Internal Processor Error Status Register */ +#define ERRDR2 0x800000c5 /* Error Detection Register 2 */ +#define PBESR 0x800000c7 /* PCI Bus Error Status Register */ +#define PBEAR 0x800000c8 /* Processor/PCI Bus Error Status Register */ +#define AMBOR 0x800000e0 /* Address Map B Options Register */ +#define MCCR1 0x800000f0 /* Memory Control Configuration Register 1 */ +#define MCCR2 0x800000f4 /* Memory Control Configuration Register 2 */ +#define MCCR3 0x800000f8 /* Memory Control Configuration Register 3 */ +#define MCCR4 0x800000fc /* Memory Control Configuration Register 4 */ /* some values for soem of the above */ -#define PICR1_CF_APARK 0x00000008 -#define PICR1_LE_MODE 0x00000020 -#define PICR1_ST_GATH_EN 0x00000040 -#define PICR1_EN_PCS 0x00000080 /* according to dink code, sets the 8240 to handle pci config space */ -#define PICR1_CF_DPARK 0x00000200 -#define PICR1_MCP_EN 0x00000800 -#define PICR1_FLASH_WR_EN 0x00001000 -#define PICR1_ADDRESS_MAP 0x00010000 -#define PICR1_PROC_TYPE_MSK 0x00060000 -#define PICR1_PROC_TYPE_603E 0x00040000 -#define PICR1_RCS0 0x00100000 -#define PIRC1_MSK 0xff000000 - -#define PICR2_CF_SNOOP_WS_MASK 0x000c0000 -#define PICR2_CF_SNOOP_WS_0WS 0x00000000 -#define PICR2_CF_SNOOP_WS_1WS 0x00040000 -#define PICR2_CF_SNOOP_WS_2WS 0x00080000 -#define PICR2_CF_SNOOP_WS_3WS 0x000c0000 +#define PICR1_CF_APARK 0x00000008 +#define PICR1_LE_MODE 0x00000020 +#define PICR1_ST_GATH_EN 0x00000040 +#define PICR1_EN_PCS 0x00000080 /* according to dink code, sets the 8240 to handle pci config space */ +#define PICR1_CF_DPARK 0x00000200 +#define PICR1_MCP_EN 0x00000800 +#define PICR1_FLASH_WR_EN 0x00001000 +#define PICR1_ADDRESS_MAP 0x00010000 +#define PICR1_PROC_TYPE_MSK 0x00060000 +#define PICR1_PROC_TYPE_603E 0x00040000 +#define PICR1_RCS0 0x00100000 +#define PIRC1_MSK 0xff000000 + +#define PICR2_CF_SNOOP_WS_MASK 0x000c0000 +#define PICR2_CF_SNOOP_WS_0WS 0x00000000 +#define PICR2_CF_SNOOP_WS_1WS 0x00040000 +#define PICR2_CF_SNOOP_WS_2WS 0x00080000 +#define PICR2_CF_SNOOP_WS_3WS 0x000c0000 #define PICR2_CF_APHASE_WS_MASK 0x0000000c -#define PICR2_CF_APHASE_WS_0WS 0x00000000 -#define PICR2_CF_APHASE_WS_1WS 0x00000004 -#define PICR2_CF_APHASE_WS_2WS 0x00000008 -#define PICR2_CF_APHASE_WS_3WS 0x0000000c - -#define MCCR1_ROMNAL_SHIFT 28 -#define MCCR1_ROMNAL_MSK 0xf0000000 -#define MCCR1_ROMFAL_SHIFT 23 -#define MCCR1_ROMFAL_MSK 0x0f800000 -#define MCCR1_BURST 0x00100000 -#define MCCR1_MEMGO 0x00080000 -#define MCCR1_SREN 0x00040000 -#define MCCR1_RAM_TYPE 0x00020000 -#define MCCR1_PCKEN 0x00010000 +#define PICR2_CF_APHASE_WS_0WS 0x00000000 +#define PICR2_CF_APHASE_WS_1WS 0x00000004 +#define PICR2_CF_APHASE_WS_2WS 0x00000008 +#define PICR2_CF_APHASE_WS_3WS 0x0000000c + +#define MCCR1_ROMNAL_SHIFT 28 +#define MCCR1_ROMNAL_MSK 0xf0000000 +#define MCCR1_ROMFAL_SHIFT 23 +#define MCCR1_ROMFAL_MSK 0x0f800000 +#define MCCR1_BURST 0x00100000 +#define MCCR1_MEMGO 0x00080000 +#define MCCR1_SREN 0x00040000 +#define MCCR1_RAM_TYPE 0x00020000 +#define MCCR1_PCKEN 0x00010000 #define MCCR2_TS_WAIT_TIMER_MSK 0xe0000000 #define MCCR2_TS_WAIT_TIMER_SHIFT 29 -#define MCCR2_ASRISE_MSK 0x1e000000 -#define MCCR2_ASRISE_SHIFT 25 -#define MCCR2_ASFALL_MSK 0x01e00000 -#define MCCR2_ASFALL_SHIFT 21 +#define MCCR2_ASRISE_MSK 0x1e000000 +#define MCCR2_ASRISE_SHIFT 25 +#define MCCR2_ASFALL_MSK 0x01e00000 +#define MCCR2_ASFALL_SHIFT 21 #define MCCR2_INLINE_PAR_NOT_ECC 0x00100000 -#define MCCR2_WRITE_PARITY_CHK 0x00080000 +#define MCCR2_WRITE_PARITY_CHK 0x00080000 #define MCCR2_INLFRD_PARECC_CHK_EN 0x00040000 -#define MCCR2_ECC_EN 0x00020000 -#define MCCR2_EDO 0x00010000 -#define MCCR2_REFINT_MSK 0x0000fffc -#define MCCR2_REFINT_SHIFT 2 -#define MCCR2_RSV_PG 0x00000002 -#define MCCR2_PMW_PAR 0x00000001 - -#define MCCR3_BSTOPRE2TO5_MSK 0xf0000000 /*BSTOPRE[2-5]*/ +#define MCCR2_ECC_EN 0x00020000 +#define MCCR2_EDO 0x00010000 +#define MCCR2_REFINT_MSK 0x0000fffc +#define MCCR2_REFINT_SHIFT 2 +#define MCCR2_RSV_PG 0x00000002 +#define MCCR2_PMW_PAR 0x00000001 + +#define MCCR3_BSTOPRE2TO5_MSK 0xf0000000 /*BSTOPRE[2-5]*/ #define MCCR3_BSTOPRE2TO5_SHIFT 28 -#define MCCR3_REFREC_MSK 0x0f000000 -#define MCCR3_REFREC_SHIFT 24 -#define MCCR3_RDLAT_MSK 0x00f00000 -#define MCCR3_RDLAT_SHIFT 20 -#define MCCR3_CPX 0x00010000 -#define MCCR3_RAS6P_MSK 0x00078000 -#define MCCR3_RAS6P_SHIFT 15 -#define MCCR3_CAS5_MSK 0x00007000 -#define MCCR3_CAS5_SHIFT 12 -#define MCCR3_CP4_MSK 0x00000e00 -#define MCCR3_CP4_SHIFT 9 -#define MCCR3_CAS3_MSK 0x000001c0 -#define MCCR3_CAS3_SHIFT 6 -#define MCCR3_RCD2_MSK 0x00000038 -#define MCCR3_RCD2_SHIFT 3 -#define MCCR3_RP1_MSK 0x00000007 -#define MCCR3_RP1_SHIFT 0 - -#define MCCR4_PRETOACT_MSK 0xf0000000 -#define MCCR4_PRETOACT_SHIFT 28 -#define MCCR4_ACTTOPRE_MSK 0x0f000000 -#define MCCR4_ACTTOPRE_SHIFT 24 -#define MCCR4_WMODE 0x00800000 -#define MCCR4_INLINE 0x00400000 -#define MCCR4_BIT21 0x00200000 /* this include cos DINK code sets it- unknown function*/ -#define MCCR4_REGISTERED 0x00100000 -#define MCCR4_BSTOPRE0TO1_MSK 0x000c0000 /*BSTOPRE[0-1]*/ +#define MCCR3_REFREC_MSK 0x0f000000 +#define MCCR3_REFREC_SHIFT 24 +#define MCCR3_RDLAT_MSK 0x00f00000 +#define MCCR3_RDLAT_SHIFT 20 +#define MCCR3_CPX 0x00010000 +#define MCCR3_RAS6P_MSK 0x00078000 +#define MCCR3_RAS6P_SHIFT 15 +#define MCCR3_CAS5_MSK 0x00007000 +#define MCCR3_CAS5_SHIFT 12 +#define MCCR3_CP4_MSK 0x00000e00 +#define MCCR3_CP4_SHIFT 9 +#define MCCR3_CAS3_MSK 0x000001c0 +#define MCCR3_CAS3_SHIFT 6 +#define MCCR3_RCD2_MSK 0x00000038 +#define MCCR3_RCD2_SHIFT 3 +#define MCCR3_RP1_MSK 0x00000007 +#define MCCR3_RP1_SHIFT 0 + +#define MCCR4_PRETOACT_MSK 0xf0000000 +#define MCCR4_PRETOACT_SHIFT 28 +#define MCCR4_ACTTOPRE_MSK 0x0f000000 +#define MCCR4_ACTTOPRE_SHIFT 24 +#define MCCR4_WMODE 0x00800000 +#define MCCR4_INLINE 0x00400000 +#define MCCR4_BIT21 0x00200000 /* this include cos DINK code sets it- unknown function*/ +#define MCCR4_REGISTERED 0x00100000 +#define MCCR4_BSTOPRE0TO1_MSK 0x000c0000 /*BSTOPRE[0-1]*/ #define MCCR4_BSTOPRE0TO1_SHIFT 18 -#define MCCR4_REGDIMM 0x00008000 -#define MCCR4_SDMODE_MSK 0x00007f00 -#define MCCR4_SDMODE_SHIFT 8 -#define MCCR4_ACTTORW_MSK 0x000000f0 -#define MCCR4_ACTTORW_SHIFT 4 -#define MCCR4_BSTOPRE6TO9_MSK 0x0000000f /*BSTOPRE[0-1]*/ +#define MCCR4_REGDIMM 0x00008000 +#define MCCR4_SDMODE_MSK 0x00007f00 +#define MCCR4_SDMODE_SHIFT 8 +#define MCCR4_ACTTORW_MSK 0x000000f0 +#define MCCR4_ACTTORW_SHIFT 4 +#define MCCR4_BSTOPRE6TO9_MSK 0x0000000f /*BSTOPRE[0-1]*/ #define MCCR4_BSTOPRE6TO9_SHIFT 0 -#define MICR_ADDR_MASK 0x0ff00000 -#define MICR_ADDR_SHIFT 20 -#define MICR_EADDR_MASK 0x30000000 -#define MICR_EADDR_SHIFT 28 - -#define BATU_BEPI_MSK 0xfffe0000 -#define BATU_BL_MSK 0x00001ffc - -#define BATU_BL_128K 0x00000000 -#define BATU_BL_256K 0x00000004 -#define BATU_BL_512K 0x0000000c -#define BATU_BL_1M 0x0000001c -#define BATU_BL_2M 0x0000003c -#define BATU_BL_4M 0x0000007c -#define BATU_BL_8M 0x000000fc -#define BATU_BL_16M 0x000001fc -#define BATU_BL_32M 0x000003fc -#define BATU_BL_64M 0x000007fc -#define BATU_BL_128M 0x00000ffc -#define BATU_BL_256M 0x00001ffc - -#define BATU_VS 0x00000002 -#define BATU_VP 0x00000001 - -#define BATL_BRPN_MSK 0xfffe0000 -#define BATL_WIMG_MSK 0x00000078 -#define BATL_WRITETHROUGH 0x00000008 -#define BATL_CACHEINHIBIT 0x00000010 -#define BATL_MEMCOHERENCE 0x00000020 -#define BATL_GUARDEDSTORAGE 0x00000040 -#define BATL_PP_MSK 0x00000003 -#define BATL_PP_00 0x00000000 -#define BATL_PP_01 0x00000001 -#define BATL_PP_10 0x00000002 -#define BATL_PP_11 0x00000003 +#define MICR_ADDR_MASK 0x0ff00000 +#define MICR_ADDR_SHIFT 20 +#define MICR_EADDR_MASK 0x30000000 +#define MICR_EADDR_SHIFT 28 + +#define BATU_BEPI_MSK 0xfffe0000 +#define BATU_BL_MSK 0x00001ffc + +#define BATU_BL_128K 0x00000000 +#define BATU_BL_256K 0x00000004 +#define BATU_BL_512K 0x0000000c +#define BATU_BL_1M 0x0000001c +#define BATU_BL_2M 0x0000003c +#define BATU_BL_4M 0x0000007c +#define BATU_BL_8M 0x000000fc +#define BATU_BL_16M 0x000001fc +#define BATU_BL_32M 0x000003fc +#define BATU_BL_64M 0x000007fc +#define BATU_BL_128M 0x00000ffc +#define BATU_BL_256M 0x00001ffc + +#define BATU_VS 0x00000002 +#define BATU_VP 0x00000001 + +#define BATL_BRPN_MSK 0xfffe0000 +#define BATL_WIMG_MSK 0x00000078 +#ifndef CONFIG_MOUSSE +/* The below defines are not correct, but are in use + * for Sandpoint. + */ +#define BATL_WRITETHROUGH 0x00000008 +#define BATL_CACHEINHIBIT 0x00000010 +#define BATL_MEMCOHERENCE 0x00000020 +#define BATL_GUARDEDSTORAGE 0x00000040 +#else +#define BATL_WRITETHROUGH 0x00000040 +#define BATL_CACHEINHIBIT 0x00000020 +#define BATL_MEMCOHERENCE 0x00000010 +#define BATL_GUARDEDSTORAGE 0x00000008 +#endif /* CONFIG_MOUSSE */ +#define BATL_PP_MSK 0x00000003 +#define BATL_PP_00 0x00000000 /* No access */ +#define BATL_PP_01 0x00000001 /* Read-only */ +#define BATL_PP_10 0x00000002 /* Read-write */ +#define BATL_PP_11 0x00000003 /* I'd attempt to do defines for the PP bits, but it's use is a bit too complex, * see the PowerPC Operating Environment Architecture section in the PowerPc arch book. @@ -342,53 +410,78 @@ /*eumb and epic config*/ -#define EPIC_FPR 0x00041000 -#define EPIC_GCR 0x00041020 -#define EPIC_EICR 0x00041030 -#define EPIC_EVI 0x00041080 -#define EPIC_PI 0x00041090 -#define EPIC_SVR 0x000410E0 -#define EPIC_TFRR 0x000410F0 +#define EPIC_FPR 0x00041000 +#define EPIC_GCR 0x00041020 +#define EPIC_EICR 0x00041030 +#define EPIC_EVI 0x00041080 +#define EPIC_PI 0x00041090 +#define EPIC_SVR 0x000410E0 +#define EPIC_TFRR 0x000410F0 /*note the information for these is rather mangled in the 8240 manual. these are guesses*/ -#define EPIC_GTCCR0 0x00041100 -#define EPIC_GTCCR1 0x00041140 -#define EPIC_GTCCR2 0x00041180 -#define EPIC_GTCCR3 0x000411C0 -#define EPIC_GTBCR0 0x00041110 -#define EPIC_GTBCR1 0x00041150 -#define EPIC_GTBCR2 0x00041190 -#define EPIC_GTBCR3 0x000411D0 -#define EPIC_GTVPR0 0x00041120 -#define EPIC_GTVPR1 0x00041160 -#define EPIC_GTVPR2 0x000411a0 -#define EPIC_GTVPR3 0x000411e0 -#define EPIC_GTDR0 0x00041130 -#define EPIC_GTDR1 0x00041170 -#define EPIC_GTDR2 0x000411b0 -#define EPIC_GTDR3 0x000411f0 - -#define EPIC_IVPR0 0x00050200 -#define EPIC_IVPR1 0x00050220 -#define EPIC_IVPR2 0x00050240 -#define EPIC_IVPR3 0x00050260 -#define EPIC_IVPR4 0x00050280 - -#define EPIC_SVPR0 0x00050200 -#define EPIC_SVPR1 0x00050220 -#define EPIC_SVPR2 0x00050240 -#define EPIC_SVPR3 0x00050260 -#define EPIC_SVPR4 0x00050280 -#define EPIC_SVPR5 0x000502A0 -#define EPIC_SVPR6 0x000502C0 -#define EPIC_SVPR7 0x000502E0 -#define EPIC_SVPR8 0x00050300 -#define EPIC_SVPR9 0x00050320 -#define EPIC_SVPRa 0x00050340 -#define EPIC_SVPRb 0x00050360 -#define EPIC_SVPRc 0x00050380 -#define EPIC_SVPRd 0x000503A0 -#define EPIC_SVPRe 0x000503C0 -#define EPIC_SVPRf 0x000503E0 +#define EPIC_GTCCR0 0x00041100 +#define EPIC_GTCCR1 0x00041140 +#define EPIC_GTCCR2 0x00041180 +#define EPIC_GTCCR3 0x000411C0 +#define EPIC_GTBCR0 0x00041110 +#define EPIC_GTBCR1 0x00041150 +#define EPIC_GTBCR2 0x00041190 +#define EPIC_GTBCR3 0x000411D0 +#define EPIC_GTVPR0 0x00041120 +#define EPIC_GTVPR1 0x00041160 +#define EPIC_GTVPR2 0x000411a0 +#define EPIC_GTVPR3 0x000411e0 +#define EPIC_GTDR0 0x00041130 +#define EPIC_GTDR1 0x00041170 +#define EPIC_GTDR2 0x000411b0 +#define EPIC_GTDR3 0x000411f0 + +#define EPIC_IVPR0 0x00050200 +#define EPIC_IVPR1 0x00050220 +#define EPIC_IVPR2 0x00050240 +#define EPIC_IVPR3 0x00050260 +#define EPIC_IVPR4 0x00050280 + +#define EPIC_SVPR0 0x00050200 +#define EPIC_SVPR1 0x00050220 +#define EPIC_SVPR2 0x00050240 +#define EPIC_SVPR3 0x00050260 +#define EPIC_SVPR4 0x00050280 +#define EPIC_SVPR5 0x000502A0 +#define EPIC_SVPR6 0x000502C0 +#define EPIC_SVPR7 0x000502E0 +#define EPIC_SVPR8 0x00050300 +#define EPIC_SVPR9 0x00050320 +#define EPIC_SVPRa 0x00050340 +#define EPIC_SVPRb 0x00050360 +#define EPIC_SVPRc 0x00050380 +#define EPIC_SVPRd 0x000503A0 +#define EPIC_SVPRe 0x000503C0 +#define EPIC_SVPRf 0x000503E0 + +/* MPC8240 Byte Swap/PCI Support Macros */ +#define BYTE_SWAP_16_BIT(x) ( (((x) & 0x00ff) << 8) | ( (x) >> 8) ) +#define LONGSWAP(x) ((((x) & 0x000000ff) << 24) | (((x) & 0x0000ff00) << 8)|\ + (((x) & 0x00ff0000) >> 8) | (((x) & 0xff000000) >> 24) ) +#define PCISWAP(x) LONGSWAP(x) + +#ifndef __ASSEMBLY__ +/* + * MPC107 Support + * + */ +unsigned int mpc8240_mpc107_getreg(unsigned int regNum); +void mpc8240_mpc107_setreg(unsigned int regNum, unsigned int regVal); +void mpc8240_mpc107_write8(unsigned int address, unsigned char data); +void mpc8240_mpc107_write16(unsigned int address, unsigned short data); +void mpc8240_mpc107_write32(unsigned int address, unsigned int data); +unsigned char mpc8240_mpc107_read8(unsigned int address); +unsigned short mpc8240_mpc107_read16(unsigned int address); +unsigned int mpc8240_mpc107_read32(unsigned int address); +unsigned int mpc8240_eummbar_read(unsigned int regNum); +void mpc8240_eummbar_write(unsigned int regNum, unsigned int regVal); +unsigned long get_gclk_freq(void); + +#endif /* __ASSEMBLY__ */ #endif /* __MPC8240_H__ */