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.
####################################################################
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
LIST="$LIST \
CU824 \
+ MOUSSE \
Sandpoint8240 \
"
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:
echo "CPU = mpc8240" >>config.mk ; \
echo "#include <config_$(@:_config=).h>" >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_$(@:_config=).h>" >config.h
+
Sandpoint8240_config: unconfig
@echo "Configuring for $(@:_config=) Board..." ; \
cd include ; \
--- /dev/null
+#
+# (C) Copyright 2001
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+include $(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
+
+#########################################################################
--- /dev/null
+
+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=<IP ADDRESS>
+netmask=<NETMASK>
+hostname=<NAME>
+serverip=<NFS SERVER IP ADDRESS>
+ethaddr=00:00:10:20:30:44
+nfsroot=<NFS SERVER IP ADDRESS>:/boot/root-fs
+gateway=<IP ADDRESS>
+root=/dev/nfs
+stdin=serial
+stdout=serial
+stderr=serial
+
+NVRAM environment variables.
+
+use the command:
+
+setenv <attribute> <value>
+
+type "saveenv" to write to NVRAM.
+
+
+
+II. To boot from a hard drive:
+
+setenv root /dev/hda1
+
+
+III. IP options which configure the network:
+
+ipaddr=<IP ADDRESS OF MACHINE>
+netmask=<NETMASK>
+hostname=mousse
+ethaddr=00:00:10:20:30:44
+gateway=<IP ADDRESS OF GATEWAY/ROUTER>
+
+
+IV. IP Options which configure NFS Root/Boot Support
+
+root=/dev/nfs
+serverip=<NFS SERVER IP ADDRESS>
+nfsroot=<NFS SERVER IP ADDRESS>:/boot/root-fs
+
+V. 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#
--- /dev/null
+#
+# (C) Copyright 2001
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+#
+# MOUSSE boards
+#
+TEXT_BASE = 0xFFF00000
+PLATFORM_CPPFLAGS += -DTEXT_BASE=$(TEXT_BASE)
--- /dev/null
+/*
+ * 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 <ppcboot.h>
+#include <mpc8240.h>
+#include <net.h>
+#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<PS,FD> = 1,1 (DE4X5_OMR)
+ * CSR6<OM> = 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;
+}
+
--- /dev/null
+/*
+ * MOUSSE/MPC8240 Board definitions.
+ * Flash Routines for MOUSSE onboard AMD29LV106DB devices
+ *
+ * (C) Copyright 2000
+ * Marius Groeger <mgroeger@sysgo.de>
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ *
+ * (C) Copyright 2000
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * (C) Copyright 1999, by Curt McDowell, 08-06-99, Broadcom Corp.
+ * (C) Copyright 2001, James Dougherty, 07/18/01, Broadcom Corp.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <ppcboot.h>
+#include <mpc8xx.h>
+#include <malloc.h>
+#include "mousse.h"
+#include "flash.h"
+
+int flashLibDebug = 0;
+int flashLibInited = 0;
+
+#define OK 0
+#define ERROR -1
+#define STATUS int
+#define PRINTF if (flashLibDebug) printf
+#if 0
+#define PRIVATE static
+#else
+#define PRIVATE
+#endif
+
+flash_info_t flash_info[CFG_MAX_FLASH_BANKS];
+
+#define SLEEP_DELAY 166
+#define FLASH_SECTOR_SIZE (64*1024)
+/***********************************************************************
+ *
+ * Virtual Flash Devices on Mousse board
+ *
+ * These must be kept in sync with the definitions in flashLib.h.
+ *
+ ***********************************************************************/
+
+PRIVATE flash_dev_t flashDev[] = {
+ /* Bank 0 sector SA0 (16 kB) */
+ { "SA0",FLASH0_BANK, FLASH0_SEG0_START, 1, 14,
+ FLASH0_VENDOR_ID, FLASH0_DEVICE_ID
+ },
+ /* Bank 0 sector SA1 (8 kB) */
+ { "SA1", FLASH0_BANK, FLASH0_SEG0_START + 0x4000, 1, 13,
+ FLASH0_VENDOR_ID, FLASH0_DEVICE_ID
+ },
+ /* Bank 0 sector SA2 (8 kB) */
+ { "SA2", FLASH0_BANK, FLASH0_SEG0_START + 0x6000, 1, 13,
+ FLASH0_VENDOR_ID, FLASH0_DEVICE_ID
+ },
+ /* Bank 0 sector SA3 is occluded by Mousse I/O devices */
+ /* Bank 0 sectors SA4-SA18, after Mousse devices up to PLCC (960 kB) */
+ { "KERNEL", FLASH0_BANK, FLASH0_SEG1_START, 15, 16,
+ FLASH0_VENDOR_ID, FLASH0_DEVICE_ID
+ },
+ /* Bank 0 sectors SA19-SA26, jumper can occlude this by PLCC (512 kB) */
+ /* This is where the Kahlua boot vector and boot ROM code resides. */
+ { "BOOT",FLASH0_BANK, FLASH0_SEG2_START, 8, 16,
+ FLASH0_VENDOR_ID, FLASH0_DEVICE_ID
+ },
+ /* Bank 0 sectors SA27-SA34 (512 kB) */
+ { "RAMDISK",FLASH0_BANK, FLASH0_SEG3_START, 8, 16,
+ FLASH0_VENDOR_ID, FLASH0_DEVICE_ID
+ },
+};
+
+int flashDevCount = (sizeof (flashDev) / sizeof (flashDev[0]));
+
+#define DEV(no) (&flashDev[no])
+#define DEV_NO(dev) ((dev) - flashDev)
+
+/***********************************************************************
+ *
+ * Private Flash Routines
+ *
+ ***********************************************************************/
+
+/*
+ * The convention is:
+ *
+ * "addr" is always the PROM raw address, which is the address of an
+ * 8-bit quantity for flash 0 and 16-bit quantity for flash 1.
+ *
+ * "pos" is always a logical byte position from the PROM beginning.
+ */
+
+#define FLASH0_ADDR(dev, addr) \
+ ((unsigned char *) ((dev)->base + (addr)))
+
+#define FLASH0_WRITE(dev, addr, value) \
+ (*FLASH0_ADDR(dev, addr) = (value))
+
+#define FLASH0_READ(dev, addr) \
+ (*FLASH0_ADDR(dev, addr))
+
+PRIVATE int flashCheck(flash_dev_t *dev)
+{
+ if (! flashLibInited) {
+ printf("flashCheck: flashLib not initialized\n");
+ return ERROR;
+ }
+
+ if (dev < &flashDev[0] || dev >= &flashDev[flashDevCount]) {
+ printf("flashCheck: Bad dev parameter\n");
+ return ERROR;
+ }
+
+ if (! dev->found) {
+ printf("flashCheck: Device %d not available\n", DEV_NO(dev));
+ return ERROR;
+ }
+
+ return OK;
+}
+
+PRIVATE void flashReset(flash_dev_t *dev)
+{
+ PRINTF("flashReset: dev=%d\n", DEV_NO(dev));
+
+ if (dev->bank == FLASH0_BANK) {
+ FLASH0_WRITE(dev, 0x555, 0xaa);
+ FLASH0_WRITE(dev, 0xaaa, 0x55);
+ FLASH0_WRITE(dev, 0x555, 0xf0);
+ }
+
+ udelay(SLEEP_DELAY);
+
+ PRINTF("flashReset: done\n");
+}
+
+PRIVATE int flashProbe(flash_dev_t *dev)
+{
+ int rv, deviceID, vendorID;
+
+ PRINTF("flashProbe: dev=%d\n", DEV_NO(dev));
+
+ if (dev->bank == FLASH0_BANK) {
+ 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; i<info->sector_count; ++i) {
+ if ((i % 5) == 0)
+ printf ("\n ");
+ printf (" %08lX%s",
+ info->start[FIRST_SECTOR] + i*FLASH_SECTOR_SIZE,
+ info->protect[i] ? " (RO)" : " "
+ );
+ }
+ printf ("\n");
+}
+
+
+/*
+ * Erase a range of flash sectors.
+ */
+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; i<l; ++i, ++cp) {
+ data = (data << 8) | (*(uchar *)cp);
+ }
+ for (; i<4 && cnt>0; ++i) {
+ data = (data << 8) | *src++;
+ --cnt;
+ ++cp;
+ }
+ for (; cnt==0 && i<4; ++i, ++cp) {
+ data = (data << 8) | (*(uchar *)cp);
+ }
+ if ((rc = write_word(info, wp, data)) != 0) {
+ return (rc);
+ }
+ wp += 4;
+ }
+
+ /*
+ * handle word aligned part
+ */
+ while (cnt >= 4) {
+ data = 0;
+ for (i=0; i<4; ++i) {
+ data = (data << 8) | *src++;
+ }
+ if ((rc = write_word(info, wp, data)) != 0) {
+ return (rc);
+ }
+ wp += 4;
+ cnt -= 4;
+ }
+
+ if (cnt == 0) {
+ return (0);
+ }
+
+ /*
+ * handle unaligned tail bytes
+ */
+ data = 0;
+ for (i=0, cp=wp; i<4 && cnt>0; ++i, ++cp) {
+ data = (data << 8) | *src++;
+ --cnt;
+ }
+ for (; i<4; ++i, ++cp) {
+ data = (data << 8) | (*(uchar *)cp);
+ }
+
+ return (write_word(info, wp, data));
+ }
+ return 1;
+}
+
+/*-----------------------------------------------------------------------
+ */
--- /dev/null
+#ifndef FLASH_LIB_H
+#define FLASH_LIB_H
+
+#include <ppcboot.h>
+
+/* PIO operations max */
+#define FLASH_PROGRAM_POLLS 100000
+
+/* 10 Seconds default */
+#define FLASH_ERASE_SECTOR_TIMEOUT (10*1000 /*SEC*/ )
+
+/* Flash device info structure */
+typedef struct flash_dev_s {
+ char name[24]; /* Bank Name */
+ int bank; /* Bank 0 or 1 */
+ unsigned int base; /* Base address */
+ int sectors; /* Sector count */
+ int lgSectorSize; /* Log2(usable bytes/sector) */
+ int vendorID; /* Expected vendor ID */
+ int deviceID; /* Expected device ID */
+ int found; /* Set if found by flashLibInit */
+ int swap; /* Set for bank 1 if byte swap req'd */
+} flash_dev_t;
+
+#define FLASH_MAX_POS(dev) \
+ ((dev)->sectors << (dev)->lgSectorSize)
+
+#define FLASH_SECTOR_POS(dev, sector) \
+ ((sector) << (dev)->lgSectorSize)
+
+/* AMD 29F040 */
+#define FLASH0_BANK 0
+#define FLASH0_VENDOR_ID 0x01
+#define FLASH0_DEVICE_ID 0x49
+
+/* AMD29LV160DB */
+#define FLASH1_BANK 1
+#define FLASH1_VENDOR_ID 0x0001
+#define FLASH1_DEVICE_ID 0x2249
+
+extern flash_dev_t flashDev[];
+extern int flashDevCount;
+
+/*
+ * Device pointers
+ *
+ * These must be kept in sync with the table in flashLib.c.
+ */
+#define FLASH_DEV_BANK0_SA0 (&flashDev[0])
+#define FLASH_DEV_BANK0_SA1 (&flashDev[1])
+#define FLASH_DEV_BANK0_SA2 (&flashDev[2])
+#define FLASH_DEV_BANK0_LOW (&flashDev[3]) /* 960K */
+#define FLASH_DEV_BANK0_BOOT (&flashDev[4]) /* PLCC */
+#define FLASH_DEV_BANK0_HIGH (&flashDev[5]) /* 512K PLCC shadow */
+
+unsigned long flash_init(void);
+int flashEraseSector(flash_dev_t *dev, int sector);
+int flashErase(flash_dev_t *dev);
+int flashRead(flash_dev_t *dev, int pos, char *buf, int len);
+int flashWrite(flash_dev_t *dev, int pos, char *buf, int len);
+int flashWritable(flash_dev_t *dev, int pos, int len);
+int flashDiag(flash_dev_t *dev);
+int flashDiagAll(void);
+
+ulong flash_get_size (vu_long *addr, flash_info_t *info);
+void flash_print_info (flash_info_t *info);
+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 */
--- /dev/null
+/*
+ * 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 <ppcboot.h>
+#include <rtc.h>
+#include "mousse.h"
+
+/*
+ * Imported from mousse.h:
+ *
+ * TOD_REG_BASE Base of m48t59y TOD registers
+ * SYS_TOD_UNPROTECT() Disable NVRAM write protect
+ * SYS_TOD_PROTECT() Re-enable NVRAM write protect
+ */
+
+#define YEAR 0xf
+#define MONTH 0xe
+#define DAY 0xd
+#define DAY_OF_WEEK 0xc
+#define HOUR 0xb
+#define MINUTE 0xa
+#define SECOND 0x9
+#define CONTROL 0x8
+#define WATCH 0x7
+#define INTCTL 0x6
+#define WD_DATE 0x5
+#define WD_HOUR 0x4
+#define WD_MIN 0x3
+#define WD_SEC 0x2
+#define _UNUSED 0x1
+#define FLAGS 0x0
+
+#define M48_ADDR ((volatile unsigned char *) TOD_REG_BASE)
+
+int m48_tod_init(void)
+{
+ SYS_TOD_UNPROTECT();
+
+ M48_ADDR[CONTROL] = 0;
+ M48_ADDR[WATCH] = 0;
+ M48_ADDR[INTCTL] = 0;
+
+ /*
+ * If the oscillator is currently stopped (as on a new part shipped
+ * from the factory), start it running.
+ *
+ * Here is an example of the TOD bytes on a brand new M48T59Y part:
+ * 00 00 00 00 00 00 00 00 00 88 8c c3 bf c8 f5 01
+ */
+
+ if (M48_ADDR[SECOND] & 0x80)
+ M48_ADDR[SECOND] = 0;
+
+ /* Is battery low */
+ if ( M48_ADDR[FLAGS] & 0x10) {
+ printf("NOTICE: Battery low on Real-Time Clock (replace SNAPHAT).\n");
+ }
+
+ SYS_TOD_PROTECT();
+
+ return 0;
+}
+
+/*
+ * m48_tod_set
+ */
+
+static int to_bcd(int value)
+{
+ return value / 10 * 16 + value % 10;
+}
+
+static int from_bcd(int value)
+{
+ return value / 16 * 10 + value % 16;
+}
+
+static int day_of_week(int y, int m, int d) /* 0-6 ==> Sun-Sat */
+{
+ static int t[] = {0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4};
+ y -= m < 3;
+ return (y + y/4 - y/100 + y/400 + t[m-1] + d) % 7;
+}
+
+/*
+ * Note: the TOD should store the current GMT
+ */
+
+int m48_tod_set(int year, /* 1980-2079 */
+ int month, /* 01-12 */
+ int day, /* 01-31 */
+ int hour, /* 00-23 */
+ int minute, /* 00-59 */
+ int second) /* 00-59 */
+
+{
+ SYS_TOD_UNPROTECT();
+
+ M48_ADDR[CONTROL] |= 0x80; /* Set WRITE bit */
+
+ M48_ADDR[YEAR] = to_bcd(year % 100);
+ M48_ADDR[MONTH] = to_bcd(month);
+ M48_ADDR[DAY] = to_bcd(day);
+ M48_ADDR[DAY_OF_WEEK] = day_of_week(year, month, day) + 1;
+ M48_ADDR[HOUR] = to_bcd(hour);
+ M48_ADDR[MINUTE] = to_bcd(minute);
+ M48_ADDR[SECOND] = to_bcd(second);
+
+ M48_ADDR[CONTROL] &= ~0x80; /* Clear WRITE bit */
+
+ SYS_TOD_PROTECT();
+
+ return 0;
+}
+
+/*
+ * Note: the TOD should store the current GMT
+ */
+
+int m48_tod_get(int *year, /* 1980-2079 */
+ int *month, /* 01-12 */
+ int *day, /* 01-31 */
+ int *hour, /* 00-23 */
+ int *minute, /* 00-59 */
+ int *second) /* 00-59 */
+{
+ int y;
+
+ SYS_TOD_UNPROTECT();
+
+ M48_ADDR[CONTROL] |= 0x40; /* Set READ bit */
+
+ y = from_bcd(M48_ADDR[YEAR]);
+ *year = y < 80 ? 2000 + y : 1900 + y;
+ *month = from_bcd(M48_ADDR[MONTH]);
+ *day = from_bcd(M48_ADDR[DAY]);
+ /* day_of_week = M48_ADDR[DAY_OF_WEEK] & 0xf; */
+ *hour = from_bcd(M48_ADDR[HOUR]);
+ *minute = from_bcd(M48_ADDR[MINUTE]);
+ *second = from_bcd(M48_ADDR[SECOND] & 0x7f);
+
+ M48_ADDR[CONTROL] &= ~0x40; /* Clear READ bit */
+
+ SYS_TOD_PROTECT();
+
+ return 0;
+}
+
+int m48_tod_get_second(void)
+{
+ return from_bcd(M48_ADDR[SECOND] & 0x7f);
+}
+
+/*
+ * Watchdog function
+ *
+ * If usec is 0, the watchdog timer is disarmed.
+ *
+ * If usec is non-zero, the watchdog timer is armed (or re-armed) for
+ * approximately usec microseconds (if the exact requested usec is
+ * not supported by the chip, the next higher available value is used).
+ *
+ * Minimum watchdog timeout = 62500 usec
+ * Maximum watchdog timeout = 124 sec (124000000 usec)
+ */
+
+void m48_watchdog_arm(int usec)
+{
+ int mpy, res;
+
+ SYS_TOD_UNPROTECT();
+
+ if (usec == 0) {
+ res = 0;
+ mpy = 0;
+ } else if (usec < 2000000) { /* Resolution: 1/16s if below 2s */
+ res = 0;
+ mpy = (usec + 62499) / 62500;
+ } else if (usec < 8000000) { /* Resolution: 1/4s if below 8s */
+ res = 1;
+ mpy = (usec + 249999) / 250000;
+ } else if (usec < 32000000) { /* Resolution: 1s if below 32s */
+ res = 2;
+ mpy = (usec + 999999) / 1000000;
+ } else { /* Resolution: 4s up to 124s */
+ res = 3;
+ mpy = (usec + 3999999) / 4000000;
+ if (mpy > 31)
+ mpy = 31;
+ }
+
+ M48_ADDR[WATCH] = (0x80 | /* Steer to RST signal (IRQ = N/C) */
+ mpy << 2 |
+ res);
+
+ SYS_TOD_PROTECT();
+}
+
+/*
+ * 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();
+}
+
--- /dev/null
+/*
+ * 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 */
--- /dev/null
+/*
+ * 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 <ppcboot.h>
+#include <mpc8240.h>
+#include <asm/processor.h>
+
+#include "mousse.h"
+#include "m48t59y.h"
+#include "pci.h"
+
+
+int checkboard(void)
+{
+ ulong busfreq = get_bus_freq(0);
+ char buf[32];
+
+ 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;
+}
--- /dev/null
+/*
+ * 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 */
--- /dev/null
+/*
+ * (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 <config.h>
+#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;
+}
--- /dev/null
+/*
+ * (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 */
--- /dev/null
+/*
+ *
+ * (C) Copyright 2000
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * (C) Copyright 2001
+ * James Dougherty (jfd@cs.stanford.edu)
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/*
+ * PCI Configuration space access support for MPC8240/MPC107 PCI Bridge
+ */
+#include <ppcboot.h>
+#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;
+}
+
+
--- /dev/null
+/*
+ * (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 */
--- /dev/null
+/*
+ * (C) Copyright 2001
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+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 = .);
+}
+
--- /dev/null
+/*
+ * (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 = .);
+}
+
--- /dev/null
+/*
+ * (C) Copyright 2001
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+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 = .);
+}
+
--- /dev/null
+/*
+ * (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 <ppcboot.h>
+#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);
+}
+
--- /dev/null
+/*
+ * (C) Copyright 2001
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <ppcboot.h>
+#include <mpc8240.h>
+#include <asm/processor.h>
+
+
+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;
+}
+
+/* ------------------------------------------------------------------------- */
+
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));
}
/* ------------------------------------------------------------------------- */
+
+/*
+ * 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;
+}
+
+/* ------------------------------------------------------------------------- */
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*/
*/
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 */
}
#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 */
{
--- /dev/null
+/*
+ * (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 <cmd_confdefs.h>
+#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 */
+
+
#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
/*
* 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.
#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 */
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.
/*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__ */