]> git.kernelconcepts.de Git - karo-tx-uboot.git/commitdiff
Patch by TsiChung Liew, 23 Sep 2004:
authorwdenk <wdenk>
Thu, 28 Oct 2004 00:09:35 +0000 (00:09 +0000)
committerwdenk <wdenk>
Thu, 28 Oct 2004 00:09:35 +0000 (00:09 +0000)
- add support for MPC8220 CPU
- Add support for Alaska and Yukon boards

43 files changed:
CHANGELOG
MAKEALL
Makefile
README
board/alaska/Makefile [new file with mode: 0644]
board/alaska/alaska.c [new file with mode: 0644]
board/alaska/config.mk [new file with mode: 0644]
board/alaska/extserial.c [new file with mode: 0644]
board/alaska/flash.c [new file with mode: 0644]
board/alaska/serial.c [new file with mode: 0644]
board/alaska/u-boot.lds [new file with mode: 0644]
common/cmd_bdinfo.c
common/cmd_bootm.c
cpu/mpc8220/Makefile [new file with mode: 0644]
cpu/mpc8220/config.mk [new file with mode: 0644]
cpu/mpc8220/cpu.c [new file with mode: 0644]
cpu/mpc8220/cpu_init.c [new file with mode: 0644]
cpu/mpc8220/dma.h [new file with mode: 0644]
cpu/mpc8220/dramSetup.c [new file with mode: 0644]
cpu/mpc8220/dramSetup.h [new file with mode: 0644]
cpu/mpc8220/fec.c [new file with mode: 0644]
cpu/mpc8220/fec.h [new file with mode: 0644]
cpu/mpc8220/fec_dma_tasks.S [new file with mode: 0644]
cpu/mpc8220/i2c.c [new file with mode: 0644]
cpu/mpc8220/i2cCore.c [new file with mode: 0644]
cpu/mpc8220/i2cCore.h [new file with mode: 0644]
cpu/mpc8220/interrupts.c [new file with mode: 0644]
cpu/mpc8220/io.S [new file with mode: 0644]
cpu/mpc8220/loadtask.c [new file with mode: 0644]
cpu/mpc8220/speed.c [new file with mode: 0644]
cpu/mpc8220/start.S [new file with mode: 0644]
cpu/mpc8220/traps.c [new file with mode: 0644]
cpu/mpc8220/uart.c [new file with mode: 0644]
doc/README.alaska8220 [new file with mode: 0644]
include/asm-ppc/global_data.h
include/asm-ppc/immap_8220.h [new file with mode: 0644]
include/asm-ppc/u-boot.h
include/common.h
include/configs/Alaska8220.h [new file with mode: 0644]
include/mpc8220.h [new file with mode: 0644]
include/ppc_asm.tmpl
lib_ppc/board.c
net/eth.c

index baa3bb828dccd40e4d19fedfd31bc00aee208f69..693ead40c3ab00b1c605644f9268ebe7250460ae 100644 (file)
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -2,6 +2,10 @@
 Changes since U-Boot 1.1.1:
 ======================================================================
 
+* Patch by TsiChung Liew, 23 Sep 2004:
+  - add support for MPC8220 CPU
+  - Add support for Alaska and Yukon boards
+
 * Fix configuration for ERIC board (needs more room)
 
 * Adjust MIPS compiler options at run-time depending on tools version
diff --git a/MAKEALL b/MAKEALL
index ed9b9de1fe0a60d106623fcd860826e37c27494f..e070b0d0ee00636aab7560879de5636f065dc9c5 100644 (file)
--- a/MAKEALL
+++ b/MAKEALL
@@ -71,6 +71,14 @@ LIST_4xx="   \
        WALNUT405       XPEDITE1K                                       \
 "
 
+#########################################################################
+## MPC8220 Systems
+#########################################################################
+
+LIST_8220="    \
+       Alaska8220      Yukon8220                                       \
+"
+
 #########################################################################
 ## MPC824x Systems
 #########################################################################
@@ -228,7 +236,7 @@ build_target() {
 for arg in $@
 do
        case "$arg" in
-       ppc|5xx|5xxx|8xx|824x|8260|85xx|4xx|7xx|74xx| \
+       ppc|5xx|5xxx|8xx|8220|824x|8260|85xx|4xx|7xx|74xx| \
        arm|SA|ARM7|ARM9|pxa|ixp| \
        microblaze| \
        mips| \
index bdfc99af193dd06fa87188b9e75c8d5283aad7bf..f2965f78865117b1e0b20da8d11b6791ed6c6311 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -825,6 +825,15 @@ WALNUT405_config:  unconfig
 XPEDITE1K_config:      unconfig
        @./mkconfig $(@:_config=) ppc ppc4xx xpedite1k
 
+#########################################################################
+## MPC8220 Systems
+#########################################################################
+Alaska8220_config:     unconfig
+       @./mkconfig $(@:_config=) ppc mpc8220 alaska
+
+Yukon8220_config:      unconfig
+       @./mkconfig $(@:_config=) ppc mpc8220 yukon
+
 #########################################################################
 ## MPC824x Systems
 #########################################################################
diff --git a/README b/README
index 8ea41f86a5da22b573ffa69ecfd89ff6790532db..294f8f704df0b9f21568e6255f361cf0ee48a45b 100644 (file)
--- a/README
+++ b/README
@@ -123,24 +123,25 @@ Directory Hierarchy:
 - board                Board dependent files
 - common       Misc architecture independent functions
 - cpu          CPU specific files
-  - 74xx_7xx   Files specific to Motorola MPC74xx and 7xx CPUs
+  - 74xx_7xx   Files specific to Freescale MPC74xx and 7xx CPUs
   - arm720t    Files specific to ARM 720 CPUs
   - arm920t    Files specific to ARM 920 CPUs
-    - imx      Files specific to Motorola MC9328 i.MX CPUs
+    - imx      Files specific to Freescale MC9328 i.MX CPUs
     - s3c24x0  Files specific to Samsung S3C24X0 CPUs
   - arm925t    Files specific to ARM 925 CPUs
   - arm926ejs  Files specific to ARM 926 CPUs
   - at91rm9200 Files specific to Atmel AT91RM9200 CPUs
   - i386       Files specific to i386 CPUs
   - ixp                Files specific to Intel XScale IXP CPUs
-  - mcf52x2    Files specific to Motorola ColdFire MCF52x2 CPUs
+  - mcf52x2    Files specific to Freescale ColdFire MCF52x2 CPUs
   - mips       Files specific to MIPS CPUs
-  - mpc5xx     Files specific to Motorola MPC5xx  CPUs
-  - mpc5xxx    Files specific to Motorola MPC5xxx CPUs
-  - mpc8xx     Files specific to Motorola MPC8xx  CPUs
-  - mpc824x    Files specific to Motorola MPC824x CPUs
-  - mpc8260    Files specific to Motorola MPC8260 CPUs
-  - mpc85xx    Files specific to Motorola MPC85xx CPUs
+  - mpc5xx     Files specific to Freescale MPC5xx  CPUs
+  - mpc5xxx    Files specific to Freescale MPC5xxx CPUs
+  - mpc8xx     Files specific to Freescale MPC8xx  CPUs
+  - mpc8220    Files specific to Freescale MPC8220 CPUs
+  - mpc824x    Files specific to Freescale MPC824x CPUs
+  - mpc8260    Files specific to Freescale MPC8260 CPUs
+  - mpc85xx    Files specific to Freescale MPC85xx CPUs
   - nios       Files specific to Altera NIOS CPUs
   - nios2      Files specific to Altera Nios-II CPUs
   - ppc4xx     Files specific to IBM PowerPC 4xx CPUs
@@ -229,6 +230,7 @@ The following options need to be configured:
                -------------------
                CONFIG_MPC823,  CONFIG_MPC850,  CONFIG_MPC855,  CONFIG_MPC860
        or      CONFIG_MPC5xx
+       or      CONFIG_MPC8220
        or      CONFIG_MPC824X, CONFIG_MPC8260
        or      CONFIG_MPC85xx
        or      CONFIG_IOP480
@@ -2140,6 +2142,7 @@ configurations; the following names are supported:
 
        ADCIOP_config           FPS860L_config          omap730p2_config
        ADS860_config           GEN860T_config          pcu_e_config
+       Alaska8220_config
        AR405_config            GENIETV_config          PIP405_config
        at91rm9200dk_config     GTH_config              QS823_config
        CANBT_config            hermes_config           QS850_config
@@ -2161,6 +2164,7 @@ configurations; the following names are supported:
        FADS860T_config         omap1610inn_config      TQM855L_config
        FPS850L_config          omap5912osk_config      TQM860L_config
                                                        WALNUT405_config
+                                                       Yukon8220_config
                                                        ZPC1900_config
 
 Note: for some board special configuration names may exist; check if
diff --git a/board/alaska/Makefile b/board/alaska/Makefile
new file mode 100644 (file)
index 0000000..d2b5bb7
--- /dev/null
@@ -0,0 +1,45 @@
+# (C) Copyright 2003-2004
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+include $(TOPDIR)/config.mk
+
+LIB    = lib$(BOARD).a
+
+OBJS   := $(BOARD).o flash.o extserial.o serial.o
+
+$(LIB):        $(OBJS) $(SOBJS)
+       $(AR) crv $@ $(OBJS)
+
+clean:
+       rm -f $(SOBJS) $(OBJS)
+
+distclean:     clean
+       rm -f $(LIB) core *.bak .depend
+
+#########################################################################
+
+.depend:       Makefile $(SOBJS:.o=.S) $(OBJS:.o=.c)
+               $(CC) -M $(CPPFLAGS) $(SOBJS:.o=.S) $(OBJS:.o=.c) > $@
+
+-include .depend
+
+#########################################################################
diff --git a/board/alaska/alaska.c b/board/alaska/alaska.c
new file mode 100644 (file)
index 0000000..93874b2
--- /dev/null
@@ -0,0 +1,153 @@
+/*
+ * (C) Copyright 2004, Freescale Inc.
+ * TsiChung Liew, Tsi-Chung.Liew@freescale.com
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <mpc8220.h>
+#include <asm/processor.h>
+#include <asm/mmu.h>
+
+void setupBat (ulong size)
+{
+       ulong batu, batl;
+       int blocksize = 0;
+
+       /* Flash 0 */
+#if defined (CFG_AMD_BOOT)
+       batu = CFG_FLASH0_BASE | (BL_512K << 2) | BPP_RW | BPP_RX;
+#else
+       batu = CFG_FLASH0_BASE | (BL_16M << 2) | BPP_RW | BPP_RX;
+#endif
+       batl = CFG_FLASH0_BASE | 0x22;
+       write_bat (IBAT0, batu, batl);
+       write_bat (DBAT0, batu, batl);
+
+       /* Flash 1 */
+#if defined (CFG_AMD_BOOT)
+       batu = CFG_FLASH1_BASE | (BL_16M << 2) | BPP_RW | BPP_RX;
+#else
+       batu = CFG_FLASH1_BASE | (BL_512K << 2) | BPP_RW | BPP_RX;
+#endif
+       batl = CFG_FLASH1_BASE | 0x22;
+       write_bat (IBAT1, batu, batl);
+       write_bat (DBAT1, batu, batl);
+
+       /* CPLD */
+       batu = CFG_CPLD_BASE | (BL_512K << 2) | BPP_RW | BPP_RX;
+       batl = CFG_CPLD_BASE | 0x22;
+       write_bat (IBAT2, 0, 0);
+       write_bat (DBAT2, batu, batl);
+
+       /* FPGA */
+       batu = CFG_FPGA_BASE | (BL_512K << 2) | BPP_RW | BPP_RX;
+       batl = CFG_FPGA_BASE | 0x22;
+       write_bat (IBAT3, 0, 0);
+       write_bat (DBAT3, batu, batl);
+
+       /* MBAR - Data only */
+       batu = CFG_MBAR | BPP_RW | BPP_RX;
+       batl = CFG_MBAR | 0x22;
+       mtspr (IBAT4L, 0);
+       mtspr (IBAT4U, 0);
+       mtspr (DBAT4L, batl);
+       mtspr (DBAT4U, batu);
+
+       /* MBAR - SRAM */
+       batu = CFG_SRAM_BASE | BPP_RW | BPP_RX;
+       batl = CFG_SRAM_BASE | 0x42;
+       mtspr (IBAT5L, batl);
+       mtspr (IBAT5U, batu);
+       mtspr (DBAT5L, batl);
+       mtspr (DBAT5U, batu);
+
+       if (size <= 0x800000)   /* 8MB */
+               blocksize = BL_8M << 2;
+       else if (size <= 0x1000000)     /* 16MB */
+               blocksize = BL_16M << 2;
+       else if (size <= 0x2000000)     /* 32MB */
+               blocksize = BL_32M << 2;
+       else if (size <= 0x4000000)     /* 64MB */
+               blocksize = BL_64M << 2;
+       else if (size <= 0x8000000)     /* 128MB */
+               blocksize = BL_128M << 2;
+       else if (size <= 0x10000000)    /* 256MB */
+               blocksize = BL_256M << 2;
+
+       /* Memory */
+       batu = CFG_SDRAM_BASE | blocksize | BPP_RW | BPP_RX;
+       batl = CFG_SDRAM_BASE | 0x42;
+       mtspr (IBAT6L, batl);
+       mtspr (IBAT6U, batu);
+       mtspr (DBAT6L, batl);
+       mtspr (DBAT6U, batu);
+
+       /* memory size is less than 256MB */
+       if (size <= 0x10000000) {
+               /* Nothing */
+               batu = 0;
+               batl = 0;
+       } else {
+               size -= 0x10000000;
+               if (size <= 0x800000)   /* 8MB */
+                       blocksize = BL_8M << 2;
+               else if (size <= 0x1000000)     /* 16MB */
+                       blocksize = BL_16M << 2;
+               else if (size <= 0x2000000)     /* 32MB */
+                       blocksize = BL_32M << 2;
+               else if (size <= 0x4000000)     /* 64MB */
+                       blocksize = BL_64M << 2;
+               else if (size <= 0x8000000)     /* 128MB */
+                       blocksize = BL_128M << 2;
+               else if (size <= 0x10000000)    /* 256MB */
+                       blocksize = BL_256M << 2;
+
+               batu = (CFG_SDRAM_BASE +
+                       0x10000000) | blocksize | BPP_RW | BPP_RX;
+               batl = (CFG_SDRAM_BASE + 0x10000000) | 0x42;
+       }
+
+       mtspr (IBAT7L, batl);
+       mtspr (IBAT7U, batu);
+       mtspr (DBAT7L, batl);
+       mtspr (DBAT7U, batu);
+}
+
+long int initdram (int board_type)
+{
+       ulong size;
+
+       size = dramSetup ();
+
+/* if iCache ad dCache is defined */
+#if (CONFIG_COMMANDS & CFG_CMD_CACHE)
+/*    setupBat(size);*/
+#endif
+
+       return size;
+}
+
+int checkboard (void)
+{
+       puts ("Board: Alaska MPC8220 Evaluation Board\n");
+
+       return 0;
+}
diff --git a/board/alaska/config.mk b/board/alaska/config.mk
new file mode 100644 (file)
index 0000000..99d28a5
--- /dev/null
@@ -0,0 +1,31 @@
+#
+# (C) Copyright 2003-2004
+# 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
+#
+
+#
+# alaska board
+#
+
+TEXT_BASE = 0xfff00000
+# TEXT_BASE = 0x00100000
+
+PLATFORM_CPPFLAGS += -DTEXT_BASE=$(TEXT_BASE) -I$(TOPDIR)/board
diff --git a/board/alaska/extserial.c b/board/alaska/extserial.c
new file mode 100644 (file)
index 0000000..f17e06e
--- /dev/null
@@ -0,0 +1,110 @@
+/*
+ * (C) Copyright 2004, Freescale, Inc
+ * TsiChung Liew, Tsi-Chung.Liew@freescale.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
+ *
+ */
+
+/*
+ * Minimal serial functions needed to use one of the PSC ports
+ * as serial console interface.
+ */
+
+#include <common.h>
+#include <mpc8220.h>
+
+#if defined (CONFIG_EXTUART_CONSOLE)
+#   include <ns16550.h>
+
+#   define PADSERIAL_BAUD_115200   0x40
+#   define PADSERIAL_BAUD_57600    0x20
+#   define PADSERIAL_BAUD_9600     0
+#   define PADCARD_FREQ            18432000
+
+const NS16550_t com_port = (NS16550_t) CFG_NS16550_COM1;
+
+int ext_serial_init (void)
+{
+       DECLARE_GLOBAL_DATA_PTR;
+       volatile u8 *dipswitch = (volatile u8 *) (CFG_CPLD_BASE + 0x1002);
+       int baud_divisor;
+
+       /* Find out the baud rate speed on debug card dip switches */
+       if (*dipswitch & PADSERIAL_BAUD_115200)
+               gd->baudrate = 115200;
+       else if (*dipswitch & PADSERIAL_BAUD_57600)
+               gd->baudrate = 57600;
+       else
+               gd->baudrate = 9600;
+
+       /* Debug card frequency */
+       baud_divisor = PADCARD_FREQ / (16 * gd->baudrate);
+
+       NS16550_init (com_port, baud_divisor);
+
+       return (0);
+}
+
+void ext_serial_putc (const char c)
+{
+       if (c == '\n')
+               NS16550_putc (com_port, '\r');
+
+       NS16550_putc (com_port, c);
+}
+
+void ext_serial_puts (const char *s)
+{
+       while (*s) {
+               serial_putc (*s++);
+       }
+}
+
+int ext_serial_getc (void)
+{
+       return NS16550_getc (com_port);
+}
+
+int ext_serial_tstc (void)
+{
+       return NS16550_tstc (com_port);
+}
+
+void ext_serial_setbrg (void)
+{
+       DECLARE_GLOBAL_DATA_PTR;
+
+       volatile u8 *dipswitch = (volatile u8 *) (CFG_CPLD_BASE + 0x1002);
+       int baud_divisor;
+
+       /* Find out the baud rate speed on debug card dip switches */
+       if (*dipswitch & PADSERIAL_BAUD_115200)
+               gd->baudrate = 115200;
+       else if (*dipswitch & PADSERIAL_BAUD_57600)
+               gd->baudrate = 57600;
+       else
+               gd->baudrate = 9600;
+
+       /* Debug card frequency */
+       baud_divisor = PADCARD_FREQ / (16 * gd->baudrate);
+
+       NS16550_reinit (com_port, baud_divisor);
+}
+#endif /* CONFIG_EXTUART_CONSOLE */
diff --git a/board/alaska/flash.c b/board/alaska/flash.c
new file mode 100644 (file)
index 0000000..48c9472
--- /dev/null
@@ -0,0 +1,807 @@
+/*
+ * (C) Copyright 2001
+ * Kyle Harris, Nexus Technologies, Inc. kharris@nexus-tech.net
+ *
+ * (C) Copyright 2001-2004
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <linux/byteorder/swab.h>
+
+
+flash_info_t flash_info[CFG_MAX_FLASH_BANKS];  /* info for FLASH chips    */
+
+/* Board support for 1 or 2 flash devices */
+#define FLASH_PORT_WIDTH8
+
+typedef unsigned char FLASH_PORT_WIDTH;
+typedef volatile unsigned char FLASH_PORT_WIDTHV;
+
+#define SWAP(x)         (x)
+
+/* Intel-compatible flash ID */
+#define INTEL_COMPAT    0x89
+#define INTEL_ALT       0xB0
+
+/* Intel-compatible flash commands */
+#define INTEL_PROGRAM   0x10
+#define INTEL_ERASE     0x20
+#define INTEL_CLEAR     0x50
+#define INTEL_LOCKBIT   0x60
+#define INTEL_PROTECT   0x01
+#define INTEL_STATUS    0x70
+#define INTEL_READID    0x90
+#define INTEL_CONFIRM   0xD0
+#define INTEL_RESET     0xFF
+
+/* Intel-compatible flash status bits */
+#define INTEL_FINISHED  0x80
+#define INTEL_OK        0x80
+
+#define FPW             FLASH_PORT_WIDTH
+#define FPWV            FLASH_PORT_WIDTHV
+
+#define FLASH_CYCLE1    0x0555
+#define FLASH_CYCLE2    0x02aa
+
+#define WR_BLOCK        0x20
+
+/*-----------------------------------------------------------------------
+ * Functions
+ */
+static ulong flash_get_size (FPW * addr, flash_info_t * info);
+static int write_data (flash_info_t * info, ulong dest, FPW data);
+static int write_data_block (flash_info_t * info, ulong src, ulong dest);
+static int write_word_amd (flash_info_t * info, FPWV * dest, FPW data);
+static void flash_get_offsets (ulong base, flash_info_t * info);
+void inline spin_wheel (void);
+
+/*-----------------------------------------------------------------------
+ */
+
+unsigned long flash_init (void)
+{
+       int i;
+       ulong size = 0;
+       ulong fsize = 0;
+
+       for (i = 0; i < CFG_MAX_FLASH_BANKS; i++) {
+               memset (&flash_info[i], 0, sizeof (flash_info_t));
+
+               switch (i) {
+               case 0:
+                       flash_get_size ((FPW *) CFG_FLASH1_BASE,
+                                       &flash_info[i]);
+                       flash_get_offsets (CFG_FLASH1_BASE, &flash_info[i]);
+                       break;
+               case 1:
+                       flash_get_size ((FPW *) CFG_FLASH1_BASE,
+                                       &flash_info[i]);
+                       fsize = CFG_FLASH1_BASE + flash_info[i - 1].size;
+                       flash_get_offsets (fsize, &flash_info[i]);
+                       break;
+               case 2:
+                       flash_get_size ((FPW *) CFG_FLASH0_BASE,
+                                       &flash_info[i]);
+                       flash_get_offsets (CFG_FLASH0_BASE, &flash_info[i]);
+                       break;
+               case 3:
+                       flash_get_size ((FPW *) CFG_FLASH0_BASE,
+                                       &flash_info[i]);
+                       fsize = CFG_FLASH0_BASE + flash_info[i - 1].size;
+                       flash_get_offsets (fsize, &flash_info[i]);
+                       break;
+               default:
+                       panic ("configured to many flash banks!\n");
+                       break;
+               }
+               size += flash_info[i].size;
+       }
+
+       /* Protect monitor and environment sectors
+        */
+#if defined (CFG_AMD_BOOT)
+       flash_protect (FLAG_PROTECT_SET,
+                      CFG_MONITOR_BASE,
+                      CFG_MONITOR_BASE + monitor_flash_len - 1,
+                      &flash_info[2]);
+       flash_protect (FLAG_PROTECT_SET,
+                      CFG_INTEL_BASE,
+                      CFG_INTEL_BASE + monitor_flash_len - 1,
+                      &flash_info[1]);
+#else
+       flash_protect (FLAG_PROTECT_SET,
+                      CFG_MONITOR_BASE,
+                      CFG_MONITOR_BASE + monitor_flash_len - 1,
+                      &flash_info[3]);
+       flash_protect (FLAG_PROTECT_SET,
+                      CFG_AMD_BASE,
+                      CFG_AMD_BASE + monitor_flash_len - 1, &flash_info[0]);
+#endif
+
+       flash_protect (FLAG_PROTECT_SET,
+                      CFG_ENV1_ADDR,
+                      CFG_ENV1_ADDR + CFG_ENV1_SIZE - 1, &flash_info[1]);
+       flash_protect (FLAG_PROTECT_SET,
+                      CFG_ENV_ADDR,
+                      CFG_ENV_ADDR + CFG_ENV_SIZE - 1, &flash_info[3]);
+
+       return size;
+}
+
+/*-----------------------------------------------------------------------
+ */
+static void flash_get_offsets (ulong base, flash_info_t * info)
+{
+       int i;
+
+       if (info->flash_id == FLASH_UNKNOWN)
+               return;
+
+       if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_AMD) {
+               for (i = 0; i < info->sector_count; i++) {
+                       info->start[i] = base + (i * PHYS_AMD_SECT_SIZE);
+                       info->protect[i] = 0;
+               }
+       }
+
+       if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL) {
+               for (i = 0; i < info->sector_count; i++) {
+                       info->start[i] = base + (i * PHYS_INTEL_SECT_SIZE);
+                       info->protect[i] = 0;
+               }
+       }
+}
+
+/*-----------------------------------------------------------------------
+ */
+void flash_print_info (flash_info_t * info)
+{
+       int i;
+
+       if (info->flash_id == FLASH_UNKNOWN) {
+               printf ("missing or unknown FLASH type\n");
+               return;
+       }
+
+       switch (info->flash_id & FLASH_VENDMASK) {
+       case FLASH_MAN_INTEL:
+               printf ("INTEL ");
+               break;
+       case FLASH_MAN_AMD:
+               printf ("AMD ");
+               break;
+       default:
+               printf ("Unknown Vendor ");
+               break;
+       }
+
+       switch (info->flash_id & FLASH_TYPEMASK) {
+       case FLASH_28F128J3A:
+               printf ("28F128J3A\n");
+               break;
+
+       case FLASH_AM040:
+               printf ("AMD29F040B\n");
+               break;
+
+       default:
+               printf ("Unknown Chip Type\n");
+               break;
+       }
+
+       printf ("  Size: %ld MB in %d Sectors\n",
+               info->size >> 20, info->sector_count);
+
+       printf ("  Sector Start Addresses:");
+       for (i = 0; i < info->sector_count; ++i) {
+               if ((i % 5) == 0)
+                       printf ("\n   ");
+               printf (" %08lX%s",
+                       info->start[i], info->protect[i] ? " (RO)" : "     ");
+       }
+       printf ("\n");
+       return;
+}
+
+/*
+ * The following code cannot be run from FLASH!
+ */
+static ulong flash_get_size (FPW * addr, flash_info_t * info)
+{
+       FPWV value;
+       static int amd = 0;
+
+       /* Write auto select command: read Manufacturer ID */
+       /* Write auto select command sequence and test FLASH answer */
+       addr[FLASH_CYCLE1] = (FPW) 0x00AA00AA;  /* for AMD, Intel ignores this */
+       __asm__ ("sync");
+       addr[FLASH_CYCLE2] = (FPW) 0x00550055;  /* for AMD, Intel ignores this */
+       __asm__ ("sync");
+       addr[FLASH_CYCLE1] = (FPW) 0x00900090;  /* selects Intel or AMD */
+       __asm__ ("sync");
+
+       udelay (100);
+
+       switch (addr[0] & 0xff) {
+
+       case (uchar) AMD_MANUFACT:
+               info->flash_id = FLASH_MAN_AMD;
+               value = addr[1];
+               break;
+
+       case (uchar) INTEL_MANUFACT:
+               info->flash_id = FLASH_MAN_INTEL;
+               value = addr[2];
+               break;
+
+       default:
+               printf ("unknown\n");
+               info->flash_id = FLASH_UNKNOWN;
+               info->sector_count = 0;
+               info->size = 0;
+               addr[0] = (FPW) 0x00FF00FF;     /* restore read mode */
+               return (0);     /* no or unknown flash  */
+       }
+
+       switch (value) {
+
+       case (FPW) INTEL_ID_28F128J3A:
+               info->flash_id += FLASH_28F128J3A;
+               info->sector_count = 64;
+               info->size = 0x00800000;        /* => 16 MB     */
+               break;
+
+       case (FPW) AMD_ID_LV040B:
+               info->flash_id += FLASH_AM040;
+               if (amd == 0) {
+                       info->sector_count = 7;
+                       info->size = 0x00070000;        /* => 448 KB     */
+                       amd = 1;
+               } else {
+                       /* for Environment settings */
+                       info->sector_count = 1;
+                       info->size = PHYS_AMD_SECT_SIZE;        /* => 64 KB     */
+                       amd = 0;
+               }
+               break;
+
+       default:
+               info->flash_id = FLASH_UNKNOWN;
+               break;
+       }
+
+       if (info->sector_count > CFG_MAX_FLASH_SECT) {
+               printf ("** ERROR: sector count %d > max (%d) **\n",
+                       info->sector_count, CFG_MAX_FLASH_SECT);
+               info->sector_count = CFG_MAX_FLASH_SECT;
+       }
+
+       if (value == (FPW) INTEL_ID_28F128J3A)
+               addr[0] = (FPW) 0x00FF00FF;     /* restore read mode */
+       else
+               addr[0] = (FPW) 0x00F000F0;     /* restore read mode */
+
+       return (info->size);
+}
+
+
+/*-----------------------------------------------------------------------
+ */
+int flash_erase (flash_info_t * info, int s_first, int s_last)
+{
+       int flag, prot, sect;
+       ulong type, start, last;
+       int rcode = 0, intel = 0;
+
+       if ((s_first < 0) || (s_first > s_last)) {
+               if (info->flash_id == FLASH_UNKNOWN)
+                       printf ("- missing\n");
+               else
+                       printf ("- no sectors to erase\n");
+               return 1;
+       }
+
+       type = (info->flash_id & FLASH_VENDMASK);
+       if ((type != FLASH_MAN_INTEL)) {
+               type = (info->flash_id & FLASH_VENDMASK);
+               if ((type != FLASH_MAN_AMD)) {
+                       printf ("Can't erase unknown flash type %08lx - aborted\n",
+                               info->flash_id);
+                       return 1;
+               }
+       }
+
+       if (type == FLASH_MAN_INTEL)
+               intel = 1;
+
+       prot = 0;
+       for (sect = s_first; sect <= s_last; ++sect) {
+               if (info->protect[sect]) {
+                       prot++;
+               }
+       }
+
+       if (prot) {
+               printf ("- Warning: %d protected sectors will not be erased!\n", prot);
+       } else {
+               printf ("\n");
+       }
+
+       start = get_timer (0);
+       last = start;
+
+       /* Disable interrupts which might cause a timeout here */
+       flag = disable_interrupts ();
+
+       /* Start erase on unprotected sectors */
+       for (sect = s_first; sect <= s_last; sect++) {
+               if (info->protect[sect] == 0) { /* not protected */
+                       FPWV *addr = (FPWV *) (info->start[sect]);
+                       FPW status;
+
+                       printf ("Erasing sector %2d ... ", sect);
+
+                       /* arm simple, non interrupt dependent timer */
+                       start = get_timer (0);
+
+                       if (intel) {
+                               *addr = (FPW) 0x00500050;       /* clear status register */
+                               *addr = (FPW) 0x00200020;       /* erase setup */
+                               *addr = (FPW) 0x00D000D0;       /* erase confirm */
+                       } else {
+                               FPWV *base;     /* first address in bank */
+
+                               base = (FPWV *) (CFG_AMD_BASE);
+                               base[FLASH_CYCLE1] = (FPW) 0x00AA00AA;  /* unlock */
+                               base[FLASH_CYCLE2] = (FPW) 0x00550055;  /* unlock */
+                               base[FLASH_CYCLE1] = (FPW) 0x00800080;  /* erase mode */
+                               base[FLASH_CYCLE1] = (FPW) 0x00AA00AA;  /* unlock */
+                               base[FLASH_CYCLE2] = (FPW) 0x00550055;  /* unlock */
+                               *addr = (FPW) 0x00300030;       /* erase sector */
+                       }
+
+                       while (((status =
+                                *addr) & (FPW) 0x00800080) !=
+                              (FPW) 0x00800080) {
+                               if (get_timer (start) > CFG_FLASH_ERASE_TOUT) {
+                                       printf ("Timeout\n");
+                                       if (intel) {
+                                               *addr = (FPW) 0x00B000B0;       /* suspend erase     */
+                                               *addr = (FPW) 0x00FF00FF;       /* reset to read mode */
+                                       } else
+                                               *addr = (FPW) 0x00F000F0;       /* reset to read mode */
+
+                                       rcode = 1;
+                                       break;
+                               }
+                       }
+
+                       if (intel) {
+                               *addr = (FPW) 0x00500050;       /* clear status register cmd.   */
+                               *addr = (FPW) 0x00FF00FF;       /* resest to read mode          */
+                       } else
+                               *addr = (FPW) 0x00F000F0;       /* reset to read mode */
+
+                       printf (" done\n");
+               }
+       }
+       return rcode;
+}
+
+/*-----------------------------------------------------------------------
+ * Copy memory to flash, returns:
+ * 0 - OK
+ * 1 - write timeout
+ * 2 - Flash not erased
+ * 4 - Flash not identified
+ */
+
+int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt)
+{
+       if (info->flash_id == FLASH_UNKNOWN) {
+               return 4;
+       }
+
+       switch (info->flash_id & FLASH_VENDMASK) {
+       case FLASH_MAN_AMD:
+           {
+               FPW data = 0;   /* 16 or 32 bit word, matches flash bus width */
+               int bytes;      /* number of bytes to program in current word */
+               int left;       /* number of bytes left to program */
+               int i, res;
+
+               for (left = cnt, res = 0;
+                    left > 0 && res == 0;
+                    addr += sizeof (data), left -=
+                    sizeof (data) - bytes) {
+
+                       bytes = addr & (sizeof (data) - 1);
+                       addr &= ~(sizeof (data) - 1);
+
+                       /* combine source and destination data so can program
+                        * an entire word of 16 or 32 bits
+                        */
+                       for (i = 0; i < sizeof (data); i++) {
+                               data <<= 8;
+                               if (i < bytes || i - bytes >= left)
+                                       data += *((uchar *) addr + i);
+                               else
+                                       data += *src++;
+                       }
+
+                       res = write_word_amd (info, (FPWV *) addr,
+                                             data);
+               }
+               return res;
+           }           /* case FLASH_MAN_AMD */
+
+       case FLASH_MAN_INTEL:
+           {
+               ulong cp, wp;
+               FPW data;
+               int count, i, l, rc, port_width;
+
+               /* get lower word aligned address */
+               wp = addr;
+               port_width = 1;
+
+               /*
+                * handle unaligned start bytes
+                */
+               if ((l = addr - wp) != 0) {
+                       data = 0;
+                       for (i = 0, cp = wp; i < l; ++i, ++cp) {
+                               data = (data << 8) | (*(uchar *) cp);
+                       }
+
+                       for (; i < port_width && cnt > 0; ++i) {
+                               data = (data << 8) | *src++;
+                               --cnt;
+                               ++cp;
+                       }
+
+                       for (; cnt == 0 && i < port_width; ++i, ++cp)
+                               data = (data << 8) | (*(uchar *) cp);
+
+                       if ((rc =
+                            write_data (info, wp, SWAP (data))) != 0)
+                               return (rc);
+                       wp += port_width;
+               }
+
+               if (cnt > WR_BLOCK) {
+                       /*
+                        * handle word aligned part
+                        */
+                       count = 0;
+                       while (cnt >= WR_BLOCK) {
+
+                               if ((rc =
+                                    write_data_block (info,
+                                                      (ulong) src,
+                                                      wp)) != 0)
+                                       return (rc);
+
+                               wp += WR_BLOCK;
+                               src += WR_BLOCK;
+                               cnt -= WR_BLOCK;
+
+                               if (count++ > 0x800) {
+                                       spin_wheel ();
+                                       count = 0;
+                               }
+                       }
+               }
+
+               if (cnt < WR_BLOCK) {
+                       /*
+                        * handle word aligned part
+                        */
+                       count = 0;
+                       while (cnt >= port_width) {
+                               data = 0;
+                               for (i = 0; i < port_width; ++i)
+                                       data = (data << 8) | *src++;
+
+                               if ((rc =
+                                    write_data (info, wp,
+                                                SWAP (data))) != 0)
+                                       return (rc);
+
+                               wp += port_width;
+                               cnt -= port_width;
+                               if (count++ > 0x800) {
+                                       spin_wheel ();
+                                       count = 0;
+                               }
+                       }
+               }
+
+               if (cnt == 0)
+                       return (0);
+
+               /*
+                * handle unaligned tail bytes
+                */
+               data = 0;
+               for (i = 0, cp = wp; i < port_width && cnt > 0;
+                    ++i, ++cp) {
+                       data = (data << 8) | *src++;
+                       --cnt;
+               }
+
+               for (; i < port_width; ++i, ++cp)
+                       data = (data << 8) | (*(uchar *) cp);
+
+               return (write_data (info, wp, SWAP (data)));
+           }           /* case FLASH_MAN_INTEL */
+
+       }                       /* switch */
+       return (0);
+}
+
+/*-----------------------------------------------------------------------
+ * Write a word or halfword to Flash, returns:
+ * 0 - OK
+ * 1 - write timeout
+ * 2 - Flash not erased
+ */
+static int write_data (flash_info_t * info, ulong dest, FPW data)
+{
+       FPWV *addr = (FPWV *) dest;
+       ulong start;
+       int flag;
+
+       /* Check if Flash is (sufficiently) erased */
+       if ((*addr & data) != data) {
+               printf ("not erased at %08lx (%lx)\n", (ulong) addr, *addr);
+               return (2);
+       }
+       /* Disable interrupts which might cause a timeout here */
+       flag = disable_interrupts ();
+
+       *addr = (FPW) 0x00400040;       /* write setup */
+       *addr = data;
+
+       /* arm simple, non interrupt dependent timer */
+       start = get_timer (0);
+
+       /* wait while polling the status register */
+       while ((*addr & (FPW) 0x00800080) != (FPW) 0x00800080) {
+               if (get_timer (start) > CFG_FLASH_WRITE_TOUT) {
+                       *addr = (FPW) 0x00FF00FF;       /* restore read mode */
+                       return (1);
+               }
+       }
+
+       *addr = (FPW) 0x00FF00FF;       /* restore read mode */
+
+       return (0);
+}
+
+/*-----------------------------------------------------------------------
+ * Write a word or halfword to Flash, returns:
+ * 0 - OK
+ * 1 - write timeout
+ * 2 - Flash not erased
+ */
+static int write_data_block (flash_info_t * info, ulong src, ulong dest)
+{
+       FPWV *srcaddr = (FPWV *) src;
+       FPWV *dstaddr = (FPWV *) dest;
+       ulong start;
+       int flag, i;
+
+       /* Check if Flash is (sufficiently) erased */
+       for (i = 0; i < WR_BLOCK; i++)
+               if ((*dstaddr++ & 0xff) != 0xff) {
+                       printf ("not erased at %08lx (%lx)\n",
+                               (ulong) dstaddr, *dstaddr);
+                       return (2);
+               }
+
+       dstaddr = (FPWV *) dest;
+
+       /* Disable interrupts which might cause a timeout here */
+       flag = disable_interrupts ();
+
+       *dstaddr = (FPW) 0x00e800e8;    /* write block setup */
+
+       /* arm simple, non interrupt dependent timer */
+       start = get_timer (0);
+
+       /* wait while polling the status register */
+       while ((*dstaddr & (FPW) 0x00800080) != (FPW) 0x00800080) {
+               if (get_timer (start) > CFG_FLASH_WRITE_TOUT) {
+                       *dstaddr = (FPW) 0x00FF00FF;    /* restore read mode */
+                       return (1);
+               }
+       }
+
+       *dstaddr = (FPW) 0x001f001f;    /* write 32 to buffer */
+       for (i = 0; i < WR_BLOCK; i++)
+               *dstaddr++ = *srcaddr++;
+
+       dstaddr -= 1;
+       *dstaddr = (FPW) 0x00d000d0;    /* write 32 to buffer */
+
+       /* arm simple, non interrupt dependent timer */
+       start = get_timer (0);
+
+       /* wait while polling the status register */
+       while ((*dstaddr & (FPW) 0x00800080) != (FPW) 0x00800080) {
+               if (get_timer (start) > CFG_FLASH_WRITE_TOUT) {
+                       *dstaddr = (FPW) 0x00FF00FF;    /* restore read mode */
+                       return (1);
+               }
+       }
+
+       *dstaddr = (FPW) 0x00FF00FF;    /* restore read mode */
+
+       return (0);
+}
+
+/*-----------------------------------------------------------------------
+ * Write a word to Flash for AMD FLASH
+ * A word is 16 or 32 bits, whichever the bus width of the flash bank
+ * (not an individual chip) is.
+ *
+ * returns:
+ * 0 - OK
+ * 1 - write timeout
+ * 2 - Flash not erased
+ */
+static int write_word_amd (flash_info_t * info, FPWV * dest, FPW data)
+{
+       ulong start;
+       int flag;
+       int res = 0;            /* result, assume success */
+       FPWV *base;             /* first address in flash bank */
+
+       /* Check if Flash is (sufficiently) erased */
+       if ((*dest & data) != data) {
+               return (2);
+       }
+
+       base = (FPWV *) (CFG_AMD_BASE);
+
+       /* Disable interrupts which might cause a timeout here */
+       flag = disable_interrupts ();
+
+       base[FLASH_CYCLE1] = (FPW) 0x00AA00AA;  /* unlock */
+       base[FLASH_CYCLE2] = (FPW) 0x00550055;  /* unlock */
+       base[FLASH_CYCLE1] = (FPW) 0x00A000A0;  /* selects program mode */
+
+       *dest = data;           /* start programming the data */
+
+       /* re-enable interrupts if necessary */
+       if (flag)
+               enable_interrupts ();
+
+       start = get_timer (0);
+
+       /* data polling for D7 */
+       while (res == 0
+              && (*dest & (FPW) 0x00800080) != (data & (FPW) 0x00800080)) {
+               if (get_timer (start) > CFG_FLASH_WRITE_TOUT) {
+                       *dest = (FPW) 0x00F000F0;       /* reset bank */
+                       res = 1;
+               }
+       }
+
+       return (res);
+}
+
+void inline spin_wheel (void)
+{
+       static int p = 0;
+       static char w[] = "\\/-";
+
+       printf ("\010%c", w[p]);
+       (++p == 3) ? (p = 0) : 0;
+}
+
+/*-----------------------------------------------------------------------
+ * Set/Clear sector's lock bit, returns:
+ * 0 - OK
+ * 1 - Error (timeout, voltage problems, etc.)
+ */
+int flash_real_protect (flash_info_t * info, long sector, int prot)
+{
+       ulong start;
+       int i;
+       int rc = 0;
+       FPWV *addr = (FPWV *) (info->start[sector]);
+       int flag = disable_interrupts ();
+
+       /*
+        * 29F040B AMD flash does not support software protection/unprotection,
+        * the only way to protect the AMD flash is marked it as prot bit.
+        * This flash only support hardware protection, by supply or not supply
+        * 12vpp to the flash
+        */
+       if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_AMD) {
+               info->protect[sector] = prot;
+
+               return 0;
+       }
+
+       *addr = INTEL_CLEAR;    /* Clear status register    */
+       if (prot) {             /* Set sector lock bit      */
+               *addr = INTEL_LOCKBIT;  /* Sector lock bit          */
+               *addr = INTEL_PROTECT;  /* set                      */
+       } else {                /* Clear sector lock bit    */
+               *addr = INTEL_LOCKBIT;  /* All sectors lock bits    */
+               *addr = INTEL_CONFIRM;  /* clear                    */
+       }
+
+       start = get_timer (0);
+
+       while ((*addr & INTEL_FINISHED) != INTEL_FINISHED) {
+               if (get_timer (start) > CFG_FLASH_UNLOCK_TOUT) {
+                       printf ("Flash lock bit operation timed out\n");
+                       rc = 1;
+                       break;
+               }
+       }
+
+       if (*addr != INTEL_OK) {
+               printf ("Flash lock bit operation failed at %08X, CSR=%08X\n",
+                       (uint) addr, (uint) * addr);
+               rc = 1;
+       }
+
+       if (!rc)
+               info->protect[sector] = prot;
+
+       /*
+        * Clear lock bit command clears all sectors lock bits, so
+        * we have to restore lock bits of protected sectors.
+        */
+       if (!prot) {
+               for (i = 0; i < info->sector_count; i++) {
+                       if (info->protect[i]) {
+                               start = get_timer (0);
+                               addr = (FPWV *) (info->start[i]);
+                               *addr = INTEL_LOCKBIT;  /* Sector lock bit  */
+                               *addr = INTEL_PROTECT;  /* set              */
+                               while ((*addr & INTEL_FINISHED) !=
+                                      INTEL_FINISHED) {
+                                       if (get_timer (start) >
+                                           CFG_FLASH_UNLOCK_TOUT) {
+                                               printf ("Flash lock bit operation timed out\n");
+                                               rc = 1;
+                                               break;
+                                       }
+                               }
+                       }
+               }
+       }
+
+       if (flag)
+               enable_interrupts ();
+
+       *addr = INTEL_RESET;    /* Reset to read array mode */
+
+       return rc;
+}
diff --git a/board/alaska/serial.c b/board/alaska/serial.c
new file mode 100644 (file)
index 0000000..08285b8
--- /dev/null
@@ -0,0 +1,131 @@
+/*
+ * (C) Copyright 2004, Freescale, Inc
+ * TsiChung Liew, Tsi-Chung.Liew@freescale.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
+ *
+ */
+
+/*
+ * Minimal serial functions needed to use one of the PSC ports
+ * as serial console interface.
+ */
+
+#include <common.h>
+#include <mpc8220.h>
+
+int serial_init (void)
+{
+       DECLARE_GLOBAL_DATA_PTR;
+
+#if defined (CONFIG_EXTUART_CONSOLE)
+       volatile uchar *cpld = (volatile uchar *) CFG_CPLD_BASE;
+#endif
+
+       /* Check CPLD Switch 2 whether is external or internal */
+#if defined (CONFIG_EXTUART_CONSOLE)
+       if ((*cpld & 0x02) == 0x02) {
+               gd->bExtUart = 1;
+               return ext_serial_init ();
+       } else
+#endif
+       {
+#if defined(CONFIG_PSC_CONSOLE)
+               gd->bExtUart = 0;
+               return psc_serial_init ();
+#endif
+       }
+
+       return (0);
+}
+
+void serial_putc (const char c)
+{
+       DECLARE_GLOBAL_DATA_PTR;
+
+       if (gd->bExtUart) {
+#if defined (CONFIG_EXTUART_CONSOLE)
+               ext_serial_putc (c);
+#endif
+       } else {
+#if defined(CONFIG_PSC_CONSOLE)
+               psc_serial_putc (c);
+#endif
+       }
+}
+
+void serial_puts (const char *s)
+{
+       DECLARE_GLOBAL_DATA_PTR;
+
+       if (gd->bExtUart) {
+#if defined (CONFIG_EXTUART_CONSOLE)
+               ext_serial_puts (s);
+#endif
+       } else {
+#if defined(CONFIG_PSC_CONSOLE)
+               psc_serial_puts (s);
+#endif
+       }
+}
+
+int serial_getc (void)
+{
+       DECLARE_GLOBAL_DATA_PTR;
+
+       if (gd->bExtUart) {
+#if defined (CONFIG_EXTUART_CONSOLE)
+               return ext_serial_getc ();
+#endif
+       } else {
+#if defined(CONFIG_PSC_CONSOLE)
+               return psc_serial_getc ();
+#endif
+       }
+}
+
+int serial_tstc (void)
+{
+       DECLARE_GLOBAL_DATA_PTR;
+
+       if (gd->bExtUart) {
+#if defined (CONFIG_EXTUART_CONSOLE)
+               return ext_serial_tstc ();
+#endif
+       } else {
+#if defined(CONFIG_PSC_CONSOLE)
+               return psc_serial_tstc ();
+#endif
+       }
+}
+
+void serial_setbrg (void)
+{
+       DECLARE_GLOBAL_DATA_PTR;
+
+       if (gd->bExtUart) {
+#if defined (CONFIG_EXTUART_CONSOLE)
+               ext_serial_setbrg ();
+#endif
+       } else {
+#if defined(CONFIG_PSC_CONSOLE)
+               psc_serial_setbrg ();
+#endif
+       }
+}
diff --git a/board/alaska/u-boot.lds b/board/alaska/u-boot.lds
new file mode 100644 (file)
index 0000000..6e4a060
--- /dev/null
@@ -0,0 +1,122 @@
+/*
+ * (C) Copyright 2003-2004
+ * 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/mpc8220/start.o        (.text)
+    *(.text)
+    *(.fixup)
+    *(.got1)
+    . = ALIGN(16);
+    *(.rodata)
+    *(.rodata1)
+    *(.rodata.str1.4)
+  }
+  .fini      : { *(.fini)    } =0
+  .ctors     : { *(.ctors)   }
+  .dtors     : { *(.dtors)   }
+
+  /* Read-write section, merged into data segment: */
+  . = (. + 0x0FFF) & 0xFFFFF000;
+  _erotext = .;
+  PROVIDE (erotext = .);
+  .reloc   :
+  {
+    *(.got)
+    _GOT2_TABLE_ = .;
+    *(.got2)
+    _FIXUP_TABLE_ = .;
+    *(.fixup)
+  }
+  __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >> 2;
+  __fixup_entries = (. - _FIXUP_TABLE_) >> 2;
+
+  .data    :
+  {
+    *(.data)
+    *(.data1)
+    *(.sdata)
+    *(.sdata2)
+    *(.dynamic)
+    CONSTRUCTORS
+  }
+  _edata  =  .;
+  PROVIDE (edata = .);
+
+  __u_boot_cmd_start = .;
+  .u_boot_cmd : { *(.u_boot_cmd) }
+  __u_boot_cmd_end = .;
+
+
+  __start___ex_table = .;
+  __ex_table : { *(__ex_table) }
+  __stop___ex_table = .;
+
+  . = ALIGN(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 = .);
+}
index d42b498f7e5fa8d88d5eb0be4e93ad8bd9b203d9..4c5540f253b48cf53f9ee2992dcd976b0618c6e3 100644 (file)
@@ -63,9 +63,9 @@ int do_bdinfo ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 #if defined(CONFIG_405GP) || defined(CONFIG_405CR) || \
     defined(CONFIG_405EP) || defined(CONFIG_XILINX_ML300)
        print_str ("procfreq",      strmhz(buf, bd->bi_procfreq));
-       print_str ("plb_busfreq",           strmhz(buf, bd->bi_plb_busfreq));
+       print_str ("plb_busfreq",   strmhz(buf, bd->bi_plb_busfreq));
 #if defined(CONFIG_405GP) || defined(CONFIG_405EP) || defined(CONFIG_XILINX_ML300)
-       print_str ("pci_busfreq",           strmhz(buf, bd->bi_pci_busfreq));
+       print_str ("pci_busfreq",   strmhz(buf, bd->bi_pci_busfreq));
 #endif
 #else  /* ! CONFIG_405GP, CONFIG_405CR, CONFIG_405EP, CONFIG_XILINX_ML300 */
 #if defined(CONFIG_8260) || defined(CONFIG_MPC8560)
@@ -79,6 +79,13 @@ int do_bdinfo ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 #endif
        print_str ("busfreq",       strmhz(buf, bd->bi_busfreq));
 #endif /* CONFIG_405GP, CONFIG_405CR, CONFIG_405EP, CONFIG_XILINX_ML300 */
+#if defined(CONFIG_MPC8220)
+       print_str ("inpfreq",       strmhz(buf, bd->bi_inpfreq));
+       print_str ("flbfreq",       strmhz(buf, bd->bi_flbfreq));
+       print_str ("pcifreq",       strmhz(buf, bd->bi_pcifreq));
+       print_str ("vcofreq",       strmhz(buf, bd->bi_vcofreq));
+       print_str ("pevfreq",       strmhz(buf, bd->bi_pevfreq));
+#endif
 
        puts ("ethaddr     =");
        for (i=0; i<6; ++i) {
index 84499a0330521bd8dc04000f9c4892607986b39e..43ea5f19fee27cd076cdf251099c8d271c85bacc 100644 (file)
@@ -573,6 +573,13 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag,
                /* convert all clock information to MHz */
                kbd->bi_intfreq /= 1000000L;
                kbd->bi_busfreq /= 1000000L;
+#if defined(CONFIG_MPC8220)
+        kbd->bi_inpfreq /= 1000000L;
+        kbd->bi_pcifreq /= 1000000L;
+        kbd->bi_pevfreq /= 1000000L;
+        kbd->bi_flbfreq /= 1000000L;
+        kbd->bi_vcofreq /= 1000000L;
+#endif
 #if defined(CONFIG_8260) || defined(CONFIG_MPC8560)
                kbd->bi_cpmfreq /= 1000000L;
                kbd->bi_brgfreq /= 1000000L;
diff --git a/cpu/mpc8220/Makefile b/cpu/mpc8220/Makefile
new file mode 100644 (file)
index 0000000..e64964b
--- /dev/null
@@ -0,0 +1,45 @@
+#
+# (C) Copyright 2003
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+include $(TOPDIR)/config.mk
+
+LIB    = lib$(CPU).a
+
+START  = start.o
+ASOBJS = io.o fec_dma_tasks.o
+OBJS   = i2c.o traps.o cpu.o cpu_init.o fec.o dramSetup.o interrupts.o \
+         loadtask.o uart.o speed.o
+
+all:   .depend $(START) $(ASOBJS) $(LIB)
+
+$(LIB):        $(OBJS)
+       $(AR) crv $@ $(ASOBJS) $(OBJS)
+
+#########################################################################
+
+.depend:       Makefile $(START:.o=.S) $(OBJS:.o=.c)
+               $(CC) -M $(CFLAGS) $(START:.o=.S) $(ASOBJS:.o=.S) $(OBJS:.o=.c) > $@
+
+sinclude .depend
+
+#########################################################################
diff --git a/cpu/mpc8220/config.mk b/cpu/mpc8220/config.mk
new file mode 100644 (file)
index 0000000..6fec5df
--- /dev/null
@@ -0,0 +1,27 @@
+#
+# (C) Copyright 2003
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+PLATFORM_RELFLAGS += -fPIC -ffixed-r14 -meabi
+
+PLATFORM_CPPFLAGS += -DCONFIG_MPC8220 -ffixed-r2 -ffixed-r29 \
+                    -mstring -mcpu=603e -mmultiple
diff --git a/cpu/mpc8220/cpu.c b/cpu/mpc8220/cpu.c
new file mode 100644 (file)
index 0000000..0cfe808
--- /dev/null
@@ -0,0 +1,93 @@
+/*
+ * (C) Copyright 2000-2003
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/*
+ * CPU specific code for the MPC8220 CPUs
+ */
+
+#include <common.h>
+#include <watchdog.h>
+#include <command.h>
+#include <mpc8220.h>
+#include <asm/processor.h>
+
+int checkcpu (void)
+{
+       DECLARE_GLOBAL_DATA_PTR;
+
+       ulong clock = gd->cpu_clk;
+       char buf[32];
+
+       puts ("CPU:   ");
+
+       printf (CPU_ID_STR);
+
+       printf (" (JTAG ID %08lx)", *(vu_long *) (CFG_MBAR + 0x50));
+
+       printf (" at %s MHz\n", strmhz (buf, clock));
+
+       return 0;
+}
+
+/* ------------------------------------------------------------------------- */
+
+int do_reset (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
+{
+       volatile gptmr8220_t *gptmr = (volatile gptmr8220_t *) MMAP_GPTMR;
+       ulong msr;
+
+       /* Interrupts and MMU off */
+       __asm__ __volatile__ ("mfmsr    %0":"=r" (msr):);
+
+       msr &= ~(MSR_ME | MSR_EE | MSR_IR | MSR_DR);
+       __asm__ __volatile__ ("mtmsr    %0"::"r" (msr));
+
+       /* Charge the watchdog timer */
+       gptmr->Prescl = 10;
+       gptmr->Count = 1;
+
+       gptmr->Mode = GPT_TMS_SGPIO;
+
+       gptmr->Control = GPT_CTRL_WDEN | GPT_CTRL_CE;
+
+       return 1;
+}
+
+/* ------------------------------------------------------------------------- */
+
+/*
+ * Get timebase clock frequency (like cpu_clk in Hz)
+ *
+ */
+unsigned long get_tbclk (void)
+{
+       DECLARE_GLOBAL_DATA_PTR;
+
+       ulong tbclk;
+
+       tbclk = (gd->bus_clk + 3L) / 4L;
+
+       return (tbclk);
+}
+
+/* ------------------------------------------------------------------------- */
diff --git a/cpu/mpc8220/cpu_init.c b/cpu/mpc8220/cpu_init.c
new file mode 100644 (file)
index 0000000..09b23ee
--- /dev/null
@@ -0,0 +1,130 @@
+/*
+ * (C) Copyright 2000-2003
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <mpc8220.h>
+
+/*
+ * Breath some life into the CPU...
+ *
+ * Set up the memory map,
+ * initialize a bunch of registers.
+ */
+void cpu_init_f (void)
+{
+       DECLARE_GLOBAL_DATA_PTR;
+
+       volatile flexbus8220_t *flexbus = (volatile flexbus8220_t *) MMAP_FB;
+       volatile pcfg8220_t *portcfg = (volatile pcfg8220_t *) MMAP_PCFG;
+       volatile xlbarb8220_t *xlbarb = (volatile xlbarb8220_t *) MMAP_XLBARB;
+
+       /* Pointer is writable since we allocated a register for it */
+       gd = (gd_t *) (CFG_INIT_RAM_ADDR + CFG_GBL_DATA_OFFSET);
+
+       /* Clear initial global data */
+       memset ((void *) gd, 0, sizeof (gd_t));
+
+       /* Clear all port configuration */
+       portcfg->pcfg0 = 0;
+       portcfg->pcfg1 = 0;
+       portcfg->pcfg2 = 0;
+       portcfg->pcfg3 = 0;
+
+       /*
+        * Flexbus Controller: configure chip selects and enable them
+        */
+#if defined (CFG_CS0_BASE)
+       flexbus->csar0 = CFG_CS0_BASE;
+       flexbus->cscr0 = CFG_CS0_CTRL;
+       flexbus->csmr0 = ((CFG_CS0_MASK - 1) & 0xffff0000) | 1;
+       __asm__ volatile ("sync");
+#endif
+#if defined (CFG_CS1_BASE)
+       flexbus->csar1 = CFG_CS1_BASE;
+       flexbus->cscr1 = CFG_CS1_CTRL;
+       flexbus->csmr1 = ((CFG_CS1_MASK - 1) & 0xffff0000) | 1;
+       __asm__ volatile ("sync");
+#endif
+#if defined (CFG_CS2_BASE)
+       flexbus->csar2 = CFG_CS2_BASE;
+       flexbus->cscr2 = CFG_CS2_CTRL;
+       flexbus->csmr2 = ((CFG_CS2_MASK - 1) & 0xffff0000) | 1;
+       portcfg->pcfg3 |= CFG_CS2_PORT3_CONFIG;
+       __asm__ volatile ("sync");
+#endif
+#if defined (CFG_CS3_BASE)
+       flexbus->csar3 = CFG_CS3_BASE;
+       flexbus->cscr3 = CFG_CS3_CTRL;
+       flexbus->csmr3 = ((CFG_CS3_MASK - 1) & 0xffff0000) | 1;
+       portcfg->pcfg3 |= CFG_CS3_PORT3_CONFIG;
+       __asm__ volatile ("sync");
+#endif
+#if defined (CFG_CS4_BASE)
+       flexbus->csar4 = CFG_CS4_BASE;
+       flexbus->cscr4 = CFG_CS4_CTRL;
+       flexbus->csmr4 = ((CFG_CS4_MASK - 1) & 0xffff0000) | 1;
+       portcfg->pcfg3 |= CFG_CS4_PORT3_CONFIG;
+       __asm__ volatile ("sync");
+#endif
+#if defined (CFG_CS5_BASE)
+       flexbus->csar5 = CFG_CS5_BASE;
+       flexbus->cscr5 = CFG_CS5_CTRL;
+       flexbus->csmr5 = ((CFG_CS5_MASK - 1) & 0xffff0000) | 1;
+       portcfg->pcfg3 |= CFG_CS5_PORT3_CONFIG;
+       __asm__ volatile ("sync");
+#endif
+
+       /* This section of the code cannot place in cpu_init_r(),
+          it will cause the system to hang */
+       /* enable timebase */
+       xlbarb->config = 0x00002000;
+
+       xlbarb->addrTenTimeOut = 0x1000;
+       xlbarb->dataTenTimeOut = 0x1000;
+       xlbarb->busActTimeOut = 0x2000;
+
+       /* Master Priority Enable */
+       xlbarb->mastPriEn = 0x1f;
+       xlbarb->mastPriority = 0;
+}
+
+/*
+ * initialize higher level parts of CPU like time base and timers
+ */
+int cpu_init_r (void)
+{
+       /* this may belongs to disable interrupt section */
+       /* mask all interrupts */
+       *(vu_long *) 0xf0000700 = 0xfffffc00;
+       *(vu_long *) 0xf0000714 |= 0x0001ffff;
+       *(vu_long *) 0xf0000710 &= ~0x00000f00;
+
+       /* route critical ints to normal ints */
+       *(vu_long *) 0xf0000710 |= 0x00000001;
+
+#if (CONFIG_COMMANDS & CFG_CMD_NET) && defined(CONFIG_MPC8220_FEC)
+       /* load FEC microcode */
+       loadtask (0, 2);
+#endif
+       return (0);
+}
diff --git a/cpu/mpc8220/dma.h b/cpu/mpc8220/dma.h
new file mode 100644 (file)
index 0000000..d06ee63
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ * (C) Copyright 2003
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * This file is based on code
+ * (C) Copyright Motorola, Inc., 2000
+ *
+ * MPC8220 dma header file
+ */
+
+#ifndef __MPC8220_DMA_H
+#define __MPC8220_DMA_H
+
+#include <common.h>
+#include <mpc8220.h>
+
+/* Task number assignment */
+#define FEC_RECV_TASK_NO            0
+#define FEC_XMIT_TASK_NO            1
+
+/*---------------------------------------------------------------------
+ * Stuff for Ethernet Tx/Rx tasks
+ *---------------------------------------------------------------------
+ */
+
+/* Layout of Ethernet controller Parameter SRAM area:
+ * ----------------------------------------------------------------
+ * 0x00: TBD_BASE, base address of TX BD ring
+ * 0x04: TBD_NEXT, address of next TX BD to be processed
+ * 0x08: RBD_BASE, base address of RX BD ring
+ * 0x0C: RBD_NEXT, address of next RX BD to be processed
+ * ---------------------------------------------------------------
+ * ALL PARAMETERS ARE ALL LONGWORDS (FOUR BYTES EACH).
+ */
+
+/* base address of SRAM area to store parameters used by Ethernet tasks */
+#define FEC_PARAM_BASE  (MMAP_SRAM + 0x5b00)
+
+/* base address of SRAM area for buffer descriptors */
+#define FEC_BD_BASE     (MMAP_SRAM + 0x5b20)
+
+/*---------------------------------------------------------------------
+ * common shortcuts  used  by driver C code
+ *---------------------------------------------------------------------
+ */
+
+/* Disable SmartDMA task */
+#define DMA_TASK_DISABLE(tasknum)                                              \
+{                                                                              \
+       volatile ushort *tcr = (ushort *)(MMAP_DMA + 0x0000001c + 2 * tasknum); \
+       *tcr = (*tcr) & (~0x8000);                                              \
+}
+
+/* Enable SmartDMA task */
+#define DMA_TASK_ENABLE(tasknum)                                               \
+{                                                                              \
+       volatile ushort *tcr = (ushort *) (MMAP_DMA + 0x0000001c + 2 * tasknum);\
+       *tcr = (*tcr)  | 0x8000;                                                \
+}
+
+/* Clear interrupt pending bits */
+#define DMA_CLEAR_IEVENT(tasknum)                                              \
+{                                                                              \
+       struct mpc8220_dma *dma = (struct mpc8220_dma *)MMAP_DMA;               \
+       dma->IntPend = (1 << tasknum);                                          \
+}
+
+#endif  /* __MPC8220_DMA_H */
diff --git a/cpu/mpc8220/dramSetup.c b/cpu/mpc8220/dramSetup.c
new file mode 100644 (file)
index 0000000..033b719
--- /dev/null
@@ -0,0 +1,755 @@
+/*
+ * (C) Copyright 2004, Freescale, Inc
+ * TsiChung Liew, Tsi-Chung.Liew@freescale.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
+ */
+
+/*
+DESCRIPTION
+Read Dram spd and base on its information to calculate the memory size,
+characteristics to initialize the dram on MPC8220
+*/
+
+#include <common.h>
+#include <mpc8220.h>
+#include "i2cCore.h"
+#include "dramSetup.h"
+
+#define SPD_SIZE    0x40
+#define DRAM_SPD    0xA2       /* on Board SPD eeprom */
+#define TOTAL_BANK  2
+
+int spd_status (volatile i2c8220_t * pi2c, u8 sta_bit, u8 truefalse)
+{
+       int i;
+
+       for (i = 0; i < I2C_POLL_COUNT; i++) {
+               if ((pi2c->sr & sta_bit) == (truefalse ? sta_bit : 0))
+                       return (OK);
+       }
+
+       return (ERROR);
+}
+
+int spd_clear (volatile i2c8220_t * pi2c)
+{
+       pi2c->adr = 0;
+       pi2c->fdr = 0;
+       pi2c->cr = 0;
+       pi2c->sr = 0;
+
+       return (OK);
+}
+
+int spd_stop (volatile i2c8220_t * pi2c)
+{
+       pi2c->cr &= ~I2C_CTL_STA;       /* Generate stop signal         */
+       if (spd_status (pi2c, I2C_STA_BB, 0) != OK)
+               return ERROR;
+
+       return (OK);
+}
+
+int spd_readbyte (volatile i2c8220_t * pi2c, u8 * readb, int *index)
+{
+       pi2c->sr &= ~I2C_STA_IF;        /* Clear Interrupt Bit          */
+       *readb = pi2c->dr;      /* Read a byte                  */
+
+       /*
+          Set I2C_CTRL_TXAK will cause Transfer pending and
+          set I2C_CTRL_STA will cause Interrupt pending
+        */
+       if (*index != 2) {
+               if (spd_status (pi2c, I2C_STA_CF, 1) != OK)     /* Transfer not complete?       */
+                       return ERROR;
+       }
+
+       if (*index != 1) {
+               if (spd_status (pi2c, I2C_STA_IF, 1) != OK)
+                       return ERROR;
+       }
+
+       return (OK);
+}
+
+int readSpdData (u8 * spdData)
+{
+       DECLARE_GLOBAL_DATA_PTR;
+
+       volatile i2c8220_t *pi2cReg;
+       volatile pcfg8220_t *pcfg;
+       u8 slvAdr = DRAM_SPD;
+       u8 Tmp;
+       int Length = SPD_SIZE;
+       int i = 0;
+
+       /* Enable Port Configuration for SDA and SDL signals */
+       pcfg = (volatile pcfg8220_t *) (MMAP_PCFG);
+       __asm__ ("sync");
+       pcfg->pcfg3 &= ~CFG_I2C_PORT3_CONFIG;
+       __asm__ ("sync");
+
+       /* Points the structure to I2c mbar memory offset */
+       pi2cReg = (volatile i2c8220_t *) (MMAP_I2C);
+
+
+       /* Clear FDR, ADR, SR and CR reg */
+       pi2cReg->adr = 0;
+       pi2cReg->fdr = 0;
+       pi2cReg->cr = 0;
+       pi2cReg->sr = 0;
+
+       /* Set for fix XLB Bus Frequency */
+       switch (gd->bus_clk) {
+       case 60000000:
+               pi2cReg->fdr = 0x15;
+               break;
+       case 70000000:
+               pi2cReg->fdr = 0x16;
+               break;
+       case 80000000:
+               pi2cReg->fdr = 0x3a;
+               break;
+       case 90000000:
+               pi2cReg->fdr = 0x17;
+               break;
+       case 100000000:
+               pi2cReg->fdr = 0x3b;
+               break;
+       case 110000000:
+               pi2cReg->fdr = 0x18;
+               break;
+       case 120000000:
+               pi2cReg->fdr = 0x19;
+               break;
+       case 130000000:
+               pi2cReg->fdr = 0x1a;
+               break;
+       }
+
+       pi2cReg->adr = 0x90;    /* I2C device address */
+
+       pi2cReg->cr = I2C_CTL_EN;       /* Set Enable         */
+
+       /*
+          The I2C bus should be in Idle state. If the bus is busy,
+          clear the STA bit in control register
+        */
+       if (spd_status (pi2cReg, I2C_STA_BB, 0) != OK) {
+               if ((pi2cReg->cr & I2C_CTL_STA) == I2C_CTL_STA)
+                       pi2cReg->cr &= ~I2C_CTL_STA;
+
+               /* Check again if it is still busy, return error if found */
+               if (spd_status (pi2cReg, I2C_STA_BB, 1) == OK)
+                       return ERROR;
+       }
+
+       pi2cReg->cr |= I2C_CTL_TX;      /* Enable the I2c for TX, Ack   */
+       pi2cReg->cr |= I2C_CTL_STA;     /* Generate start signal        */
+
+       if (spd_status (pi2cReg, I2C_STA_BB, 1) != OK)
+               return ERROR;
+
+
+       /* Write slave address */
+       pi2cReg->sr &= ~I2C_STA_IF;     /* Clear Interrupt              */
+       pi2cReg->dr = slvAdr;   /* Write a byte                 */
+
+       if (spd_status (pi2cReg, I2C_STA_CF, 1) != OK) {        /* Transfer not complete?       */
+               spd_stop (pi2cReg);
+               return ERROR;
+       }
+
+       if (spd_status (pi2cReg, I2C_STA_IF, 1) != OK) {
+               spd_stop (pi2cReg);
+               return ERROR;
+       }
+
+
+       /* Issue the offset to start */
+       pi2cReg->sr &= ~I2C_STA_IF;     /* Clear Interrupt              */
+       pi2cReg->dr = 0;        /* Write a byte                 */
+
+       if (spd_status (pi2cReg, I2C_STA_CF, 1) != OK) {        /* Transfer not complete?       */
+               spd_stop (pi2cReg);
+               return ERROR;
+       }
+
+       if (spd_status (pi2cReg, I2C_STA_IF, 1) != OK) {
+               spd_stop (pi2cReg);
+               return ERROR;
+       }
+
+
+       /* Set repeat start */
+       pi2cReg->cr |= I2C_CTL_RSTA;    /* Repeat Start                 */
+
+       pi2cReg->sr &= ~I2C_STA_IF;     /* Clear Interrupt              */
+       pi2cReg->dr = slvAdr | 1;       /* Write a byte                 */
+
+       if (spd_status (pi2cReg, I2C_STA_CF, 1) != OK) {        /* Transfer not complete?       */
+               spd_stop (pi2cReg);
+               return ERROR;
+       }
+
+       if (spd_status (pi2cReg, I2C_STA_IF, 1) != OK) {
+               spd_stop (pi2cReg);
+               return ERROR;
+       }
+
+       if (((pi2cReg->sr & 0x07) == 0x07) || (pi2cReg->sr & 0x01))
+               return ERROR;
+
+       pi2cReg->cr &= ~I2C_CTL_TX;     /* Set receive mode             */
+
+       if (((pi2cReg->sr & 0x07) == 0x07) || (pi2cReg->sr & 0x01))
+               return ERROR;
+
+       /* Dummy Read */
+       if (spd_readbyte (pi2cReg, &Tmp, &i) != OK) {
+               spd_stop (pi2cReg);
+               return ERROR;
+       }
+
+       i = 0;
+       while (Length) {
+               if (Length == 2)
+                       pi2cReg->cr |= I2C_CTL_TXAK;
+
+               if (Length == 1)
+                       pi2cReg->cr &= ~I2C_CTL_STA;
+
+               if (spd_readbyte (pi2cReg, spdData, &Length) != OK) {
+                       return spd_stop (pi2cReg);
+               }
+               i++;
+               Length--;
+               spdData++;
+       }
+
+       /* Stop the service */
+       spd_stop (pi2cReg);
+
+       return OK;
+}
+
+int getBankInfo (int bank, draminfo_t * pBank)
+{
+       int status;
+       int checksum;
+       int count;
+       u8 spdData[SPD_SIZE];
+
+
+       if (bank > 2 || pBank == 0) {
+               /* illegal values */
+               return (-42);
+       }
+
+       status = readSpdData (&spdData[0]);
+       if (status < 0)
+               return (-1);
+
+       /* check the checksum */
+       for (count = 0, checksum = 0; count < LOC_CHECKSUM; count++)
+               checksum += spdData[count];
+
+       checksum = checksum - ((checksum / 256) * 256);
+
+       if (checksum != spdData[LOC_CHECKSUM])
+               return (-2);
+
+       /* Get the memory type */
+       if (!
+           ((spdData[LOC_TYPE] == TYPE_DDR)
+            || (spdData[LOC_TYPE] == TYPE_SDR)))
+               /* not one of the types we support */
+               return (-3);
+
+       pBank->type = spdData[LOC_TYPE];
+
+       /* Set logical banks */
+       pBank->banks = spdData[LOC_LOGICAL_BANKS];
+
+       /* Check that we have enough physical banks to cover the bank we are
+        * figuring out.  Odd-numbered banks correspond to the second bank
+        * on the device.
+        */
+       if (bank & 1) {
+               /* Second bank of a "device" */
+               if (spdData[LOC_PHYS_BANKS] < 2)
+                       /* this bank doesn't exist on the "device" */
+                       return (-4);
+
+               if (spdData[LOC_ROWS] & 0xf0)
+                       /* Two asymmetric banks */
+                       pBank->rows = spdData[LOC_ROWS] >> 4;
+               else
+                       pBank->rows = spdData[LOC_ROWS];
+
+               if (spdData[LOC_COLS] & 0xf0)
+                       /* Two asymmetric banks */
+                       pBank->cols = spdData[LOC_COLS] >> 4;
+               else
+                       pBank->cols = spdData[LOC_COLS];
+       } else {
+               /* First bank of a "device" */
+               pBank->rows = spdData[LOC_ROWS];
+               pBank->cols = spdData[LOC_COLS];
+       }
+
+       pBank->width = spdData[LOC_WIDTH_HIGH] << 8 | spdData[LOC_WIDTH_LOW];
+       pBank->bursts = spdData[LOC_BURSTS];
+       pBank->CAS = spdData[LOC_CAS];
+       pBank->CS = spdData[LOC_CS];
+       pBank->WE = spdData[LOC_WE];
+       pBank->Trp = spdData[LOC_Trp];
+       pBank->Trcd = spdData[LOC_Trcd];
+       pBank->buffered = spdData[LOC_Buffered] & 1;
+       pBank->refresh = spdData[LOC_REFRESH];
+
+       return (0);
+}
+
+
+/* checkMuxSetting -- given a row/column device geometry, return a mask
+ *                    of the valid DRAM controller addr_mux settings for
+ *                    that geometry.
+ *
+ *  Arguments:        u8 rows:     number of row addresses in this device
+ *                    u8 columns:  number of column addresses in this device
+ *
+ *  Returns:          a mask of the allowed addr_mux settings for this
+ *                    geometry.  Each bit in the mask represents a
+ *                    possible addr_mux settings (for example, the
+ *                    (1<<2) bit in the mask represents the 0b10 setting)/
+ *
+ */
+u8 checkMuxSetting (u8 rows, u8 columns)
+{
+       muxdesc_t *pIdx, *pMux;
+       u8 mask;
+       int lrows, lcolumns;
+       u32 mux[4] = { 0x00080c04, 0x01080d03, 0x02080e02, 0xffffffff };
+
+       /* Setup MuxDescriptor in SRAM space */
+       /* MUXDESC AddressRuns [] = {
+          { 0, 8, 12, 4 },         / setting, columns, rows, extra columns /
+          { 1, 8, 13, 3 },         / setting, columns, rows, extra columns /
+          { 2, 8, 14, 2 },         / setting, columns, rows, extra columns /
+          { 0xff }                 / list terminator /
+          }; */
+
+       pIdx = (muxdesc_t *) & mux[0];
+
+       /* Check rows x columns against each possible address mux setting */
+       for (pMux = pIdx, mask = 0;; pMux++) {
+               lrows = rows;
+               lcolumns = columns;
+
+               if (pMux->MuxValue == 0xff)
+                       break;  /* end of list */
+
+               /* For a given mux setting, since we want all the memory in a
+                * device to be contiguous, we want the device "use up" the
+                * address lines such that there are no extra column or row
+                * address lines on the device.
+                */
+
+               lcolumns -= pMux->Columns;
+               if (lcolumns < 0)
+                       /* Not enough columns to get to the rows */
+                       continue;
+
+               lrows -= pMux->Rows;
+               if (lrows > 0)
+                       /* we have extra rows left -- can't do that! */
+                       continue;
+
+               /* At this point, we either have to have used up all the
+                * rows or we have to have no columns left.
+                */
+
+               if (lcolumns != 0 && lrows != 0)
+                       /* rows AND columns are left.  Bad! */
+                       continue;
+
+               lcolumns -= pMux->MoreColumns;
+
+               if (lcolumns <= 0)
+                       mask |= (1 << pMux->MuxValue);
+       }
+
+       return (mask);
+}
+
+
+u32 dramSetup (void)
+{
+       DECLARE_GLOBAL_DATA_PTR;
+
+       draminfo_t DramInfo[TOTAL_BANK];
+       draminfo_t *pDramInfo;
+       u32 size, temp, cfg_value, mode_value, refresh;
+       u8 *ptr;
+       u8 bursts, Trp, Trcd, type, buffered;
+       u8 muxmask, rows, columns;
+       int count, banknum;
+       u32 *prefresh, *pIdx;
+       u32 refrate[8] = { 15625, 3900, 7800, 31300,
+               62500, 125000, 0xffffffff, 0xffffffff
+       };
+       volatile sysconf8220_t *sysconf;
+       volatile memctl8220_t *memctl;
+
+       sysconf = (volatile sysconf8220_t *) MMAP_MBAR;
+       memctl = (volatile memctl8220_t *) MMAP_MEMCTL;
+
+       /* Set everything in the descriptions to zero */
+       ptr = (u8 *) & DramInfo[0];
+       for (count = 0; count < sizeof (DramInfo); count++)
+               *ptr++ = 0;
+
+       for (banknum = 0; banknum < TOTAL_BANK; banknum++)
+               sysconf->cscfg[banknum];
+
+       /* Descriptions of row/column address muxing for various
+        * addr_mux settings.
+        */
+
+       pIdx = prefresh = (u32 *) & refrate[0];
+
+       /* Get all the info for all three logical banks */
+       bursts = 0xff;
+       Trp = 0;
+       Trcd = 0;
+       type = 0;
+       buffered = 0xff;
+       refresh = 0xffffffff;
+       muxmask = 0xff;
+
+       /* Two bank, CS0 and CS1 */
+       for (banknum = 0, pDramInfo = &DramInfo[0];
+            banknum < TOTAL_BANK; banknum++, pDramInfo++) {
+               pDramInfo->ordinal = banknum;   /* initial sorting */
+               if (getBankInfo (banknum, pDramInfo) < 0)
+                       continue;
+
+               /* get cumulative parameters of all three banks */
+               if (type && pDramInfo->type != type)
+                       return 0;
+
+               type = pDramInfo->type;
+               rows = pDramInfo->rows;
+               columns = pDramInfo->cols;
+
+               /* This chip only supports 13 DRAM memory lines, but some devices
+                * have 14 rows.  To deal with this, ignore the 14th address line
+                * by limiting the number of rows (and columns) to 13.  This will
+                * mean that for 14-row devices we will only be able to use
+                * half of the memory, but it's better than nothing.
+                */
+               if (rows > 13)
+                       rows = 13;
+               if (columns > 13)
+                       columns = 13;
+
+               pDramInfo->size =
+                       ((1 << (rows + columns)) * pDramInfo->width);
+               pDramInfo->size *= pDramInfo->banks;
+               pDramInfo->size >>= 3;
+
+               /* figure out which addr_mux configurations will support this device */
+               muxmask &= checkMuxSetting (rows, columns);
+               if (muxmask == 0)
+                       return 0;
+
+               buffered = pDramInfo->buffered;
+               bursts &= pDramInfo->bursts;    /* union of all bursts */
+               if (pDramInfo->Trp > Trp)       /* worst case (longest) Trp */
+                       Trp = pDramInfo->Trp;
+
+               if (pDramInfo->Trcd > Trcd)     /* worst case (longest) Trcd */
+                       Trcd = pDramInfo->Trcd;
+
+               prefresh = pIdx;
+               /* worst case (shortest) Refresh period */
+               if (refresh > prefresh[pDramInfo->refresh & 7])
+                       refresh = prefresh[pDramInfo->refresh & 7];
+
+       }                       /* for loop */
+
+
+       /* We only allow a burst length of 8! */
+       if (!(bursts & 8))
+               bursts = 8;
+
+       /* Sort the devices.  In order to get each chip select region
+        * aligned properly, put the biggest device at the lowest address.
+        * A simple bubble sort will do the trick.
+        */
+       for (banknum = 0, pDramInfo = &DramInfo[0];
+            banknum < TOTAL_BANK; banknum++, pDramInfo++) {
+               int i;
+
+               for (i = 0; i < TOTAL_BANK; i++) {
+                       if (pDramInfo->size < DramInfo[i].size &&
+                           pDramInfo->ordinal < DramInfo[i].ordinal) {
+                               /* If the current bank is smaller, but if the ordinal is also
+                                * smaller, swap the ordinals
+                                */
+                               u8 temp8;
+
+                               temp8 = DramInfo[i].ordinal;
+                               DramInfo[i].ordinal = pDramInfo->ordinal;
+                               pDramInfo->ordinal = temp8;
+                       }
+               }
+       }
+
+
+       /* Now figure out the base address for each bank.  While
+        * we're at it, figure out how much memory there is.
+        *
+        */
+       size = 0;
+       for (banknum = 0; banknum < TOTAL_BANK; banknum++) {
+               int i;
+
+               for (i = 0; i < TOTAL_BANK; i++) {
+                       if (DramInfo[i].ordinal == banknum
+                           && DramInfo[i].size != 0) {
+                               DramInfo[i].base = size;
+                               size += DramInfo[i].size;
+                       }
+               }
+       }
+
+       /* Set up the Drive Strength register */
+       temp = ((DRIVE_STRENGTH_LOW << SDRAMDS_SBE_SHIFT)
+               | (DRIVE_STRENGTH_HIGH << SDRAMDS_SBC_SHIFT)
+               | (DRIVE_STRENGTH_LOW << SDRAMDS_SBA_SHIFT)
+               | (DRIVE_STRENGTH_OFF << SDRAMDS_SBS_SHIFT)
+               | (DRIVE_STRENGTH_LOW << SDRAMDS_SBD_SHIFT));
+       sysconf->sdramds = temp;
+
+       /* ********************** Cfg 1 ************************* */
+
+       /* Set the single read to read/write/precharge delay */
+       cfg_value = CFG1_SRD2RWP ((type == TYPE_DDR) ? 7 : 0xb);
+
+       /* Set the single write to read/write/precharge delay.
+        * This may or may not be correct.  The controller spec
+        * says "tWR", but "tWR" does not appear in the SPD.  It
+        * always seems to be 15nsec for the class of device we're
+        * using, which turns out to be 2 clock cycles at 133MHz,
+        * so that's what we're going to use.
+        *
+        * HOWEVER, because of a bug in the controller, for DDR
+        * we need to set this to be the same as the value
+        * calculated for bwt2rwp.
+        */
+       cfg_value |= CFG1_SWT2RWP ((type == TYPE_DDR) ? 7 : 2);
+
+       /* Set the Read CAS latency.  We're going to use a CL of
+        * 2 for DDR and SDR.
+        */
+       cfg_value |= CFG1_RLATENCY ((type == TYPE_DDR) ? 7 : 2);
+
+
+       /* Set the Active to Read/Write delay.  This depends
+        * on Trcd which is reported as nanoseconds times 4.
+        * We want to calculate Trcd (in nanoseconds) times XLB clock (in Hz)
+        * which gives us a dimensionless quantity.  Play games with
+        * the divisions so we don't run out of dynamic ranges.
+        */
+       /* account for megaherz and the times 4 */
+       temp = (Trcd * (gd->bus_clk / 1000000)) / 4;
+
+       /* account for nanoseconds and round up, with a minimum value of 2 */
+       temp = ((temp + 999) / 1000) - 1;
+       if (temp < 2)
+               temp = 2;
+
+       cfg_value |= CFG1_ACT2WR (temp);
+
+       /* Set the precharge to active delay.  This depends
+        * on Trp which is reported as nanoseconds times 4.
+        * We want to calculate Trp (in nanoseconds) times XLB clock (in Hz)
+        * which gives us a dimensionless quantity.  Play games with
+        * the divisions so we don't run out of dynamic ranges.
+        */
+       /* account for megaherz and the times 4 */
+       temp = (Trp * (gd->bus_clk / 1000000)) / 4;
+
+       /* account for nanoseconds and round up, then subtract 1, with a
+        * minumum value of 1 and a maximum value of 7.
+        */
+       temp = (((temp + 999) / 1000) - 1) & 7;
+       if (temp < 1)
+               temp = 1;
+
+       cfg_value |= CFG1_PRE2ACT (temp);
+
+       /* Set refresh to active delay.  This depends
+        * on Trfc which is not reported in the SPD.
+        * We'll use a nominal value of 75nsec which is
+        * what the controller spec uses.
+        */
+       temp = (75 * (gd->bus_clk / 1000000));
+       /* account for nanoseconds and round up, then subtract 1 */
+       cfg_value |= CFG1_REF2ACT (((temp + 999) / 1000) - 1);
+
+       /* Set the write latency, using the values given in the controller spec */
+       cfg_value |= CFG1_WLATENCY ((type == TYPE_DDR) ? 3 : 0);
+       memctl->cfg1 = cfg_value;       /* cfg 1 */
+       asm volatile ("sync");
+
+
+       /* ********************** Cfg 2 ************************* */
+
+       /* Set the burst read to read/precharge delay */
+       cfg_value = CFG2_BRD2RP ((type == TYPE_DDR) ? 5 : 8);
+
+       /* Set the burst write to read/precharge delay.  Semi-magic numbers
+        * based on the controller spec recommendations, assuming tWR is
+        * two clock cycles.
+        */
+       cfg_value |= CFG2_BWT2RWP ((type == TYPE_DDR) ? 7 : 10);
+
+       /* Set the Burst read to write delay.  Semi-magic numbers
+        * based on the DRAM controller documentation.
+        */
+       cfg_value |= CFG2_BRD2WT ((type == TYPE_DDR) ? 7 : 0xb);
+
+       /* Set the burst length -- must be 8!! Well, 7, actually, becuase
+        * it's burst lenght minus 1.
+        */
+       cfg_value |= CFG2_BURSTLEN (7);
+       memctl->cfg2 = cfg_value;       /* cfg 2 */
+       asm volatile ("sync");
+
+
+       /* ********************** mode ************************* */
+
+       /* Set enable bit, CKE high/low bits, and the DDR/SDR mode bit,
+        * disable automatic refresh.
+        */
+       cfg_value = CTL_MODE_ENABLE | CTL_CKE_HIGH |
+               ((type == TYPE_DDR) ? CTL_DDR_MODE : 0);
+
+       /* Set the address mux based on whichever setting(s) is/are common
+        * to all the devices we have.  If there is more than one, choose
+        * one arbitrarily.
+        */
+       if (muxmask & 0x4)
+               cfg_value |= CTL_ADDRMUX (2);
+       else if (muxmask & 0x2)
+               cfg_value |= CTL_ADDRMUX (1);
+       else
+               cfg_value |= CTL_ADDRMUX (0);
+
+       /* Set the refresh interval. */
+       temp = ((refresh * (gd->bus_clk / 1000000)) / (1000 * 64)) - 1;
+       cfg_value |= CTL_REFRESH_INTERVAL (temp);
+
+       /* Set buffered/non-buffered memory */
+       if (buffered)
+               cfg_value |= CTL_BUFFERED;
+
+       memctl->ctrl = cfg_value;       /* ctrl */
+       asm volatile ("sync");
+
+       if (type == TYPE_DDR) {
+               /* issue precharge all */
+               temp = cfg_value | CTL_PRECHARGE_CMD;
+               memctl->ctrl = temp;    /* ctrl */
+               asm volatile ("sync");
+       }
+
+
+       /* Set up mode value for CAS latency == 2 */
+       mode_value = (MODE_MODE | MODE_BURSTLEN (MODE_BURSTLEN_8) |
+                     MODE_BT_SEQUENTIAL | MODE_CL (MODE_CL_2) | MODE_CMD);
+
+       asm volatile ("sync");
+
+       /* Write Extended Mode  - enable DLL */
+       if (type == TYPE_DDR) {
+               temp = MODE_EXTENDED | MODE_X_DLL_ENABLE |
+                       MODE_X_DS_NORMAL | MODE_CMD;
+               memctl->mode = (temp >> 16);    /* mode */
+               asm volatile ("sync");
+
+               /* Write Mode - reset DLL, set CAS latency == 2 */
+               temp = mode_value | MODE_OPMODE (MODE_OPMODE_RESETDLL);
+               memctl->mode = (temp >> 16);    /* mode */
+               asm volatile ("sync");
+       }
+
+       /* Program the chip selects. */
+       for (banknum = 0; banknum < TOTAL_BANK; banknum++) {
+               if (DramInfo[banknum].size != 0) {
+                       u32 mask;
+                       int i;
+
+                       for (i = 0, mask = 1; i < 32; mask <<= 1, i++) {
+                               if (DramInfo[banknum].size & mask)
+                                       break;
+                       }
+                       temp = (DramInfo[banknum].base & 0xfff00000) | (i -
+                                                                       1);
+
+                       sysconf->cscfg[banknum] = temp;
+                       asm volatile ("sync");
+               }
+       }
+
+       /* Wait for DLL lock */
+       udelay (200);
+
+       temp = cfg_value | CTL_PRECHARGE_CMD;   /* issue precharge all */
+       memctl->ctrl = temp;    /* ctrl */
+       asm volatile ("sync");
+
+       temp = cfg_value | CTL_REFRESH_CMD;     /* issue precharge all */
+       memctl->ctrl = temp;    /* ctrl */
+       asm volatile ("sync");
+
+       memctl->ctrl = temp;    /* ctrl */
+       asm volatile ("sync");
+
+       /* Write Mode - DLL normal */
+       temp = mode_value | MODE_OPMODE (MODE_OPMODE_NORMAL);
+       memctl->mode = (temp >> 16);    /* mode */
+       asm volatile ("sync");
+
+       /* Enable refresh, enable DQS's (if DDR), and lock the control register */
+       cfg_value &= ~CTL_MODE_ENABLE;  /* lock register */
+       cfg_value |= CTL_REFRESH_ENABLE;        /* enable refresh */
+
+       if (type == TYPE_DDR)
+               cfg_value |= CTL_DQSOEN (0xf);  /* enable DQS's for DDR */
+
+       memctl->ctrl = cfg_value;       /* ctrl */
+       asm volatile ("sync");
+
+       return size;
+}
diff --git a/cpu/mpc8220/dramSetup.h b/cpu/mpc8220/dramSetup.h
new file mode 100644 (file)
index 0000000..3b64e08
--- /dev/null
@@ -0,0 +1,108 @@
+/*
+ * dramSetup.h
+ *
+ * Prototypes, etc. for the Motorola MPC8220
+ * embedded cpu chips
+ *
+ * 2004 (c) Freescale, Inc.
+ * Author: TsiChung Liew <Tsi-Chung.Liew@freescale.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
+ */
+#ifndef __INCdramsetuph
+#define __INCdramsetuph
+#ifndef __ASSEMBLY__
+/* Where various things are in the SPD */
+#define LOC_TYPE                    2
+#define LOC_CHECKSUM                63
+#define LOC_PHYS_BANKS              5
+#define LOC_LOGICAL_BANKS           17
+#define LOC_ROWS                    3
+#define LOC_COLS                    4
+#define LOC_WIDTH_HIGH              7
+#define LOC_WIDTH_LOW               6
+#define LOC_REFRESH                 12
+#define LOC_BURSTS                  16
+#define LOC_CAS                     18
+#define LOC_CS                      19
+#define LOC_WE                      20
+#define LOC_Tcyc                    9
+#define LOC_Tac                     10
+#define LOC_Trp                     27
+#define LOC_Trrd                    28
+#define LOC_Trcd                    29
+#define LOC_Tras                    30
+#define LOC_Buffered                21
+/* Types of memory the SPD can tell us about.
+ * We can actually only use SDRAM and DDR.
+ */
+#define TYPE_DRAM                   1  /* plain old dram */
+#define TYPE_EDO                    2  /* EDO dram */
+#define TYPE_Nibble                 3  /* serial nibble memory */
+#define TYPE_SDR                    4  /* SDRAM */
+#define TYPE_ROM                    5  /*  */
+#define TYPE_SGRRAM                 6  /* graphics memory */
+#define TYPE_DDR                    7  /* DDR sdram */
+#define SDRAMDS_MASK        0x3        /* each field is 2 bits wide */
+#define SDRAMDS_SBE_SHIFT     8        /* Clock enable drive strength */
+#define SDRAMDS_SBC_SHIFT     6        /* Clocks drive strength */
+#define SDRAMDS_SBA_SHIFT     4        /* Address drive strength */
+#define SDRAMDS_SBS_SHIFT     2        /* SDR DQS drive strength */
+#define SDRAMDS_SBD_SHIFT     0        /* Data and DQS drive strength */
+#define  DRIVE_STRENGTH_HIGH 0
+#define  DRIVE_STRENGTH_MED  1
+#define  DRIVE_STRENGTH_LOW  2
+#define  DRIVE_STRENGTH_OFF  3
+
+#define OK      0
+#define ERROR   -1
+/* Structure to hold information about address muxing. */
+       typedef struct tagMuxDescriptor {
+       u8 MuxValue;
+       u8 Columns;
+       u8 Rows;
+       u8 MoreColumns;
+} muxdesc_t;
+
+/* Structure to define one physical bank of
+ * memory.  Note that dram size in bytes is
+ * (2^^(rows+columns)) * width * banks / 8
+*/
+typedef struct tagDramInfo {
+       u32 size;               /* size in bytes */
+       u32 base;               /* base address */
+       u8 ordinal;             /* where in the memory map will we put this */
+       u8 type;
+       u8 rows;
+       u8 cols;
+       u16 width;              /* width of each chip in bits */
+       u8 banks;               /* number of chips, aka logical banks */
+       u8 bursts;              /* bit-encoded allowable burst length */
+       u8 CAS;                 /* bit-encoded CAS latency values */
+       u8 CS;                  /* bit-encoded CS latency values */
+       u8 WE;                  /* bit-encoded WE latency values */
+       u8 Trp;                 /* bit-encoded row precharge time */
+       u8 Trcd;                /* bit-encoded RAS to CAS delay */
+       u8 buffered;            /* buffered or not */
+       u8 refresh;             /* encoded refresh rate */
+} draminfo_t;
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* __INCdramsetuph */
diff --git a/cpu/mpc8220/fec.c b/cpu/mpc8220/fec.c
new file mode 100644 (file)
index 0000000..1bc51cd
--- /dev/null
@@ -0,0 +1,993 @@
+/*
+ * (C) Copyright 2003
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * This file is based on mpc4200fec.c,
+ * (C) Copyright Motorola, Inc., 2000
+ */
+
+#include <common.h>
+#include <mpc8220.h>
+#include <malloc.h>
+#include <net.h>
+#include <miiphy.h>
+#include "dma.h"
+#include "fec.h"
+
+#define DEBUG  0
+/*tbd - rtm */
+/*#if (CONFIG_COMMANDS & CFG_CMD_NET) && defined(CONFIG_NET_MULTI) && \
+    defined(CONFIG_MPC8220_FEC)*/
+
+#if (CONFIG_COMMANDS & CFG_CMD_NET)
+
+#if (DEBUG & 0x60)
+static void tfifo_print (mpc8220_fec_priv * fec);
+static void rfifo_print (mpc8220_fec_priv * fec);
+#endif /* DEBUG */
+
+#if (DEBUG & 0x40)
+static u32 local_crc32 (char *string, unsigned int crc_value, int len);
+#endif
+
+typedef struct {
+       u8 data[1500];          /* actual data */
+       int length;             /* actual length */
+       int used;               /* buffer in use or not */
+       u8 head[16];            /* MAC header(6 + 6 + 2) + 2(aligned) */
+} NBUF;
+
+/********************************************************************/
+#if (DEBUG & 0x2)
+static void mpc8220_fec_phydump (void)
+{
+       u16 phyStatus, i;
+       u8 phyAddr = CONFIG_PHY_ADDR;
+       u8 reg_mask[] = {
+#if CONFIG_PHY_TYPE == 0x79c874 /* AMD Am79C874 */
+               /* regs to print: 0...7, 16...19, 21, 23, 24 */
+               1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0,
+               1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0,
+#else
+               /* regs to print: 0...8, 16...20 */
+               1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0,
+               1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+#endif
+       };
+
+       for (i = 0; i < 32; i++) {
+               if (reg_mask[i]) {
+                       miiphy_read (phyAddr, i, &phyStatus);
+                       printf ("Mii reg %d: 0x%04x\n", i, phyStatus);
+               }
+       }
+}
+#endif
+
+/********************************************************************/
+static int mpc8220_fec_rbd_init (mpc8220_fec_priv * fec)
+{
+       int ix;
+       char *data;
+       static int once = 0;
+
+       for (ix = 0; ix < FEC_RBD_NUM; ix++) {
+               if (!once) {
+                       data = (char *) malloc (FEC_MAX_PKT_SIZE);
+                       if (data == NULL) {
+                               printf ("RBD INIT FAILED\n");
+                               return -1;
+                       }
+                       fec->rbdBase[ix].dataPointer = (u32) data;
+               }
+               fec->rbdBase[ix].status = FEC_RBD_EMPTY;
+               fec->rbdBase[ix].dataLength = 0;
+       }
+       once++;
+
+       /*
+        * have the last RBD to close the ring
+        */
+       fec->rbdBase[ix - 1].status |= FEC_RBD_WRAP;
+       fec->rbdIndex = 0;
+
+       return 0;
+}
+
+/********************************************************************/
+static void mpc8220_fec_tbd_init (mpc8220_fec_priv * fec)
+{
+       int ix;
+
+       for (ix = 0; ix < FEC_TBD_NUM; ix++) {
+               fec->tbdBase[ix].status = 0;
+       }
+
+       /*
+        * Have the last TBD to close the ring
+        */
+       fec->tbdBase[ix - 1].status |= FEC_TBD_WRAP;
+
+       /*
+        * Initialize some indices
+        */
+       fec->tbdIndex = 0;
+       fec->usedTbdIndex = 0;
+       fec->cleanTbdNum = FEC_TBD_NUM;
+}
+
+/********************************************************************/
+static void mpc8220_fec_rbd_clean (mpc8220_fec_priv * fec, FEC_RBD * pRbd)
+{
+       /*
+        * Reset buffer descriptor as empty
+        */
+       if ((fec->rbdIndex) == (FEC_RBD_NUM - 1))
+               pRbd->status = (FEC_RBD_WRAP | FEC_RBD_EMPTY);
+       else
+               pRbd->status = FEC_RBD_EMPTY;
+
+       pRbd->dataLength = 0;
+
+       /*
+        * Now, we have an empty RxBD, restart the SmartDMA receive task
+        */
+       DMA_TASK_ENABLE (FEC_RECV_TASK_NO);
+
+       /*
+        * Increment BD count
+        */
+       fec->rbdIndex = (fec->rbdIndex + 1) % FEC_RBD_NUM;
+}
+
+/********************************************************************/
+static void mpc8220_fec_tbd_scrub (mpc8220_fec_priv * fec)
+{
+       FEC_TBD *pUsedTbd;
+
+#if (DEBUG & 0x1)
+       printf ("tbd_scrub: fec->cleanTbdNum = %d, fec->usedTbdIndex = %d\n",
+               fec->cleanTbdNum, fec->usedTbdIndex);
+#endif
+
+       /*
+        * process all the consumed TBDs
+        */
+       while (fec->cleanTbdNum < FEC_TBD_NUM) {
+               pUsedTbd = &fec->tbdBase[fec->usedTbdIndex];
+               if (pUsedTbd->status & FEC_TBD_READY) {
+#if (DEBUG & 0x20)
+                       printf ("Cannot clean TBD %d, in use\n",
+                               fec->cleanTbdNum);
+#endif
+                       return;
+               }
+
+               /*
+                * clean this buffer descriptor
+                */
+               if (fec->usedTbdIndex == (FEC_TBD_NUM - 1))
+                       pUsedTbd->status = FEC_TBD_WRAP;
+               else
+                       pUsedTbd->status = 0;
+
+               /*
+                * update some indeces for a correct handling of the TBD ring
+                */
+               fec->cleanTbdNum++;
+               fec->usedTbdIndex = (fec->usedTbdIndex + 1) % FEC_TBD_NUM;
+       }
+}
+
+/********************************************************************/
+static void mpc8220_fec_set_hwaddr (mpc8220_fec_priv * fec, char *mac)
+{
+       u8 currByte;            /* byte for which to compute the CRC */
+       int byte;               /* loop - counter */
+       int bit;                /* loop - counter */
+       u32 crc = 0xffffffff;   /* initial value */
+
+       /*
+        * The algorithm used is the following:
+        * we loop on each of the six bytes of the provided address,
+        * and we compute the CRC by left-shifting the previous
+        * value by one position, so that each bit in the current
+        * byte of the address may contribute the calculation. If
+        * the latter and the MSB in the CRC are different, then
+        * the CRC value so computed is also ex-ored with the
+        * "polynomium generator". The current byte of the address
+        * is also shifted right by one bit at each iteration.
+        * This is because the CRC generatore in hardware is implemented
+        * as a shift-register with as many ex-ores as the radixes
+        * in the polynomium. This suggests that we represent the
+        * polynomiumm itself as a 32-bit constant.
+        */
+       for (byte = 0; byte < 6; byte++) {
+               currByte = mac[byte];
+               for (bit = 0; bit < 8; bit++) {
+                       if ((currByte & 0x01) ^ (crc & 0x01)) {
+                               crc >>= 1;
+                               crc = crc ^ 0xedb88320;
+                       } else {
+                               crc >>= 1;
+                       }
+                       currByte >>= 1;
+               }
+       }
+
+       crc = crc >> 26;
+
+       /*
+        * Set individual hash table register
+        */
+       if (crc >= 32) {
+               fec->eth->iaddr1 = (1 << (crc - 32));
+               fec->eth->iaddr2 = 0;
+       } else {
+               fec->eth->iaddr1 = 0;
+               fec->eth->iaddr2 = (1 << crc);
+       }
+
+       /*
+        * Set physical address
+        */
+       fec->eth->paddr1 =
+               (mac[0] << 24) + (mac[1] << 16) + (mac[2] << 8) + mac[3];
+       fec->eth->paddr2 = (mac[4] << 24) + (mac[5] << 16) + 0x8808;
+}
+
+/********************************************************************/
+static int mpc8220_fec_init (struct eth_device *dev, bd_t * bis)
+{
+       mpc8220_fec_priv *fec = (mpc8220_fec_priv *) dev->priv;
+       struct mpc8220_dma *dma = (struct mpc8220_dma *) MMAP_DMA;
+       const u8 phyAddr = CONFIG_PHY_ADDR;     /* Only one PHY */
+
+#if (DEBUG & 0x1)
+       printf ("mpc8220_fec_init... Begin\n");
+#endif
+
+       /*
+        * Initialize RxBD/TxBD rings
+        */
+       mpc8220_fec_rbd_init (fec);
+       mpc8220_fec_tbd_init (fec);
+
+       /*
+        * Set up Pin Muxing for FEC 1
+        */
+       *(vu_long *) MMAP_PCFG = 0;
+       *(vu_long *) (MMAP_PCFG + 4) = 0;
+       /*
+        * Clear FEC-Lite interrupt event register(IEVENT)
+        */
+       fec->eth->ievent = 0xffffffff;
+
+       /*
+        * Set interrupt mask register
+        */
+       fec->eth->imask = 0x00000000;
+
+       /*
+        * Set FEC-Lite receive control register(R_CNTRL):
+        */
+       if (fec->xcv_type == SEVENWIRE) {
+               /*
+                * Frame length=1518; 7-wire mode
+                */
+               fec->eth->r_cntrl = 0x05ee0020; /*0x05ee0000;FIXME */
+       } else {
+               /*
+                * Frame length=1518; MII mode;
+                */
+               fec->eth->r_cntrl = 0x05ee0024; /*0x05ee0004;FIXME */
+       }
+
+       fec->eth->x_cntrl = 0x00000000; /* half-duplex, heartbeat disabled */
+       if (fec->xcv_type != SEVENWIRE) {
+               /*
+                * Set MII_SPEED = (1/(mii_speed * 2)) * System Clock
+                * and do not drop the Preamble.
+                */
+               /* tbd - rtm */
+               /*fec->eth->mii_speed = (((gd->ipb_clk >> 20) / 5) << 1); */
+               /* No MII for 7-wire mode */
+               fec->eth->mii_speed = 0x00000030;
+       }
+
+       /*
+        * Set Opcode/Pause Duration Register
+        */
+       fec->eth->op_pause = 0x00010020;        /*FIXME0xffff0020; */
+
+       /*
+        * Set Rx FIFO alarm and granularity value
+        */
+       fec->eth->rfifo_cntrl = 0x0c000000;
+       fec->eth->rfifo_alarm = 0x0000030c;
+#if (DEBUG & 0x22)
+       if (fec->eth->rfifo_status & 0x00700000) {
+               printf ("mpc8220_fec_init() RFIFO error\n");
+       }
+#endif
+
+       /*
+        * Set Tx FIFO granularity value
+        */
+       /*fec->eth->tfifo_cntrl = 0x0c000000; */ /*tbd - rtm */
+       fec->eth->tfifo_cntrl = 0x0e000000;
+#if (DEBUG & 0x2)
+       printf ("tfifo_status: 0x%08x\n", fec->eth->tfifo_status);
+       printf ("tfifo_alarm: 0x%08x\n", fec->eth->tfifo_alarm);
+#endif
+
+       /*
+        * Set transmit fifo watermark register(X_WMRK), default = 64
+        */
+       fec->eth->tfifo_alarm = 0x00000080;
+       fec->eth->x_wmrk = 0x2;
+
+       /*
+        * Set individual address filter for unicast address
+        * and set physical address registers.
+        */
+       mpc8220_fec_set_hwaddr (fec, dev->enetaddr);
+
+       /*
+        * Set multicast address filter
+        */
+       fec->eth->gaddr1 = 0x00000000;
+       fec->eth->gaddr2 = 0x00000000;
+
+       /*
+        * Turn ON cheater FSM: ????
+        */
+       fec->eth->xmit_fsm = 0x03000000;
+
+#if 1
+/*#if defined(CONFIG_MPC5200)*/
+       /*
+        * Turn off COMM bus prefetch in the MGT5200 BestComm. It doesn't
+        * work w/ the current receive task.
+        */
+       dma->PtdCntrl |= 0x00000001;
+#endif
+
+       /*
+        * Set priority of different initiators
+        */
+       dma->IPR0 = 7;          /* always */
+       dma->IPR3 = 6;          /* Eth RX */
+       dma->IPR4 = 5;          /* Eth Tx */
+
+       /*
+        * Clear SmartDMA task interrupt pending bits
+        */
+       DMA_CLEAR_IEVENT (FEC_RECV_TASK_NO);
+
+       /*
+        * Initialize SmartDMA parameters stored in SRAM
+        */
+       *(int *) FEC_TBD_BASE = (int) fec->tbdBase;
+       *(int *) FEC_RBD_BASE = (int) fec->rbdBase;
+       *(int *) FEC_TBD_NEXT = (int) fec->tbdBase;
+       *(int *) FEC_RBD_NEXT = (int) fec->rbdBase;
+
+       if (fec->xcv_type != SEVENWIRE) {
+               /*
+                * Initialize PHY(LXT971A):
+                *
+                *   Generally, on power up, the LXT971A reads its configuration
+                *   pins to check for forced operation, If not cofigured for
+                *   forced operation, it uses auto-negotiation/parallel detection
+                *   to automatically determine line operating conditions.
+                *   If the PHY device on the other side of the link supports
+                *   auto-negotiation, the LXT971A auto-negotiates with it
+                *   using Fast Link Pulse(FLP) Bursts. If the PHY partner does not
+                *   support auto-negotiation, the LXT971A automatically detects
+                *   the presence of either link pulses(10Mbps PHY) or Idle
+                *   symbols(100Mbps) and sets its operating conditions accordingly.
+                *
+                *   When auto-negotiation is controlled by software, the following
+                *   steps are recommended.
+                *
+                * Note:
+                *   The physical address is dependent on hardware configuration.
+                *
+                */
+               int timeout = 1;
+               u16 phyStatus;
+
+               /*
+                * Reset PHY, then delay 300ns
+                */
+               miiphy_write (phyAddr, 0x0, 0x8000);
+               udelay (1000);
+
+               if (fec->xcv_type == MII10) {
+                       /*
+                        * Force 10Base-T, FDX operation
+                        */
+#if (DEBUG & 0x2)
+                       printf ("Forcing 10 Mbps ethernet link... ");
+#endif
+                       miiphy_read (phyAddr, 0x1, &phyStatus);
+                       /*
+                          miiphy_write(fec, phyAddr, 0x0, 0x0100);
+                        */
+                       miiphy_write (phyAddr, 0x0, 0x0180);
+
+                       timeout = 20;
+                       do {    /* wait for link status to go down */
+                               udelay (10000);
+                               if ((timeout--) == 0) {
+#if (DEBUG & 0x2)
+                                       printf ("hmmm, should not have waited...");
+#endif
+                                       break;
+                               }
+                               miiphy_read (phyAddr, 0x1, &phyStatus);
+#if (DEBUG & 0x2)
+                               printf ("=");
+#endif
+                       } while ((phyStatus & 0x0004)); /* !link up */
+
+                       timeout = 1000;
+                       do {    /* wait for link status to come back up */
+                               udelay (10000);
+                               if ((timeout--) == 0) {
+                                       printf ("failed. Link is down.\n");
+                                       break;
+                               }
+                               miiphy_read (phyAddr, 0x1, &phyStatus);
+#if (DEBUG & 0x2)
+                               printf ("+");
+#endif
+                       } while (!(phyStatus & 0x0004));        /* !link up */
+
+#if (DEBUG & 0x2)
+                       printf ("done.\n");
+#endif
+               } else {        /* MII100 */
+                       /*
+                        * Set the auto-negotiation advertisement register bits
+                        */
+                       miiphy_write (phyAddr, 0x4, 0x01e1);
+
+                       /*
+                        * Set MDIO bit 0.12 = 1(&& bit 0.9=1?) to enable auto-negotiation
+                        */
+                       miiphy_write (phyAddr, 0x0, 0x1200);
+
+                       /*
+                        * Wait for AN completion
+                        */
+                       timeout = 5000;
+                       do {
+                               udelay (1000);
+
+                               if ((timeout--) == 0) {
+#if (DEBUG & 0x2)
+                                       printf ("PHY auto neg 0 failed...\n");
+#endif
+                                       return -1;
+                               }
+
+                               if (miiphy_read (phyAddr, 0x1, &phyStatus) !=
+                                   0) {
+#if (DEBUG & 0x2)
+                                       printf ("PHY auto neg 1 failed 0x%04x...\n", phyStatus);
+#endif
+                                       return -1;
+                               }
+                       } while (!(phyStatus & 0x0004));
+
+#if (DEBUG & 0x2)
+                       printf ("PHY auto neg complete! \n");
+#endif
+               }
+
+       }
+
+       /*
+        * Enable FEC-Lite controller
+        */
+       fec->eth->ecntrl |= 0x00000006;
+
+#if (DEBUG & 0x2)
+       if (fec->xcv_type != SEVENWIRE)
+               mpc8220_fec_phydump ();
+#endif
+
+       /*
+        * Enable SmartDMA receive task
+        */
+       DMA_TASK_ENABLE (FEC_RECV_TASK_NO);
+
+#if (DEBUG & 0x1)
+       printf ("mpc8220_fec_init... Done \n");
+#endif
+
+       return 1;
+}
+
+/********************************************************************/
+static void mpc8220_fec_halt (struct eth_device *dev)
+{
+       mpc8220_fec_priv *fec = (mpc8220_fec_priv *) dev->priv;
+       int counter = 0xffff;
+
+#if (DEBUG & 0x2)
+       if (fec->xcv_type != SEVENWIRE)
+               mpc8220_fec_phydump ();
+#endif
+
+       /*
+        * mask FEC chip interrupts
+        */
+       fec->eth->imask = 0;
+
+       /*
+        * issue graceful stop command to the FEC transmitter if necessary
+        */
+       fec->eth->x_cntrl |= 0x00000001;
+
+       /*
+        * wait for graceful stop to register
+        */
+       while ((counter--) && (!(fec->eth->ievent & 0x10000000)));
+
+       /*
+        * Disable SmartDMA tasks
+        */
+       DMA_TASK_DISABLE (FEC_XMIT_TASK_NO);
+       DMA_TASK_DISABLE (FEC_RECV_TASK_NO);
+
+       /*
+        * Disable the Ethernet Controller
+        */
+       fec->eth->ecntrl &= 0xfffffffd;
+
+       /*
+        * Clear FIFO status registers
+        */
+       fec->eth->rfifo_status &= 0x00700000;
+       fec->eth->tfifo_status &= 0x00700000;
+
+       fec->eth->reset_cntrl = 0x01000000;
+
+       /*
+        * Issue a reset command to the FEC chip
+        */
+       fec->eth->ecntrl |= 0x1;
+
+       /*
+        * wait at least 16 clock cycles
+        */
+       udelay (10);
+
+#if (DEBUG & 0x3)
+       printf ("Ethernet task stopped\n");
+#endif
+}
+
+#if (DEBUG & 0x60)
+/********************************************************************/
+
+static void tfifo_print (mpc8220_fec_priv * fec)
+{
+       u16 phyAddr = CONFIG_PHY_ADDR;
+       u16 phyStatus;
+
+       if ((fec->eth->tfifo_lrf_ptr != fec->eth->tfifo_lwf_ptr)
+           || (fec->eth->tfifo_rdptr != fec->eth->tfifo_wrptr)) {
+
+               miiphy_read (phyAddr, 0x1, &phyStatus);
+               printf ("\nphyStatus: 0x%04x\n", phyStatus);
+               printf ("ecntrl:   0x%08x\n", fec->eth->ecntrl);
+               printf ("ievent:   0x%08x\n", fec->eth->ievent);
+               printf ("x_status: 0x%08x\n", fec->eth->x_status);
+               printf ("tfifo: status  0x%08x\n", fec->eth->tfifo_status);
+
+               printf ("       control 0x%08x\n", fec->eth->tfifo_cntrl);
+               printf ("       lrfp    0x%08x\n", fec->eth->tfifo_lrf_ptr);
+               printf ("       lwfp    0x%08x\n", fec->eth->tfifo_lwf_ptr);
+               printf ("       alarm   0x%08x\n", fec->eth->tfifo_alarm);
+               printf ("       readptr 0x%08x\n", fec->eth->tfifo_rdptr);
+               printf ("       writptr 0x%08x\n", fec->eth->tfifo_wrptr);
+       }
+}
+
+static void rfifo_print (mpc8220_fec_priv * fec)
+{
+       u16 phyAddr = CONFIG_PHY_ADDR;
+       u16 phyStatus;
+
+       if ((fec->eth->rfifo_lrf_ptr != fec->eth->rfifo_lwf_ptr)
+           || (fec->eth->rfifo_rdptr != fec->eth->rfifo_wrptr)) {
+
+               miiphy_read (phyAddr, 0x1, &phyStatus);
+               printf ("\nphyStatus: 0x%04x\n", phyStatus);
+               printf ("ecntrl:   0x%08x\n", fec->eth->ecntrl);
+               printf ("ievent:   0x%08x\n", fec->eth->ievent);
+               printf ("x_status: 0x%08x\n", fec->eth->x_status);
+               printf ("rfifo: status  0x%08x\n", fec->eth->rfifo_status);
+
+               printf ("       control 0x%08x\n", fec->eth->rfifo_cntrl);
+               printf ("       lrfp    0x%08x\n", fec->eth->rfifo_lrf_ptr);
+               printf ("       lwfp    0x%08x\n", fec->eth->rfifo_lwf_ptr);
+               printf ("       alarm   0x%08x\n", fec->eth->rfifo_alarm);
+               printf ("       readptr 0x%08x\n", fec->eth->rfifo_rdptr);
+               printf ("       writptr 0x%08x\n", fec->eth->rfifo_wrptr);
+       }
+}
+#endif /* DEBUG */
+
+/********************************************************************/
+
+static int mpc8220_fec_send (struct eth_device *dev, volatile void *eth_data,
+                            int data_length)
+{
+       /*
+        * This routine transmits one frame.  This routine only accepts
+        * 6-byte Ethernet addresses.
+        */
+       mpc8220_fec_priv *fec = (mpc8220_fec_priv *) dev->priv;
+       FEC_TBD *pTbd;
+
+#if (DEBUG & 0x20)
+       printf ("tbd status: 0x%04x\n", fec->tbdBase[0].status);
+       tfifo_print (fec);
+#endif
+
+       /*
+        * Clear Tx BD ring at first
+        */
+       mpc8220_fec_tbd_scrub (fec);
+
+       /*
+        * Check for valid length of data.
+        */
+       if ((data_length > 1500) || (data_length <= 0)) {
+               return -1;
+       }
+
+       /*
+        * Check the number of vacant TxBDs.
+        */
+       if (fec->cleanTbdNum < 1) {
+#if (DEBUG & 0x20)
+               printf ("No available TxBDs ...\n");
+#endif
+               return -1;
+       }
+
+       /*
+        * Get the first TxBD to send the mac header
+        */
+       pTbd = &fec->tbdBase[fec->tbdIndex];
+       pTbd->dataLength = data_length;
+       pTbd->dataPointer = (u32) eth_data;
+       pTbd->status |= FEC_TBD_LAST | FEC_TBD_TC | FEC_TBD_READY;
+       fec->tbdIndex = (fec->tbdIndex + 1) % FEC_TBD_NUM;
+
+#if (DEBUG & 0x100)
+       printf ("DMA_TASK_ENABLE, fec->tbdIndex = %d \n", fec->tbdIndex);
+#endif
+
+       /*
+        * Kick the MII i/f
+        */
+       if (fec->xcv_type != SEVENWIRE) {
+               u16 phyStatus;
+
+               miiphy_read (0, 0x1, &phyStatus);
+       }
+
+       /*
+        * Enable SmartDMA transmit task
+        */
+
+#if (DEBUG & 0x20)
+       tfifo_print (fec);
+#endif
+
+       DMA_TASK_ENABLE (FEC_XMIT_TASK_NO);
+
+#if (DEBUG & 0x20)
+       tfifo_print (fec);
+#endif
+
+#if (DEBUG & 0x8)
+       printf ("+");
+#endif
+
+       fec->cleanTbdNum -= 1;
+
+#if (DEBUG & 0x129) && (DEBUG & 0x80000000)
+       printf ("smartDMA ethernet Tx task enabled\n");
+#endif
+       /*
+        * wait until frame is sent .
+        */
+       while (pTbd->status & FEC_TBD_READY) {
+               udelay (10);
+#if (DEBUG & 0x8)
+               printf ("TDB status = %04x\n", pTbd->status);
+#endif
+       }
+
+       return 0;
+}
+
+
+/********************************************************************/
+static int mpc8220_fec_recv (struct eth_device *dev)
+{
+       /*
+        * This command pulls one frame from the card
+        */
+       mpc8220_fec_priv *fec = (mpc8220_fec_priv *) dev->priv;
+       FEC_RBD *pRbd = &fec->rbdBase[fec->rbdIndex];
+       unsigned long ievent;
+       int frame_length, len = 0;
+       NBUF *frame;
+
+#if (DEBUG & 0x1)
+       printf ("mpc8220_fec_recv %d Start...\n", fec->rbdIndex);
+#endif
+#if (DEBUG & 0x8)
+       printf ("-");
+#endif
+
+       /*
+        * Check if any critical events have happened
+        */
+       ievent = fec->eth->ievent;
+       fec->eth->ievent = ievent;
+       if (ievent & 0x20060000) {
+               /* BABT, Rx/Tx FIFO errors */
+               mpc8220_fec_halt (dev);
+               mpc8220_fec_init (dev, NULL);
+               return 0;
+       }
+       if (ievent & 0x80000000) {
+               /* Heartbeat error */
+               fec->eth->x_cntrl |= 0x00000001;
+       }
+       if (ievent & 0x10000000) {
+               /* Graceful stop complete */
+               if (fec->eth->x_cntrl & 0x00000001) {
+                       mpc8220_fec_halt (dev);
+                       fec->eth->x_cntrl &= ~0x00000001;
+                       mpc8220_fec_init (dev, NULL);
+               }
+       }
+
+       if (!(pRbd->status & FEC_RBD_EMPTY)) {
+               if ((pRbd->status & FEC_RBD_LAST)
+                   && !(pRbd->status & FEC_RBD_ERR)
+                   && ((pRbd->dataLength - 4) > 14)) {
+
+                       /*
+                        * Get buffer address and size
+                        */
+                       frame = (NBUF *) pRbd->dataPointer;
+                       frame_length = pRbd->dataLength - 4;
+
+#if (0)
+                       {
+                               int i;
+
+                               printf ("recv data hdr:");
+                               for (i = 0; i < 14; i++)
+                                       printf ("%x ", *(frame->head + i));
+                               printf ("\n");
+                       }
+#endif
+                       /*
+                        *  Fill the buffer and pass it to upper layers
+                        */
+/*                     memcpy(buff, frame->head, 14);
+                       memcpy(buff + 14, frame->data, frame_length);*/
+                       NetReceive ((volatile uchar *) pRbd->dataPointer,
+                                   frame_length);
+                       len = frame_length;
+               }
+               /*
+                * Reset buffer descriptor as empty
+                */
+               mpc8220_fec_rbd_clean (fec, pRbd);
+       }
+       DMA_CLEAR_IEVENT (FEC_RECV_TASK_NO);
+       return len;
+}
+
+
+/********************************************************************/
+int mpc8220_fec_initialize (bd_t * bis)
+{
+       mpc8220_fec_priv *fec;
+
+#ifdef CONFIG_ETH1ADDR
+       mpc8220_fec_priv *fec2;
+#endif
+       struct eth_device *dev;
+       char *tmp, *end;
+       char env_enetaddr[6];
+
+#ifdef CONFIG_ETH1ADDR
+       char env_enet1addr[6];
+#endif
+       int i;
+
+       fec = (mpc8220_fec_priv *) malloc (sizeof (*fec));
+       dev = (struct eth_device *) malloc (sizeof (*dev));
+       memset (dev, 0, sizeof *dev);
+
+       fec->eth = (ethernet_regs *) MMAP_FEC1;
+#ifdef CONFIG_ETH1ADDR
+       fec2 = (mpc8220_fec_priv *) malloc (sizeof (*fec));
+       fec2->eth = (ethernet_regs *) MMAP_FEC2;
+#endif
+       fec->tbdBase = (FEC_TBD *) FEC_BD_BASE;
+       fec->rbdBase =
+               (FEC_RBD *) (FEC_BD_BASE + FEC_TBD_NUM * sizeof (FEC_TBD));
+       fec->xcv_type = MII100;
+
+       dev->priv = (void *) fec;
+       dev->iobase = MMAP_FEC1;
+       dev->init = mpc8220_fec_init;
+       dev->halt = mpc8220_fec_halt;
+       dev->send = mpc8220_fec_send;
+       dev->recv = mpc8220_fec_recv;
+
+       sprintf (dev->name, "FEC ETHERNET");
+       eth_register (dev);
+
+       /*
+        * Try to set the mac address now. The fec mac address is
+        * a garbage after reset. When not using fec for booting
+        * the Linux fec driver will try to work with this garbage.
+        */
+       tmp = getenv ("ethaddr");
+       if (tmp) {
+               for (i = 0; i < 6; i++) {
+                       env_enetaddr[i] =
+                               tmp ? simple_strtoul (tmp, &end, 16) : 0;
+                       if (tmp)
+                               tmp = (*end) ? end + 1 : end;
+               }
+               mpc8220_fec_set_hwaddr (fec, env_enetaddr);
+       }
+#ifdef CONFIG_ETH1ADDR
+       tmp = getenv ("eth1addr");
+       if (tmp) {
+               for (i = 0; i < 6; i++) {
+                       env_enet1addr[i] =
+                               tmp ? simple_strtoul (tmp, &end, 16) : 0;
+                       if (tmp)
+                               tmp = (*end) ? end + 1 : end;
+               }
+               mpc8220_fec_set_hwaddr (fec2, env_enet1addr);
+       }
+#endif
+
+       return 1;
+}
+
+/* MII-interface related functions */
+/********************************************************************/
+int miiphy_read (u8 phyAddr, u8 regAddr, u16 * retVal)
+{
+       ethernet_regs *eth = (ethernet_regs *) MMAP_FEC1;
+       u32 reg;                /* convenient holder for the PHY register */
+       u32 phy;                /* convenient holder for the PHY */
+       int timeout = 0xffff;
+
+       /*
+        * reading from any PHY's register is done by properly
+        * programming the FEC's MII data register.
+        */
+       reg = regAddr << FEC_MII_DATA_RA_SHIFT;
+       phy = phyAddr << FEC_MII_DATA_PA_SHIFT;
+
+       eth->mii_data =
+               (FEC_MII_DATA_ST | FEC_MII_DATA_OP_RD | FEC_MII_DATA_TA | phy
+                | reg);
+
+       /*
+        * wait for the related interrupt
+        */
+       while ((timeout--) && (!(eth->ievent & 0x00800000)));
+
+       if (timeout == 0) {
+#if (DEBUG & 0x2)
+               printf ("Read MDIO failed...\n");
+#endif
+               return -1;
+       }
+
+       /*
+        * clear mii interrupt bit
+        */
+       eth->ievent = 0x00800000;
+
+       /*
+        * it's now safe to read the PHY's register
+        */
+       *retVal = (u16) eth->mii_data;
+
+       return 0;
+}
+
+/********************************************************************/
+int miiphy_write (u8 phyAddr, u8 regAddr, u16 data)
+{
+       ethernet_regs *eth = (ethernet_regs *) MMAP_FEC1;
+       u32 reg;                /* convenient holder for the PHY register */
+       u32 phy;                /* convenient holder for the PHY */
+       int timeout = 0xffff;
+
+       reg = regAddr << FEC_MII_DATA_RA_SHIFT;
+       phy = phyAddr << FEC_MII_DATA_PA_SHIFT;
+
+       eth->mii_data = (FEC_MII_DATA_ST | FEC_MII_DATA_OP_WR |
+                        FEC_MII_DATA_TA | phy | reg | data);
+
+       /*
+        * wait for the MII interrupt
+        */
+       while ((timeout--) && (!(eth->ievent & 0x00800000)));
+
+       if (timeout == 0) {
+#if (DEBUG & 0x2)
+               printf ("Write MDIO failed...\n");
+#endif
+               return -1;
+       }
+
+       /*
+        * clear MII interrupt bit
+        */
+       eth->ievent = 0x00800000;
+
+       return 0;
+}
+
+#if (DEBUG & 0x40)
+static u32 local_crc32 (char *string, unsigned int crc_value, int len)
+{
+       int i;
+       char c;
+       unsigned int crc, count;
+
+       /*
+        * crc32 algorithm
+        */
+       /*
+        * crc = 0xffffffff; * The initialized value should be 0xffffffff
+        */
+       crc = crc_value;
+
+       for (i = len; --i >= 0;) {
+               c = *string++;
+               for (count = 0; count < 8; count++) {
+                       if ((c & 0x01) ^ (crc & 0x01)) {
+                               crc >>= 1;
+                               crc = crc ^ 0xedb88320;
+                       } else {
+                               crc >>= 1;
+                       }
+                       c >>= 1;
+               }
+       }
+
+       /*
+        * In big endian system, do byte swaping for crc value
+        */
+       return crc;
+}
+#endif /* DEBUG */
+
+#endif /* CONFIG_MPC8220_FEC */
diff --git a/cpu/mpc8220/fec.h b/cpu/mpc8220/fec.h
new file mode 100644 (file)
index 0000000..a8927fc
--- /dev/null
@@ -0,0 +1,283 @@
+/*
+ * (C) Copyright 2003-2004
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * This file is based on mpc4200fec.h
+ * (C) Copyright Motorola, Inc., 2000
+ *
+ * odin ethernet header file
+ */
+
+#ifndef __MPC8220_FEC_H
+#define __MPC8220_FEC_H
+
+#include <common.h>
+#include <mpc8220.h>
+#include "dma.h"
+
+typedef struct ethernet_register_set {
+
+/* [10:2]addr = 00 */
+
+/*  Control and status Registers (offset 000-1FF) */
+
+       volatile u32 fec_id;            /* MBAR_ETH + 0x000 */
+       volatile u32 ievent;            /* MBAR_ETH + 0x004 */
+       volatile u32 imask;             /* MBAR_ETH + 0x008 */
+
+       volatile u32 RES0[1];           /* MBAR_ETH + 0x00C */
+       volatile u32 r_des_active;      /* MBAR_ETH + 0x010 */
+       volatile u32 x_des_active;      /* MBAR_ETH + 0x014 */
+       volatile u32 r_des_active_cl;   /* MBAR_ETH + 0x018 */
+       volatile u32 x_des_active_cl;   /* MBAR_ETH + 0x01C */
+       volatile u32 ivent_set;         /* MBAR_ETH + 0x020 */
+       volatile u32 ecntrl;            /* MBAR_ETH + 0x024 */
+
+       volatile u32 RES1[6];           /* MBAR_ETH + 0x028-03C */
+       volatile u32 mii_data;          /* MBAR_ETH + 0x040 */
+       volatile u32 mii_speed;         /* MBAR_ETH + 0x044 */
+       volatile u32 mii_status;        /* MBAR_ETH + 0x048 */
+
+       volatile u32 RES2[5];           /* MBAR_ETH + 0x04C-05C */
+       volatile u32 mib_data;          /* MBAR_ETH + 0x060 */
+       volatile u32 mib_control;       /* MBAR_ETH + 0x064 */
+
+       volatile u32 RES3[6];           /* MBAR_ETH + 0x068-7C */
+       volatile u32 r_activate;        /* MBAR_ETH + 0x080 */
+       volatile u32 r_cntrl;           /* MBAR_ETH + 0x084 */
+       volatile u32 r_hash;            /* MBAR_ETH + 0x088 */
+       volatile u32 r_data;            /* MBAR_ETH + 0x08C */
+       volatile u32 ar_done;           /* MBAR_ETH + 0x090 */
+       volatile u32 r_test;            /* MBAR_ETH + 0x094 */
+       volatile u32 r_mib;             /* MBAR_ETH + 0x098 */
+       volatile u32 r_da_low;          /* MBAR_ETH + 0x09C */
+       volatile u32 r_da_high;         /* MBAR_ETH + 0x0A0 */
+
+       volatile u32 RES4[7];           /* MBAR_ETH + 0x0A4-0BC */
+       volatile u32 x_activate;        /* MBAR_ETH + 0x0C0 */
+       volatile u32 x_cntrl;           /* MBAR_ETH + 0x0C4 */
+       volatile u32 backoff;           /* MBAR_ETH + 0x0C8 */
+       volatile u32 x_data;            /* MBAR_ETH + 0x0CC */
+       volatile u32 x_status;          /* MBAR_ETH + 0x0D0 */
+       volatile u32 x_mib;             /* MBAR_ETH + 0x0D4 */
+       volatile u32 x_test;            /* MBAR_ETH + 0x0D8 */
+       volatile u32 fdxfc_da1;         /* MBAR_ETH + 0x0DC */
+       volatile u32 fdxfc_da2;         /* MBAR_ETH + 0x0E0 */
+       volatile u32 paddr1;            /* MBAR_ETH + 0x0E4 */
+       volatile u32 paddr2;            /* MBAR_ETH + 0x0E8 */
+       volatile u32 op_pause;          /* MBAR_ETH + 0x0EC */
+
+       volatile u32 RES5[4];           /* MBAR_ETH + 0x0F0-0FC */
+       volatile u32 instr_reg;         /* MBAR_ETH + 0x100 */
+       volatile u32 context_reg;       /* MBAR_ETH + 0x104 */
+       volatile u32 test_cntrl;        /* MBAR_ETH + 0x108 */
+       volatile u32 acc_reg;           /* MBAR_ETH + 0x10C */
+       volatile u32 ones;              /* MBAR_ETH + 0x110 */
+       volatile u32 zeros;             /* MBAR_ETH + 0x114 */
+       volatile u32 iaddr1;            /* MBAR_ETH + 0x118 */
+       volatile u32 iaddr2;            /* MBAR_ETH + 0x11C */
+       volatile u32 gaddr1;            /* MBAR_ETH + 0x120 */
+       volatile u32 gaddr2;            /* MBAR_ETH + 0x124 */
+       volatile u32 random;            /* MBAR_ETH + 0x128 */
+       volatile u32 rand1;             /* MBAR_ETH + 0x12C */
+       volatile u32 tmp;               /* MBAR_ETH + 0x130 */
+
+       volatile u32 RES6[3];           /* MBAR_ETH + 0x134-13C */
+       volatile u32 fifo_id;           /* MBAR_ETH + 0x140 */
+       volatile u32 x_wmrk;            /* MBAR_ETH + 0x144 */
+       volatile u32 fcntrl;            /* MBAR_ETH + 0x148 */
+       volatile u32 r_bound;           /* MBAR_ETH + 0x14C */
+       volatile u32 r_fstart;          /* MBAR_ETH + 0x150 */
+       volatile u32 r_count;           /* MBAR_ETH + 0x154 */
+       volatile u32 r_lag;             /* MBAR_ETH + 0x158 */
+       volatile u32 r_read;            /* MBAR_ETH + 0x15C */
+       volatile u32 r_write;           /* MBAR_ETH + 0x160 */
+       volatile u32 x_count;           /* MBAR_ETH + 0x164 */
+       volatile u32 x_lag;             /* MBAR_ETH + 0x168 */
+       volatile u32 x_retry;           /* MBAR_ETH + 0x16C */
+       volatile u32 x_write;           /* MBAR_ETH + 0x170 */
+       volatile u32 x_read;            /* MBAR_ETH + 0x174 */
+
+       volatile u32 RES7[2];           /* MBAR_ETH + 0x178-17C */
+       volatile u32 fm_cntrl;          /* MBAR_ETH + 0x180 */
+       volatile u32 rfifo_data;        /* MBAR_ETH + 0x184 */
+       volatile u32 rfifo_status;      /* MBAR_ETH + 0x188 */
+       volatile u32 rfifo_cntrl;       /* MBAR_ETH + 0x18C */
+       volatile u32 rfifo_lrf_ptr;     /* MBAR_ETH + 0x190 */
+       volatile u32 rfifo_lwf_ptr;     /* MBAR_ETH + 0x194 */
+       volatile u32 rfifo_alarm;       /* MBAR_ETH + 0x198 */
+       volatile u32 rfifo_rdptr;       /* MBAR_ETH + 0x19C */
+       volatile u32 rfifo_wrptr;       /* MBAR_ETH + 0x1A0 */
+       volatile u32 tfifo_data;        /* MBAR_ETH + 0x1A4 */
+       volatile u32 tfifo_status;      /* MBAR_ETH + 0x1A8 */
+       volatile u32 tfifo_cntrl;       /* MBAR_ETH + 0x1AC */
+       volatile u32 tfifo_lrf_ptr;     /* MBAR_ETH + 0x1B0 */
+       volatile u32 tfifo_lwf_ptr;     /* MBAR_ETH + 0x1B4 */
+       volatile u32 tfifo_alarm;       /* MBAR_ETH + 0x1B8 */
+       volatile u32 tfifo_rdptr;       /* MBAR_ETH + 0x1BC */
+       volatile u32 tfifo_wrptr;       /* MBAR_ETH + 0x1C0 */
+
+       volatile u32 reset_cntrl;       /* MBAR_ETH + 0x1C4 */
+       volatile u32 xmit_fsm;          /* MBAR_ETH + 0x1C8 */
+
+       volatile u32 RES8[3];           /* MBAR_ETH + 0x1CC-1D4 */
+       volatile u32 rdes_data0;        /* MBAR_ETH + 0x1D8 */
+       volatile u32 rdes_data1;        /* MBAR_ETH + 0x1DC */
+       volatile u32 r_length;          /* MBAR_ETH + 0x1E0 */
+       volatile u32 x_length;          /* MBAR_ETH + 0x1E4 */
+       volatile u32 x_addr;            /* MBAR_ETH + 0x1E8 */
+       volatile u32 cdes_data;         /* MBAR_ETH + 0x1EC */
+       volatile u32 status;            /* MBAR_ETH + 0x1F0 */
+       volatile u32 dma_control;       /* MBAR_ETH + 0x1F4 */
+       volatile u32 des_cmnd;          /* MBAR_ETH + 0x1F8 */
+       volatile u32 data;              /* MBAR_ETH + 0x1FC */
+
+       /*  MIB COUNTERS (Offset 200-2FF) */
+
+       volatile u32 rmon_t_drop;       /* MBAR_ETH + 0x200 */
+       volatile u32 rmon_t_packets;    /* MBAR_ETH + 0x204 */
+       volatile u32 rmon_t_bc_pkt;     /* MBAR_ETH + 0x208 */
+       volatile u32 rmon_t_mc_pkt;     /* MBAR_ETH + 0x20C */
+       volatile u32 rmon_t_crc_align;  /* MBAR_ETH + 0x210 */
+       volatile u32 rmon_t_undersize;  /* MBAR_ETH + 0x214 */
+       volatile u32 rmon_t_oversize;   /* MBAR_ETH + 0x218 */
+       volatile u32 rmon_t_frag;       /* MBAR_ETH + 0x21C */
+       volatile u32 rmon_t_jab;        /* MBAR_ETH + 0x220 */
+       volatile u32 rmon_t_col;        /* MBAR_ETH + 0x224 */
+       volatile u32 rmon_t_p64;        /* MBAR_ETH + 0x228 */
+       volatile u32 rmon_t_p65to127;   /* MBAR_ETH + 0x22C */
+       volatile u32 rmon_t_p128to255;  /* MBAR_ETH + 0x230 */
+       volatile u32 rmon_t_p256to511;  /* MBAR_ETH + 0x234 */
+       volatile u32 rmon_t_p512to1023; /* MBAR_ETH + 0x238 */
+       volatile u32 rmon_t_p1024to2047;/* MBAR_ETH + 0x23C */
+       volatile u32 rmon_t_p_gte2048;  /* MBAR_ETH + 0x240 */
+       volatile u32 rmon_t_octets;     /* MBAR_ETH + 0x244 */
+       volatile u32 ieee_t_drop;       /* MBAR_ETH + 0x248 */
+       volatile u32 ieee_t_frame_ok;   /* MBAR_ETH + 0x24C */
+       volatile u32 ieee_t_1col;       /* MBAR_ETH + 0x250 */
+       volatile u32 ieee_t_mcol;       /* MBAR_ETH + 0x254 */
+       volatile u32 ieee_t_def;        /* MBAR_ETH + 0x258 */
+       volatile u32 ieee_t_lcol;       /* MBAR_ETH + 0x25C */
+       volatile u32 ieee_t_excol;      /* MBAR_ETH + 0x260 */
+       volatile u32 ieee_t_macerr;     /* MBAR_ETH + 0x264 */
+       volatile u32 ieee_t_cserr;      /* MBAR_ETH + 0x268 */
+       volatile u32 ieee_t_sqe;        /* MBAR_ETH + 0x26C */
+       volatile u32 t_fdxfc;           /* MBAR_ETH + 0x270 */
+       volatile u32 ieee_t_octets_ok;  /* MBAR_ETH + 0x274 */
+
+       volatile u32 RES9[2];           /* MBAR_ETH + 0x278-27C */
+       volatile u32 rmon_r_drop;       /* MBAR_ETH + 0x280 */
+       volatile u32 rmon_r_packets;    /* MBAR_ETH + 0x284 */
+       volatile u32 rmon_r_bc_pkt;     /* MBAR_ETH + 0x288 */
+       volatile u32 rmon_r_mc_pkt;     /* MBAR_ETH + 0x28C */
+       volatile u32 rmon_r_crc_align;  /* MBAR_ETH + 0x290 */
+       volatile u32 rmon_r_undersize;  /* MBAR_ETH + 0x294 */
+       volatile u32 rmon_r_oversize;   /* MBAR_ETH + 0x298 */
+       volatile u32 rmon_r_frag;       /* MBAR_ETH + 0x29C */
+       volatile u32 rmon_r_jab;        /* MBAR_ETH + 0x2A0 */
+
+       volatile u32 rmon_r_resvd_0;    /* MBAR_ETH + 0x2A4 */
+
+       volatile u32 rmon_r_p64;        /* MBAR_ETH + 0x2A8 */
+       volatile u32 rmon_r_p65to127;   /* MBAR_ETH + 0x2AC */
+       volatile u32 rmon_r_p128to255;  /* MBAR_ETH + 0x2B0 */
+       volatile u32 rmon_r_p256to511;  /* MBAR_ETH + 0x2B4 */
+       volatile u32 rmon_r_p512to1023; /* MBAR_ETH + 0x2B8 */
+       volatile u32 rmon_r_p1024to2047;/* MBAR_ETH + 0x2BC */
+       volatile u32 rmon_r_p_gte2048;  /* MBAR_ETH + 0x2C0 */
+       volatile u32 rmon_r_octets;     /* MBAR_ETH + 0x2C4 */
+       volatile u32 ieee_r_drop;       /* MBAR_ETH + 0x2C8 */
+       volatile u32 ieee_r_frame_ok;   /* MBAR_ETH + 0x2CC */
+       volatile u32 ieee_r_crc;        /* MBAR_ETH + 0x2D0 */
+       volatile u32 ieee_r_align;      /* MBAR_ETH + 0x2D4 */
+       volatile u32 r_macerr;          /* MBAR_ETH + 0x2D8 */
+       volatile u32 r_fdxfc;           /* MBAR_ETH + 0x2DC */
+       volatile u32 ieee_r_octets_ok;  /* MBAR_ETH + 0x2E0 */
+
+       volatile u32 RES10[6];          /* MBAR_ETH + 0x2E4-2FC */
+
+       volatile u32 RES11[64];         /* MBAR_ETH + 0x300-3FF */
+} ethernet_regs;
+
+/* Receive & Transmit Buffer Descriptor definitions */
+typedef struct BufferDescriptor {
+       u16 status;
+       u16 dataLength;
+       u32 dataPointer;
+} FEC_RBD;
+
+typedef struct {
+       u16 status;
+       u16 dataLength;
+       u32 dataPointer;
+} FEC_TBD;
+
+/* private structure */
+typedef enum {
+       SEVENWIRE,              /* 7-wire       */
+       MII10,                  /* MII 10Mbps   */
+       MII100                  /* MII 100Mbps  */
+} xceiver_type;
+
+typedef struct {
+       ethernet_regs *eth;
+       xceiver_type xcv_type;  /* transceiver type */
+       FEC_RBD *rbdBase;       /* RBD ring */
+       FEC_TBD *tbdBase;       /* TBD ring */
+       u16 rbdIndex;           /* next receive BD to read */
+       u16 tbdIndex;           /* next transmit BD to send */
+       u16 usedTbdIndex;       /* next transmit BD to clean */
+       u16 cleanTbdNum;        /* the number of available transmit BDs */
+} mpc8220_fec_priv;
+
+/* Ethernet parameter area */
+#define FEC_TBD_BASE       (FEC_PARAM_BASE + 0x00)
+#define FEC_TBD_NEXT       (FEC_PARAM_BASE + 0x04)
+#define FEC_RBD_BASE       (FEC_PARAM_BASE + 0x08)
+#define FEC_RBD_NEXT       (FEC_PARAM_BASE + 0x0c)
+
+/* BD Numer definitions */
+#define FEC_TBD_NUM       48   /* The user can adjust this value */
+#define FEC_RBD_NUM       32   /* The user can adjust this value */
+
+/* packet size limit */
+#define FEC_MAX_PKT_SIZE   1536
+
+/* RBD bits definitions */
+#define FEC_RBD_EMPTY  0x8000  /* Buffer is empty */
+#define FEC_RBD_WRAP   0x2000  /* Last BD in ring */
+#define FEC_RBD_INT    0x1000  /* Interrupt */
+#define FEC_RBD_LAST   0x0800  /* Buffer is last in frame(useless) */
+#define FEC_RBD_MISS   0x0100  /* Miss bit for prom mode */
+#define FEC_RBD_BC     0x0080  /* The received frame is broadcast frame */
+#define FEC_RBD_MC     0x0040  /* The received frame is multicast frame */
+#define FEC_RBD_LG     0x0020  /* Frame length violation */
+#define FEC_RBD_NO     0x0010  /* Nonoctet align frame */
+#define FEC_RBD_SH     0x0008  /* Short frame */
+#define FEC_RBD_CR     0x0004  /* CRC error */
+#define FEC_RBD_OV     0x0002  /* Receive FIFO overrun */
+#define FEC_RBD_TR     0x0001  /* Frame is truncated */
+#define FEC_RBD_ERR    (FEC_RBD_LG | FEC_RBD_NO | FEC_RBD_CR | \
+                        FEC_RBD_OV | FEC_RBD_TR)
+
+/* TBD bits definitions */
+#define FEC_TBD_READY  0x8000  /* Buffer is ready */
+#define FEC_TBD_WRAP   0x2000  /* Last BD in ring */
+#define FEC_TBD_INT    0x1000  /* Interrupt */
+#define FEC_TBD_LAST   0x0800  /* Buffer is last in frame */
+#define FEC_TBD_TC     0x0400  /* Transmit the CRC */
+#define FEC_TBD_ABC    0x0200  /* Append bad CRC */
+
+/* MII-related definitios */
+#define FEC_MII_DATA_ST                0x40000000      /* Start of frame delimiter */
+#define FEC_MII_DATA_OP_RD     0x20000000      /* Perform a read operation */
+#define FEC_MII_DATA_OP_WR     0x10000000      /* Perform a write operation */
+#define FEC_MII_DATA_PA_MSK    0x0f800000      /* PHY Address field mask */
+#define FEC_MII_DATA_RA_MSK    0x007c0000      /* PHY Register field mask */
+#define FEC_MII_DATA_TA                0x00020000      /* Turnaround */
+#define FEC_MII_DATA_DATAMSK   0x0000ffff      /* PHY data field */
+
+#define FEC_MII_DATA_RA_SHIFT  18      /* MII Register address bits */
+#define FEC_MII_DATA_PA_SHIFT  23      /* MII PHY address bits */
+
+#endif /* __MPC8220_FEC_H */
diff --git a/cpu/mpc8220/fec_dma_tasks.S b/cpu/mpc8220/fec_dma_tasks.S
new file mode 100644 (file)
index 0000000..3f8a03b
--- /dev/null
@@ -0,0 +1,363 @@
+/*
+ * Copyright (C) 2004, Freescale Semiconductor, Inc.
+ *
+ * This file contains microcode for the FEC controller of the MPC8220.
+ */
+
+#include <config.h>
+
+#if defined(CONFIG_MPC8220)
+
+/* sas/sccg, gas target */
+.section        smartdmaInitData,"aw",@progbits        /* Initialized data for task variables */
+.section        smartdmaTaskTable,"aw",@progbits       /* Task tables */
+.align  9
+.globl taskTable
+taskTable:
+.globl scEthernetRecv_Entry
+scEthernetRecv_Entry:          /* Task 0 */
+.long   scEthernetRecv_TDT - taskTable /* Task 0 Descriptor Table */
+.long   scEthernetRecv_TDT - taskTable + 0x00000094
+.long   scEthernetRecv_VarTab - taskTable      /* Task 0 Variable Table */
+.long   scEthernetRecv_FDT - taskTable + 0x03  /* Task 0 Function Descriptor Table & Flags */
+.long   0x00000000
+.long   0x00000000
+.long   scEthernetRecv_CSave - taskTable       /* Task 0 context save space */
+.long   0xf0000000
+.globl scEthernetXmit_Entry
+scEthernetXmit_Entry:          /* Task 1 */
+.long   scEthernetXmit_TDT - taskTable /* Task 1 Descriptor Table */
+.long   scEthernetXmit_TDT - taskTable + 0x000000e0
+.long   scEthernetXmit_VarTab - taskTable      /* Task 1 Variable Table */
+.long   scEthernetXmit_FDT - taskTable + 0x03  /* Task 1 Function Descriptor Table & Flags */
+.long   0x00000000
+.long   0x00000000
+.long   scEthernetXmit_CSave - taskTable       /* Task 1 context save space */
+.long   0xf0000000
+
+
+.globl scEthernetRecv_TDT
+scEthernetRecv_TDT:    /* Task 0 Descriptor Table */
+.long   0xc4c50000     /* 0000(153):  LCDEXT: idx0 = var9 + var10; idx0 once var0; idx0 += inc0 */
+.long   0x84c5e000     /* 0004(153):  LCD: idx1 = var9 + var11; ; idx1 += inc0 */
+.long   0x10001f08     /* 0008(156):    DRD1A: var7 = idx1; FN=0 MORE init=0 WS=0 RS=0 */
+.long   0x10000380     /* 000C(157):    DRD1A: var0 = *idx0; FN=0 MORE init=0 WS=0 RS=0 */
+.long   0x00000f88     /* 0010(158):    DRD1A: var3 = *idx1; FN=0 init=0 WS=0 RS=0 */
+.long   0x81980000     /* 0014(162):  LCD: idx0 = var3; idx0 once var0; idx0 += inc0 */
+.long   0x10000780     /* 0018(164):    DRD1A: var1 = *idx0; FN=0 MORE init=0 WS=0 RS=0 */
+.long   0x60000000     /* 001C(165):    DRD2A: EU0=0 EU1=0 EU2=0 EU3=0 EXT init=0 WS=0 RS=0 */
+.long   0x010cf04c     /* 0020(165):    DRD2B1: var4 = EU3(); EU3(var1,var12)  */
+.long   0x82180349     /* 0024(169):  LCD: idx0 = var4; idx0 != var13; idx0 += inc1 */
+.long   0x81c68004     /* 0028(172):    LCD: idx1 = var3 + var13 + 4; idx1 once var0; idx1 += inc0 */
+.long   0x70000000     /* 002C(174):      DRD2A: EU0=0 EU1=0 EU2=0 EU3=0 EXT MORE init=0 WS=0 RS=0 */
+.long   0x018cf04e     /* 0030(174):      DRD2B1: var6 = EU3(); EU3(var1,var14)  */
+.long   0x70000000     /* 0034(175):      DRD2A: EU0=0 EU1=0 EU2=0 EU3=0 EXT MORE init=0 WS=0 RS=0 */
+.long   0x020cf04f     /* 0038(175):      DRD2B1: var8 = EU3(); EU3(var1,var15)  */
+.long   0x00000b88     /* 003C(176):      DRD1A: var2 = *idx1; FN=0 init=0 WS=0 RS=0 */
+.long   0x80025184     /* 0040(205):    LCDEXT: idx1 = 0xf0009184; ; */
+.long   0x86810412     /* 0044(205):    LCD: idx2 = var13, idx3 = var2; idx2 < var16; idx2 += inc2, idx3 += inc2 */
+.long   0x0200cf88     /* 0048(209):      DRD1A: *idx3 = *idx1; FN=0 init=16 WS=0 RS=0 */
+.long   0x80025184     /* 004C(217):    LCDEXT: idx1 = 0xf0009184; ; */
+.long   0x8681845b     /* 0050(217):    LCD: idx2 = var13, idx3 = var3; idx2 < var17; idx2 += inc3, idx3 += inc3 */
+.long   0x0000cf88     /* 0054(221):      DRD1A: *idx3 = *idx1; FN=0 init=0 WS=0 RS=0 */
+.long   0xc31883a4     /* 0058(225):    LCDEXT: idx1 = var6; idx1 == var14; idx1 += inc4 */
+.long   0x80190000     /* 005C(225):    LCD: idx2 = var0; idx2 once var0; idx2 += inc0 */
+.long   0x04008468     /* 0060(227):      DRD1A: idx1 = var13; FN=0 INT init=0 WS=0 RS=0 */
+.long   0xc4038360     /* 0064(232):    LCDEXT: idx1 = var8, idx2 = var7; idx1 == var13; idx1 += inc4, idx2 += inc0 */
+.long   0x81c50000     /* 0068(233):    LCD: idx3 = var3 + var10; idx3 once var0; idx3 += inc0 */
+.long   0x1000cb18     /* 006C(235):      DRD1A: *idx2 = idx3; FN=0 MORE init=0 WS=0 RS=0 */
+.long   0x00000f18     /* 0070(236):      DRD1A: var3 = idx3; FN=0 init=0 WS=0 RS=0 */
+.long   0xc418836d     /* 0074(238):    LCDEXT: idx1 = var8; idx1 > var13; idx1 += inc5 */
+.long   0x83990000     /* 0078(238):    LCD: idx2 = var7; idx2 once var0; idx2 += inc0 */
+.long   0x10000c00     /* 007C(240):      DRD1A: var3 = var0; FN=0 MORE init=0 WS=0 RS=0 */
+.long   0x0000c800     /* 0080(241):      DRD1A: *idx2 = var0; FN=0 init=0 WS=0 RS=0 */
+.long   0x81988000     /* 0084(245):    LCD: idx1 = var3; idx1 once var0; idx1 += inc0 */
+.long   0x10000788     /* 0088(247):      DRD1A: var1 = *idx1; FN=0 MORE init=0 WS=0 RS=0 */
+.long   0x60000000     /* 008C(248):      DRD2A: EU0=0 EU1=0 EU2=0 EU3=0 EXT init=0 WS=0 RS=0 */
+.long   0x080cf04c     /* 0090(248):      DRD2B1: idx0 = EU3(); EU3(var1,var12)  */
+.long   0x000001f8     /* 0094(:0):    NOP */
+
+
+.globl scEthernetXmit_TDT
+scEthernetXmit_TDT:    /* Task 1 Descriptor Table */
+.long   0x80095b00     /* 0000(280):  LCDEXT: idx0 = 0xf0025b00; ; */
+.long   0x85c60004     /* 0004(280):  LCD: idx1 = var11 + var12 + 4; idx1 once var0; idx1 += inc0 */
+.long   0x10002308     /* 0008(283):    DRD1A: var8 = idx1; FN=0 MORE init=0 WS=0 RS=0 */
+.long   0x10000f88     /* 000C(284):    DRD1A: var3 = *idx1; FN=0 MORE init=0 WS=0 RS=0 */
+.long   0x00000380     /* 0010(285):    DRD1A: var0 = *idx0; FN=0 init=0 WS=0 RS=0 */
+.long   0x81980000     /* 0014(288):  LCD: idx0 = var3; idx0 once var0; idx0 += inc0 */
+.long   0x10000780     /* 0018(290):    DRD1A: var1 = *idx0; FN=0 MORE init=0 WS=0 RS=0 */
+.long   0x60000000     /* 001C(291):    DRD2A: EU0=0 EU1=0 EU2=0 EU3=0 EXT init=0 WS=0 RS=0 */
+.long   0x024cf04d     /* 0020(291):    DRD2B1: var9 = EU3(); EU3(var1,var13)  */
+.long   0x84980309     /* 0024(294):  LCD: idx0 = var9; idx0 != var12; idx0 += inc1 */
+.long   0xc0004003     /* 0028(297):    LCDEXT: idx1 = 0x00000003; ; */
+.long   0x81c60004     /* 002C(297):    LCD: idx2 = var3 + var12 + 4; idx2 once var0; idx2 += inc0 */
+.long   0x70000000     /* 0030(299):      DRD2A: EU0=0 EU1=0 EU2=0 EU3=0 EXT MORE init=0 WS=0 RS=0 */
+.long   0x010cf04e     /* 0034(299):      DRD2B1: var4 = EU3(); EU3(var1,var14)  */
+.long   0x70000000     /* 0038(300):      DRD2A: EU0=0 EU1=0 EU2=0 EU3=0 EXT MORE init=0 WS=0 RS=0 */
+.long   0x014cf04f     /* 003C(300):      DRD2B1: var5 = EU3(); EU3(var1,var15)  */
+.long   0x70000000     /* 0040(301):      DRD2A: EU0=0 EU1=0 EU2=0 EU3=0 EXT MORE init=0 WS=0 RS=0 */
+.long   0x028cf050     /* 0044(301):      DRD2B1: var10 = EU3(); EU3(var1,var16)  */
+.long   0x70000000     /* 0048(302):      DRD2A: EU0=0 EU1=0 EU2=0 EU3=0 EXT MORE init=0 WS=0 RS=0 */
+.long   0x018cf051     /* 004C(302):      DRD2B1: var6 = EU3(); EU3(var1,var17)  */
+.long   0x10000b90     /* 0050(303):      DRD1A: var2 = *idx2; FN=0 MORE init=0 WS=0 RS=0 */
+.long   0x60000000     /* 0054(304):      DRD2A: EU0=0 EU1=0 EU2=0 EU3=0 EXT init=0 WS=0 RS=0 */
+.long   0x01ccf0a1     /* 0058(304):      DRD2B1: var7 = EU3(); EU3(var2,idx1)  */
+.long   0xc2988312     /* 005C(308):    LCDEXT: idx1 = var5; idx1 > var12; idx1 += inc2 */
+.long   0x83490000     /* 0060(308):    LCD: idx2 = var6 + var18; idx2 once var0; idx2 += inc0 */
+.long   0x00001b10     /* 0064(310):      DRD1A: var6 = idx2; FN=0 init=0 WS=0 RS=0 */
+.long   0x800251a4     /* 0068(315):    LCDEXT: idx1 = 0xf00091a4; ; */
+.long   0xc30104dc     /* 006C(315):    LCDEXT: idx2 = var6, idx3 = var2; idx2 >= var19; idx2 += inc3, idx3 += inc4 */
+.long   0x839a032d     /* 0070(316):    LCD: idx4 = var7; idx4 == var12; idx4 += inc5 */
+.long   0x0220c798     /* 0074(321):      DRD1A: *idx1 = *idx3; FN=0 init=17 WS=0 RS=0 */
+.long   0x800251a4     /* 0078(329):    LCDEXT: idx1 = 0xf00091a4; ; */
+.long   0x99198337     /* 007C(329):    LCD: idx2 = idx2, idx3 = idx3; idx2 > var12; idx2 += inc6, idx3 += inc7 */
+.long   0x022ac798     /* 0080(333):      DRD1A: *idx1 = *idx3; FN=0 init=17 WS=1 RS=1 */
+.long   0x800251a4     /* 0084(350):    LCDEXT: idx1 = 0xf00091a4; ; */
+.long   0xc1430000     /* 0088(350):    LCDEXT: idx2 = var2 + var6; idx2 once var0; idx2 += inc0 */
+.long   0x82998312     /* 008C(351):    LCD: idx3 = var5; idx3 > var12; idx3 += inc2 */
+.long   0x0a2ac790     /* 0090(354):      DRD1A: *idx1 = *idx2; FN=0 TFD init=17 WS=1 RS=1 */
+.long   0x81988000     /* 0094(359):    LCD: idx1 = var3; idx1 once var0; idx1 += inc0 */
+.long   0x60000002     /* 0098(361):      DRD2A: EU0=0 EU1=0 EU2=0 EU3=2 EXT init=0 WS=0 RS=0 */
+.long   0x0c4cfc4d     /* 009C(361):      DRD2B1: *idx1 = EU3(); EU3(*idx1,var13)  */
+.long   0xc21883ad     /* 00A0(365):    LCDEXT: idx1 = var4; idx1 == var14; idx1 += inc5 */
+.long   0x80190000     /* 00A4(365):    LCD: idx2 = var0; idx2 once var0; idx2 += inc0 */
+.long   0x04008460     /* 00A8(367):      DRD1A: idx1 = var12; FN=0 INT init=0 WS=0 RS=0 */
+.long   0xc4052305     /* 00AC(371):    LCDEXT: idx1 = var8, idx2 = var10; idx2 == var12; idx1 += inc0, idx2 += inc5 */
+.long   0x81ca0000     /* 00B0(372):    LCD: idx3 = var3 + var20; idx3 once var0; idx3 += inc0 */
+.long   0x1000c718     /* 00B4(374):      DRD1A: *idx1 = idx3; FN=0 MORE init=0 WS=0 RS=0 */
+.long   0x00000f18     /* 00B8(375):      DRD1A: var3 = idx3; FN=0 init=0 WS=0 RS=0 */
+.long   0xc4188000     /* 00BC(378):    LCDEXT: idx1 = var8; idx1 once var0; idx1 += inc0 */
+.long   0x85190312     /* 00C0(378):    LCD: idx2 = var10; idx2 > var12; idx2 += inc2 */
+.long   0x10000c00     /* 00C4(380):      DRD1A: var3 = var0; FN=0 MORE init=0 WS=0 RS=0 */
+.long   0x1000c400     /* 00C8(381):      DRD1A: *idx1 = var0; FN=0 MORE init=0 WS=0 RS=0 */
+.long   0x00008860     /* 00CC(382):      DRD1A: idx2 = var12; FN=0 init=0 WS=0 RS=0 */
+.long   0x81988000     /* 00D0(386):    LCD: idx1 = var3; idx1 once var0; idx1 += inc0 */
+.long   0x10000788     /* 00D4(388):      DRD1A: var1 = *idx1; FN=0 MORE init=0 WS=0 RS=0 */
+.long   0x60000000     /* 00D8(389):      DRD2A: EU0=0 EU1=0 EU2=0 EU3=0 EXT init=0 WS=0 RS=0 */
+.long   0x080cf04d     /* 00DC(389):      DRD2B1: idx0 = EU3(); EU3(var1,var13)  */
+.long   0x000001f8     /* 00E0(:0):    NOP */
+
+.align 8
+
+.globl scEthernetRecv_VarTab
+scEthernetRecv_VarTab: /* Task 0 Variable Table */
+.long   0x00000000     /* var[0] */
+.long   0x00000000     /* var[1] */
+.long   0x00000000     /* var[2] */
+.long   0x00000000     /* var[3] */
+.long   0x00000000     /* var[4] */
+.long   0x00000000     /* var[5] */
+.long   0x00000000     /* var[6] */
+.long   0x00000000     /* var[7] */
+.long   0x00000000     /* var[8] */
+.long   0xf0025b00     /* var[9] */
+.long   0x00000008     /* var[10] */
+.long   0x0000000c     /* var[11] */
+.long   0x80000000     /* var[12] */
+.long   0x00000000     /* var[13] */
+.long   0x10000000     /* var[14] */
+.long   0x20000000     /* var[15] */
+.long   0x00000800     /* var[16] */
+.long   0x00000001     /* var[17] */
+.long   0x00000000     /* var[18] */
+.long   0x00000000     /* var[19] */
+.long   0x00000000     /* var[20] */
+.long   0x00000000     /* var[21] */
+.long   0x00000000     /* var[22] */
+.long   0x00000000     /* var[23] */
+.long   0x00000000     /* inc[0] */
+.long   0x60000000     /* inc[1] */
+.long   0x20000004     /* inc[2] */
+.long   0x20000001     /* inc[3] */
+.long   0x80000000     /* inc[4] */
+.long   0x40000000     /* inc[5] */
+.long   0x00000000     /* inc[6] */
+.long   0x00000000     /* inc[7] */
+
+.align  8
+
+.globl scEthernetXmit_VarTab
+scEthernetXmit_VarTab: /* Task 1 Variable Table */
+.long   0x00000000     /* var[0] */
+.long   0x00000000     /* var[1] */
+.long   0x00000000     /* var[2] */
+.long   0x00000000     /* var[3] */
+.long   0x00000000     /* var[4] */
+.long   0x00000000     /* var[5] */
+.long   0x00000000     /* var[6] */
+.long   0x00000000     /* var[7] */
+.long   0x00000000     /* var[8] */
+.long   0x00000000     /* var[9] */
+.long   0x00000000     /* var[10] */
+.long   0xf0025b00     /* var[11] */
+.long   0x00000000     /* var[12] */
+.long   0x80000000     /* var[13] */
+.long   0x10000000     /* var[14] */
+.long   0x08000000     /* var[15] */
+.long   0x20000000     /* var[16] */
+.long   0x0000ffff     /* var[17] */
+.long   0xffffffff     /* var[18] */
+.long   0x00000004     /* var[19] */
+.long   0x00000008     /* var[20] */
+.long   0x00000000     /* var[21] */
+.long   0x00000000     /* var[22] */
+.long   0x00000000     /* var[23] */
+.long   0x00000000     /* inc[0] */
+.long   0x60000000     /* inc[1] */
+.long   0x40000000     /* inc[2] */
+.long   0xc000fffc     /* inc[3] */
+.long   0xe0000004     /* inc[4] */
+.long   0x80000000     /* inc[5] */
+.long   0x4000ffff     /* inc[6] */
+.long   0xe0000001     /* inc[7] */
+
+.align 8
+
+.globl scEthernetRecv_FDT
+scEthernetRecv_FDT:    /* Task 0 Function Descriptor Table */
+.long   0x00000000
+.long   0x00000000
+.long   0x00000000
+.long   0x00000000
+.long   0x00000000
+.long   0x00000000
+.long   0x00000000
+.long   0x00000000
+.long   0x00000000
+.long   0x00000000
+.long   0x00000000
+.long   0x00000000
+.long   0x00000000
+.long   0x00000000
+.long   0x00000000
+.long   0x00000000
+.long   0x00000000
+.long   0x00000000
+.long   0x00000000
+.long   0x00000000
+.long   0x00000000
+.long   0x00000000
+.long   0x00000000
+.long   0x00000000
+.long   0x00000000
+.long   0x00000000
+.long   0x00000000
+.long   0x00000000
+.long   0x00000000
+.long   0x00000000
+.long   0x00000000
+.long   0x00000000
+.long   0x00000000
+.long   0x00000000
+.long   0x00000000
+.long   0x00000000
+.long   0x00000000
+.long   0x00000000
+.long   0x00000000
+.long   0x00000000
+.long   0x00000000
+.long   0x00000000
+.long   0x00000000
+.long   0x00000000
+.long   0x00000000
+.long   0x00000000
+.long   0x00000000
+.long   0x00000000
+.long   0x21800000     /* and(), EU# 3 */
+.long   0x21e00000     /* or(), EU# 3 */
+.long   0x21400000     /* andn(), EU# 3 */
+.long   0x00000000
+.long   0x00000000
+.long   0x00000000
+.long   0x00000000
+.long   0x00000000
+.long   0x00000000
+.long   0x00000000
+.long   0x00000000
+.long   0x00000000
+.long   0x00000000
+.long   0x00000000
+.long   0x00000000
+.long   0x00000000
+
+.align 8
+
+.globl scEthernetXmit_FDT
+scEthernetXmit_FDT:    /* Task 1 Function Descriptor Table */
+.long   0x00000000
+.long   0x00000000
+.long   0x00000000
+.long   0x00000000
+.long   0x00000000
+.long   0x00000000
+.long   0x00000000
+.long   0x00000000
+.long   0x00000000
+.long   0x00000000
+.long   0x00000000
+.long   0x00000000
+.long   0x00000000
+.long   0x00000000
+.long   0x00000000
+.long   0x00000000
+.long   0x00000000
+.long   0x00000000
+.long   0x00000000
+.long   0x00000000
+.long   0x00000000
+.long   0x00000000
+.long   0x00000000
+.long   0x00000000
+.long   0x00000000
+.long   0x00000000
+.long   0x00000000
+.long   0x00000000
+.long   0x00000000
+.long   0x00000000
+.long   0x00000000
+.long   0x00000000
+.long   0x00000000
+.long   0x00000000
+.long   0x00000000
+.long   0x00000000
+.long   0x00000000
+.long   0x00000000
+.long   0x00000000
+.long   0x00000000
+.long   0x00000000
+.long   0x00000000
+.long   0x00000000
+.long   0x00000000
+.long   0x00000000
+.long   0x00000000
+.long   0x00000000
+.long   0x00000000
+.long   0x21800000     /* and(), EU# 3 */
+.long   0x21e00000     /* or(), EU# 3 */
+.long   0x21400000     /* andn(), EU# 3 */
+.long   0x00000000
+.long   0x00000000
+.long   0x00000000
+.long   0x00000000
+.long   0x00000000
+.long   0x00000000
+.long   0x00000000
+.long   0x00000000
+.long   0x00000000
+.long   0x00000000
+.long   0x00000000
+.long   0x00000000
+.long   0x00000000
+
+
+.globl scEthernetRecv_CSave
+scEthernetRecv_CSave:  /* Task 0 context save space */
+.space  128, 0x0
+
+
+.globl scEthernetXmit_CSave
+scEthernetXmit_CSave:  /* Task 1 context save space */
+.space  128, 0x0
+
+#endif
diff --git a/cpu/mpc8220/i2c.c b/cpu/mpc8220/i2c.c
new file mode 100644 (file)
index 0000000..e9d0771
--- /dev/null
@@ -0,0 +1,403 @@
+/*
+ * (C) Copyright 2004, Freescale, Inc
+ * TsiChung Liew, Tsi-Chung.Liew@freescale.com.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+
+#ifdef CONFIG_HARD_I2C
+
+#include <mpc8220.h>
+#include <i2c.h>
+
+typedef struct mpc8220_i2c {
+       volatile u32 adr;       /* I2Cn + 0x00 */
+       volatile u32 fdr;       /* I2Cn + 0x04 */
+       volatile u32 cr;        /* I2Cn + 0x08 */
+       volatile u32 sr;        /* I2Cn + 0x0C */
+       volatile u32 dr;        /* I2Cn + 0x10 */
+} i2c_t;
+
+/* I2Cn control register bits */
+#define I2C_EN      0x80
+#define I2C_IEN     0x40
+#define I2C_STA     0x20
+#define I2C_TX      0x10
+#define I2C_TXAK    0x08
+#define I2C_RSTA    0x04
+#define I2C_INIT_MASK   (I2C_EN | I2C_STA | I2C_TX | I2C_RSTA)
+
+/* I2Cn status register bits */
+#define I2C_CF      0x80
+#define I2C_AAS     0x40
+#define I2C_BB      0x20
+#define I2C_AL      0x10
+#define I2C_SRW     0x04
+#define I2C_IF      0x02
+#define I2C_RXAK    0x01
+
+#define I2C_TIMEOUT 100
+#define I2C_RETRIES 1
+
+struct mpc8220_i2c_tap {
+       int scl2tap;
+       int tap2tap;
+};
+
+static int mpc_reg_in (volatile u32 * reg);
+static void mpc_reg_out (volatile u32 * reg, int val, int mask);
+static int wait_for_bb (void);
+static int wait_for_pin (int *status);
+static int do_address (uchar chip, char rdwr_flag);
+static int send_bytes (uchar chip, char *buf, int len);
+static int receive_bytes (uchar chip, char *buf, int len);
+static int mpc_get_fdr (int);
+
+static int mpc_reg_in (volatile u32 * reg)
+{
+       return *reg >> 24;
+       __asm__ __volatile__ ("eieio");
+}
+
+static void mpc_reg_out (volatile u32 * reg, int val, int mask)
+{
+       int tmp;
+
+       if (!mask) {
+               *reg = val << 24;
+       } else {
+               tmp = mpc_reg_in (reg);
+               *reg = ((tmp & ~mask) | (val & mask)) << 24;
+       }
+       __asm__ __volatile__ ("eieio");
+
+       return;
+}
+
+static int wait_for_bb (void)
+{
+       i2c_t *regs = (i2c_t *) MMAP_I2C;
+       int timeout = I2C_TIMEOUT;
+       int status;
+
+       status = mpc_reg_in (&regs->sr);
+
+       while (timeout-- && (status & I2C_BB)) {
+#if 1
+               volatile int temp;
+
+               mpc_reg_out (&regs->cr, I2C_STA, I2C_STA);
+               temp = mpc_reg_in (&regs->dr);
+               mpc_reg_out (&regs->cr, 0, I2C_STA);
+               mpc_reg_out (&regs->cr, 0, 0);
+               mpc_reg_out (&regs->cr, I2C_EN, 0);
+#endif
+               udelay (1000);
+               status = mpc_reg_in (&regs->sr);
+       }
+
+       return (status & I2C_BB);
+}
+
+static int wait_for_pin (int *status)
+{
+       i2c_t *regs = (i2c_t *) MMAP_I2C;
+       int timeout = I2C_TIMEOUT;
+
+       *status = mpc_reg_in (&regs->sr);
+
+       while (timeout-- && !(*status & I2C_IF)) {
+               udelay (1000);
+               *status = mpc_reg_in (&regs->sr);
+       }
+
+       if (!(*status & I2C_IF)) {
+               return -1;
+       }
+
+       mpc_reg_out (&regs->sr, 0, I2C_IF);
+       return 0;
+}
+
+static int do_address (uchar chip, char rdwr_flag)
+{
+       i2c_t *regs = (i2c_t *) MMAP_I2C;
+       int status;
+
+       chip <<= 1;
+
+       if (rdwr_flag)
+               chip |= 1;
+
+       mpc_reg_out (&regs->cr, I2C_TX, I2C_TX);
+       mpc_reg_out (&regs->dr, chip, 0);
+
+       if (wait_for_pin (&status))
+               return -2;
+       if (status & I2C_RXAK)
+               return -3;
+       return 0;
+}
+
+static int send_bytes (uchar chip, char *buf, int len)
+{
+       i2c_t *regs = (i2c_t *) MMAP_I2C;
+       int wrcount;
+       int status;
+
+       for (wrcount = 0; wrcount < len; ++wrcount) {
+
+               mpc_reg_out (&regs->dr, buf[wrcount], 0);
+
+               if (wait_for_pin (&status))
+                       break;
+
+               if (status & I2C_RXAK)
+                       break;
+
+       }
+
+       return !(wrcount == len);
+       return 0;
+}
+
+static int receive_bytes (uchar chip, char *buf, int len)
+{
+       i2c_t *regs = (i2c_t *) MMAP_I2C;
+       int dummy = 1;
+       int rdcount = 0;
+       int status;
+       int i;
+
+       mpc_reg_out (&regs->cr, 0, I2C_TX);
+
+       for (i = 0; i < len; ++i) {
+               buf[rdcount] = mpc_reg_in (&regs->dr);
+
+               if (dummy)
+                       dummy = 0;
+               else
+                       rdcount++;
+
+               if (wait_for_pin (&status))
+                       return -4;
+       }
+
+       mpc_reg_out (&regs->cr, I2C_TXAK, I2C_TXAK);
+       buf[rdcount++] = mpc_reg_in (&regs->dr);
+
+       if (wait_for_pin (&status))
+               return -5;
+
+       mpc_reg_out (&regs->cr, 0, I2C_TXAK);
+       return 0;
+}
+
+/**************** I2C API ****************/
+
+void i2c_init (int speed, int saddr)
+{
+       i2c_t *regs = (i2c_t *) MMAP_I2C;
+
+       mpc_reg_out (&regs->cr, 0, 0);
+       mpc_reg_out (&regs->adr, saddr << 1, 0);
+
+       /* Set clock
+        */
+       mpc_reg_out (&regs->fdr, mpc_get_fdr (speed), 0);
+
+       /* Enable module
+        */
+       mpc_reg_out (&regs->cr, I2C_EN, I2C_INIT_MASK);
+       mpc_reg_out (&regs->sr, 0, I2C_IF);
+       return;
+}
+
+static int mpc_get_fdr (int speed)
+{
+       DECLARE_GLOBAL_DATA_PTR;
+       static int fdr = -1;
+
+       if (fdr == -1) {
+               ulong best_speed = 0;
+               ulong divider;
+               ulong ipb, scl;
+               ulong bestmatch = 0xffffffffUL;
+               int best_i = 0, best_j = 0, i, j;
+               int SCL_Tap[] = { 9, 10, 12, 15, 5, 6, 7, 8 };
+               struct mpc8220_i2c_tap scltap[] = {
+                       {4, 1},
+                       {4, 2},
+                       {6, 4},
+                       {6, 8},
+                       {14, 16},
+                       {30, 32},
+                       {62, 64},
+                       {126, 128}
+               };
+
+               ipb = gd->bus_clk;
+               for (i = 7; i >= 0; i--) {
+                       for (j = 7; j >= 0; j--) {
+                               scl = 2 * (scltap[j].scl2tap +
+                                          (SCL_Tap[i] -
+                                           1) * scltap[j].tap2tap + 2);
+                               if (ipb <= speed * scl) {
+                                       if ((speed * scl - ipb) < bestmatch) {
+                                               bestmatch = speed * scl - ipb;
+                                               best_i = i;
+                                               best_j = j;
+                                               best_speed = ipb / scl;
+                                       }
+                               }
+                       }
+               }
+               divider = (best_i & 3) | ((best_i & 4) << 3) | (best_j << 2);
+               if (gd->flags & GD_FLG_RELOC) {
+                       fdr = divider;
+               } else {
+                       printf ("%ld kHz, ", best_speed / 1000);
+                       return divider;
+               }
+       }
+
+       return fdr;
+}
+
+int i2c_probe (uchar chip)
+{
+       i2c_t *regs = (i2c_t *) MMAP_I2C;
+       int i;
+
+       for (i = 0; i < I2C_RETRIES; i++) {
+               mpc_reg_out (&regs->cr, I2C_STA, I2C_STA);
+
+               if (!do_address (chip, 0)) {
+                       mpc_reg_out (&regs->cr, 0, I2C_STA);
+                       break;
+               }
+
+               mpc_reg_out (&regs->cr, 0, I2C_STA);
+               udelay (50);
+       }
+
+       return (i == I2C_RETRIES);
+}
+
+int i2c_read (uchar chip, uint addr, int alen, uchar * buf, int len)
+{
+       uchar xaddr[4];
+       i2c_t *regs = (i2c_t *) MMAP_I2C;
+       int ret = -1;
+
+       xaddr[0] = (addr >> 24) & 0xFF;
+       xaddr[1] = (addr >> 16) & 0xFF;
+       xaddr[2] = (addr >> 8) & 0xFF;
+       xaddr[3] = addr & 0xFF;
+
+       if (wait_for_bb ()) {
+               printf ("i2c_read: bus is busy\n");
+               goto Done;
+       }
+
+       mpc_reg_out (&regs->cr, I2C_STA, I2C_STA);
+       if (do_address (chip, 0)) {
+               printf ("i2c_read: failed to address chip\n");
+               goto Done;
+       }
+
+       if (send_bytes (chip, &xaddr[4 - alen], alen)) {
+               printf ("i2c_read: send_bytes failed\n");
+               goto Done;
+       }
+
+       mpc_reg_out (&regs->cr, I2C_RSTA, I2C_RSTA);
+       if (do_address (chip, 1)) {
+               printf ("i2c_read: failed to address chip\n");
+               goto Done;
+       }
+
+       if (receive_bytes (chip, buf, len)) {
+               printf ("i2c_read: receive_bytes failed\n");
+               goto Done;
+       }
+
+       ret = 0;
+      Done:
+       mpc_reg_out (&regs->cr, 0, I2C_STA);
+       return ret;
+}
+
+int i2c_write (uchar chip, uint addr, int alen, uchar * buf, int len)
+{
+       uchar xaddr[4];
+       i2c_t *regs = (i2c_t *) MMAP_I2C;
+       int ret = -1;
+
+       xaddr[0] = (addr >> 24) & 0xFF;
+       xaddr[1] = (addr >> 16) & 0xFF;
+       xaddr[2] = (addr >> 8) & 0xFF;
+       xaddr[3] = addr & 0xFF;
+
+       if (wait_for_bb ()) {
+               printf ("i2c_write: bus is busy\n");
+               goto Done;
+       }
+
+       mpc_reg_out (&regs->cr, I2C_STA, I2C_STA);
+       if (do_address (chip, 0)) {
+               printf ("i2c_write: failed to address chip\n");
+               goto Done;
+       }
+
+       if (send_bytes (chip, &xaddr[4 - alen], alen)) {
+               printf ("i2c_write: send_bytes failed\n");
+               goto Done;
+       }
+
+       if (send_bytes (chip, buf, len)) {
+               printf ("i2c_write: send_bytes failed\n");
+               goto Done;
+       }
+
+       ret = 0;
+      Done:
+       mpc_reg_out (&regs->cr, 0, I2C_STA);
+       return ret;
+}
+
+uchar i2c_reg_read (uchar chip, uchar reg)
+{
+       char buf;
+
+       i2c_read (chip, reg, 1, &buf, 1);
+
+       return buf;
+}
+
+void i2c_reg_write (uchar chip, uchar reg, uchar val)
+{
+       i2c_write (chip, reg, 1, &val, 1);
+
+       return;
+}
+
+#endif /* CONFIG_HARD_I2C */
diff --git a/cpu/mpc8220/i2cCore.c b/cpu/mpc8220/i2cCore.c
new file mode 100644 (file)
index 0000000..accf43c
--- /dev/null
@@ -0,0 +1,627 @@
+/* I2cCore.c - MPC8220 PPC I2C Library */
+
+/* Copyright 2004      Freescale Semiconductor, Inc. */
+
+/*
+modification history
+--------------------
+01c,29jun04,tcl         1.3    removed CR. Added two bytes offset support.
+01b,19jan04,tcl         1.2    removed i2cMsDelay and sysDecGet. renamed i2cMsDelay
+                       back to sysMsDelay
+01a,19jan04,tcl         1.1    created and seperated from i2c.c
+*/
+
+/*
+DESCRIPTION
+This file contain I2C low level handling library functions
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <vxWorks.h>
+#include <sysLib.h>
+#include <iosLib.h>
+#include <logLib.h>
+#include <tickLib.h>
+
+/* BSP Includes */
+#include "config.h"
+#include "mpc8220.h"
+#include "i2cCore.h"
+
+#ifdef DEBUG_I2CCORE
+int I2CCDbg = 0;
+#endif
+
+#define ABS(x) ((x < 0)? -x : x)
+
+char *I2CERR[16] = {
+       "Transfer in Progress\n",       /* 0 */
+       "Transfer complete\n",
+       "Not Addressed\n",              /* 2 */
+       "Addressed as a slave\n",
+       "Bus is Idle\n",                /* 4 */
+       "Bus is busy\n",
+       "Arbitration Lost\n",           /* 6 */
+       "Arbitration on Track\n",
+       "Slave receive, master writing to slave\n",     /* 8 */
+       "Slave transmit, master reading from slave\n",
+       "Interrupt is pending\n",       /* 10 */
+       "Interrupt complete\n",
+       "Acknowledge received\n",       /* 12 */
+       "No acknowledge received\n",
+       "Unknown status\n",             /* 14 */
+       "\n"
+};
+
+/******************************************************************************
+ *
+ * chk_status - Check I2C status bit
+ *
+ * RETURNS: OK, or ERROR if the bit encounter
+ *
+ */
+
+STATUS chk_status (PSI2C pi2c, UINT8 sta_bit, UINT8 truefalse)
+{
+       int i, status = 0;
+
+       for (i = 0; i < I2C_POLL_COUNT; i++) {
+               if ((pi2c->sr & sta_bit) == (truefalse ? sta_bit : 0))
+                       return (OK);
+       }
+
+       I2CCDBG (L2, ("--- sr %x stabit %x truefalse %d\n",
+                     pi2c->sr, sta_bit, truefalse, 0, 0, 0));
+
+       if (i == I2C_POLL_COUNT) {
+               switch (sta_bit) {
+               case I2C_STA_CF:
+                       status = 0;
+                       break;
+               case I2C_STA_AAS:
+                       status = 2;
+                       break;
+               case I2C_STA_BB:
+                       status = 4;
+                       break;
+               case I2C_STA_AL:
+                       status = 6;
+                       break;
+               case I2C_STA_SRW:
+                       status = 8;
+                       break;
+               case I2C_STA_IF:
+                       status = 10;
+                       break;
+               case I2C_STA_RXAK:
+                       status = 12;
+                       break;
+               default:
+                       status = 14;
+                       break;
+               }
+
+               if (!truefalse)
+                       status++;
+
+               I2CCDBG (NO, ("--- status %d\n", status, 0, 0, 0, 0, 0));
+               I2CCDBG (NO, (I2CERR[status], 0, 0, 0, 0, 0, 0));
+       }
+
+       return (ERROR);
+}
+
+/******************************************************************************
+ *
+ * I2C Enable - Enable the I2C Controller
+ *
+ */
+STATUS i2c_enable (SI2C * pi2c, PI2CSET pi2cSet)
+{
+       int fdr = pi2cSet->bit_rate;
+       UINT8 adr = pi2cSet->i2c_adr;
+
+       I2CCDBG (L2, ("i2c_enable fdr %d adr %x\n", fdr, adr, 0, 0, 0, 0));
+
+       i2c_clear (pi2c);       /* Clear FDR, ADR, SR and CR reg */
+
+       SetI2cFDR (pi2c, fdr);  /* Frequency                    */
+       pi2c->adr = adr;
+
+       pi2c->cr = I2C_CTL_EN;  /* Set Enable                   */
+
+       /*
+          The I2C bus should be in Idle state. If the bus is busy,
+          clear the STA bit in control register
+        */
+       if (chk_status (pi2c, I2C_STA_BB, 0) != OK) {
+               if ((pi2c->cr & I2C_CTL_STA) == I2C_CTL_STA)
+                       pi2c->cr &= ~I2C_CTL_STA;
+
+               /* Check again if it is still busy, return error if found */
+               if (chk_status (pi2c, I2C_STA_BB, 1) == OK)
+                       return ERROR;
+       }
+
+       return (OK);
+}
+
+/******************************************************************************
+ *
+ * I2C Disable - Disable the I2C Controller
+ *
+ */
+STATUS i2c_disable (PSI2C pi2c)
+{
+       i2c_clear (pi2c);
+
+       pi2c->cr &= I2C_CTL_EN; /* Disable I2c                  */
+
+       if ((pi2c->cr & I2C_CTL_STA) == I2C_CTL_STA)
+               pi2c->cr &= ~I2C_CTL_STA;
+
+       if (chk_status (pi2c, I2C_STA_BB, 0) != OK)
+               return ERROR;
+
+       return (OK);
+}
+
+/******************************************************************************
+ *
+ * I2C Clear - Clear the I2C Controller
+ *
+ */
+STATUS i2c_clear (PSI2C pi2c)
+{
+       pi2c->adr = 0;
+       pi2c->fdr = 0;
+       pi2c->cr = 0;
+       pi2c->sr = 0;
+
+       return (OK);
+}
+
+
+STATUS i2c_start (PSI2C pi2c, PI2CSET pi2cSet)
+{
+#ifdef TWOBYTES
+       UINT16 ByteOffset = pi2cSet->str_adr;
+#else
+       UINT8 ByteOffset = pi2cSet->str_adr;
+#endif
+#if 1
+       UINT8 tmp = 0;
+#endif
+       UINT8 Addr = pi2cSet->slv_adr;
+
+       pi2c->cr |= I2C_CTL_STA;        /* Generate start signal        */
+
+       if (chk_status (pi2c, I2C_STA_BB, 1) != OK)
+               return ERROR;
+
+       /* Write slave address */
+       if (i2c_writebyte (pi2c, &Addr) != OK) {
+               i2c_stop (pi2c);        /* Disable I2c                  */
+               return ERROR;
+       }
+#ifdef TWOBYTES
+#   if 0
+       /* Issue the offset to start */
+       if (i2c_write2byte (pi2c, &ByteOffset) != OK) {
+               i2c_stop (pi2c);        /* Disable I2c                  */
+               return ERROR;
+       }
+#endif
+       tmp = (ByteOffset >> 8) & 0xff;
+       if (i2c_writebyte (pi2c, &tmp) != OK) {
+               i2c_stop (pi2c);        /* Disable I2c                  */
+               return ERROR;
+       }
+       tmp = ByteOffset & 0xff;
+       if (i2c_writebyte (pi2c, &tmp) != OK) {
+               i2c_stop (pi2c);        /* Disable I2c                  */
+               return ERROR;
+       }
+#else
+       if (i2c_writebyte (pi2c, &ByteOffset) != OK) {
+               i2c_stop (pi2c);        /* Disable I2c                  */
+               return ERROR;
+       }
+#endif
+
+       return (OK);
+}
+
+STATUS i2c_stop (PSI2C pi2c)
+{
+       pi2c->cr &= ~I2C_CTL_STA;       /* Generate stop signal         */
+       if (chk_status (pi2c, I2C_STA_BB, 0) != OK)
+               return ERROR;
+
+       return (OK);
+}
+
+/******************************************************************************
+ *
+ * Read Len bytes to the location pointed to by *Data from the device
+ * with address Addr.
+ */
+int i2c_readblock (SI2C * pi2c, PI2CSET pi2cSet, UINT8 * Data)
+{
+       int i = 0;
+       UINT8 Tmp;
+
+/*    UINT8 ByteOffset = pi2cSet->str_adr; not used? */
+       UINT8 Addr = pi2cSet->slv_adr;
+       int Length = pi2cSet->xfer_size;
+
+       I2CCDBG (L1, ("i2c_readblock addr %x data 0x%08x len %d offset %d\n",
+                     Addr, (int) Data, Length, ByteOffset, 0, 0));
+
+       if (pi2c->sr & I2C_STA_AL) {    /* Check if Arbitration lost    */
+               I2CCDBG (FN, ("Arbitration lost\n", 0, 0, 0, 0, 0, 0));
+               pi2c->sr &= ~I2C_STA_AL;        /* Clear Arbitration status bit */
+               return ERROR;
+       }
+
+       pi2c->cr |= I2C_CTL_TX; /* Enable the I2c for TX, Ack   */
+
+       if (i2c_start (pi2c, pi2cSet) == ERROR)
+               return ERROR;
+
+       pi2c->cr |= I2C_CTL_RSTA;       /* Repeat Start */
+
+       Tmp = Addr | 1;
+
+       if (i2c_writebyte (pi2c, &Tmp) != OK) {
+               i2c_stop (pi2c);        /* Disable I2c  */
+               return ERROR;
+       }
+
+       if (((pi2c->sr & 0x07) == 0x07) || (pi2c->sr & 0x01))
+               return ERROR;
+
+       pi2c->cr &= ~I2C_CTL_TX;        /* Set receive mode     */
+
+       if (((pi2c->sr & 0x07) == 0x07) || (pi2c->sr & 0x01))
+               return ERROR;
+
+       /* Dummy Read */
+       if (i2c_readbyte (pi2c, &Tmp, &i) != OK) {
+               i2c_stop (pi2c);        /* Disable I2c  */
+               return ERROR;
+       }
+
+       i = 0;
+       while (Length) {
+               if (Length == 2)
+                       pi2c->cr |= I2C_CTL_TXAK;
+
+               if (Length == 1)
+                       pi2c->cr &= ~I2C_CTL_STA;
+
+               if (i2c_readbyte (pi2c, Data, &Length) != OK) {
+                       return i2c_stop (pi2c);
+               }
+               i++;
+               Length--;
+               Data++;
+       }
+
+       if (i2c_stop (pi2c) == ERROR)
+               return ERROR;
+
+       return i;
+}
+
+STATUS i2c_writeblock (SI2C * pi2c, PI2CSET pi2cSet, UINT8 * Data)
+{
+       int Length = pi2cSet->xfer_size;
+
+#ifdef TWOBYTES
+       UINT16 ByteOffset = pi2cSet->str_adr;
+#else
+       UINT8 ByteOffset = pi2cSet->str_adr;
+#endif
+       int j, k;
+
+       I2CCDBG (L2, ("i2c_writeblock\n", 0, 0, 0, 0, 0, 0));
+
+       if (pi2c->sr & I2C_STA_AL) {
+               /* Check if arbitration lost */
+               I2CCDBG (L2, ("Arbitration lost\n", 0, 0, 0, 0, 0, 0));
+               pi2c->sr &= ~I2C_STA_AL;        /* Clear the condition  */
+               return ERROR;
+       }
+
+       pi2c->cr |= I2C_CTL_TX; /* Enable the I2c for TX, Ack   */
+
+       /* Do the not even offset first */
+       if ((ByteOffset % 8) != 0) {
+               int remain;
+
+               if (Length > 8) {
+                       remain = 8 - (ByteOffset % 8);
+                       Length -= remain;
+
+                       pi2cSet->str_adr = ByteOffset;
+
+                       if (i2c_start (pi2c, pi2cSet) == ERROR)
+                               return ERROR;
+
+                       for (j = ByteOffset; j < remain; j++) {
+                               if (i2c_writebyte (pi2c, Data++) != OK)
+                                       return ERROR;
+                       }
+
+                       if (i2c_stop (pi2c) == ERROR)
+                               return ERROR;
+
+                       sysMsDelay (32);
+
+                       /* Update the new ByteOffset */
+                       ByteOffset += remain;
+               }
+       }
+
+       for (j = ByteOffset, k = 0; j < (Length + ByteOffset); j++) {
+               if ((j % 8) == 0) {
+                       pi2cSet->str_adr = j;
+                       if (i2c_start (pi2c, pi2cSet) == ERROR)
+                               return ERROR;
+               }
+
+               k++;
+
+               if (i2c_writebyte (pi2c, Data++) != OK)
+                       return ERROR;
+
+               if ((j == (Length - 1)) || ((k % 8) == 0)) {
+                       if (i2c_stop (pi2c) == ERROR)
+                               return ERROR;
+
+                       sysMsDelay (50);
+               }
+
+       }
+
+       return k;
+}
+
+STATUS i2c_readbyte (SI2C * pi2c, UINT8 * readb, int *index)
+{
+       pi2c->sr &= ~I2C_STA_IF;        /* Clear Interrupt Bit  */
+       *readb = pi2c->dr;              /* Read a byte          */
+
+       /*
+          Set I2C_CTRL_TXAK will cause Transfer pending and
+          set I2C_CTRL_STA will cause Interrupt pending
+        */
+       if (*index != 2) {
+               if (chk_status (pi2c, I2C_STA_CF, 1) != OK)     /* Transfer not complete?       */
+                       return ERROR;
+       }
+
+       if (*index != 1) {
+               if (chk_status (pi2c, I2C_STA_IF, 1) != OK)
+                       return ERROR;
+       }
+
+       return (OK);
+}
+
+
+STATUS i2c_writebyte (SI2C * pi2c, UINT8 * writeb)
+{
+       pi2c->sr &= ~I2C_STA_IF;        /* Clear Interrupt      */
+       pi2c->dr = *writeb;             /* Write a byte         */
+
+       if (chk_status (pi2c, I2C_STA_CF, 1) != OK)     /* Transfer not complete?       */
+               return ERROR;
+
+       if (chk_status (pi2c, I2C_STA_IF, 1) != OK)
+               return ERROR;
+
+       return OK;
+}
+
+STATUS i2c_write2byte (SI2C * pi2c, UINT16 * writeb)
+{
+       UINT8 data;
+
+       data = (UINT8) ((*writeb >> 8) & 0xff);
+       if (i2c_writebyte (pi2c, &data) != OK)
+               return ERROR;
+       data = (UINT8) (*writeb & 0xff);
+       if (i2c_writebyte (pi2c, &data) != OK)
+               return ERROR;
+       return OK;
+}
+
+/* FDR table base on 33Mhz - more detail please refer to Odini2c_dividers.xls
+FDR FDR scl sda scl2tap2
+510 432 tap tap tap tap scl_per            sda_hold    I2C Freq    0   1   2   3   4   5
+000 000 9   3  4   1   28 Clocks   9 Clocks    1190 KHz    0   0   0   0   0   0
+000 001 9   3  4   2   44 Clocks   11 Clocks   758 KHz     0   0   1   0   0   0
+000 010 9   3  6   4   80 Clocks   17 Clocks   417 KHz     0   0   0   1   0   0
+000 011 9   3  6   8   144 Clocks  25 Clocks   231 KHz     0   0   1   1   0   0
+000 100 9   3  14  16  288 Clocks  49 Clocks   116 KHz     0   0   0   0   1   0
+000 101 9   3  30  32  576 Clocks  97 Clocks   58 KHz      0   0   1   0   1   0
+000 110 9   3  62  64  1152 Clocks 193 Clocks  29 KHz      0   0   0   1   1   0
+000 111 9   3  126 128 2304 Clocks 385 Clocks  14 KHz      0   0   1   1   1   0
+001 000 10  3  4   1   30 Clocks   9 Clocks    1111 KHz1   0   0   0   0   0
+001 001 10  3  4   2   48 Clocks   11 Clocks   694 KHz     1   0   1   0   0   0
+001 010 10  3  6   4   88 Clocks   17 Clocks   379 KHz     1   0   0   1   0   0
+001 011 10  3  6   8   160 Clocks  25 Clocks   208 KHz     1   0   1   1   0   0
+001 100 10  3  14  16  320 Clocks  49 Clocks   104 KHz     1   0   0   0   1   0
+001 101 10  3  30  32  640 Clocks  97 Clocks   52 KHz      1   0   1   0   1   0
+001 110 10  3  62  64  1280 Clocks 193 Clocks  26 KHz      1   0   0   1   1   0
+001 111 10  3  126 128 2560 Clocks 385 Clocks  13 KHz      1   0   1   1   1   0
+010 000 12  4  4   1   34 Clocks   10 Clocks   980 KHz     0   1   0   0   0   0
+010 001 12  4  4   2   56 Clocks   13 Clocks   595 KHz     0   1   1   0   0   0
+010 010 12  4  6   4   104 Clocks  21 Clocks   321 KHz     0   1   0   1   0   0
+010 011 12  4  6   8   192 Clocks  33 Clocks   174 KHz     0   1   1   1   0   0
+010 100 12  4  14  16  384 Clocks  65 Clocks   87 KHz      0   1   0   0   1   0
+010 101 12  4  30  32  768 Clocks  129 Clocks  43 KHz      0   1   1   0   1   0
+010 110 12  4  62  64  1536 Clocks 257 Clocks  22 KHz      0   1   0   1   1   0
+010 111 12  4  126 128 3072 Clocks 513 Clocks  11 KHz      0   1   1   1   1   0
+011 000 15  4  4   1   40 Clocks   10 Clocks   833 KHz     1   1   0   0   0   0
+011 001 15  4  4   2   68 Clocks   13 Clocks   490 KHz     1   1   1   0   0   0
+011 010 15  4  6   4   128 Clocks  21 Clocks   260 KHz     1   1   0   1   0   0
+011 011 15  4  6   8   240 Clocks  33 Clocks   139 KHz     1   1   1   1   0   0
+011 100 15  4  14  16  480 Clocks  65 Clocks   69 KHz      1   1   0   0   1   0
+011 101 15  4  30  32  960 Clocks  129 Clocks  35 KHz      1   1   1   0   1   0
+011 110 15  4  62  64  1920 Clocks 257 Clocks  17 KHz      1   1   0   1   1   0
+011 111 15  4  126 128 3840 Clocks 513 Clocks  9 KHz       1   1   1   1   1   0
+100 000 5   1  4   1   20 Clocks   7 Clocks    1667 KHz    0   0   0   0   0   1
+100 001 5   1  4   2   28 Clocks   7 Clocks    1190 KHz    0   0   1   0   0   1
+100 010 5   1  6   4   48 Clocks   9 Clocks    694 KHz     0   0   0   1   0   1
+100 011 5   1  6   8   80 Clocks   9 Clocks    417 KHz     0   0   1   1   0   1
+100 100 5   1  14  16  160 Clocks  17 Clocks   208 KHz     0   0   0   0   1   1
+100 101 5   1  30  32  320 Clocks  33 Clocks   104 KHz     0   0   1   0   1   1
+100 110 5   1  62  64  640 Clocks  65 Clocks   52 KHz      0   0   0   1   1   1
+100 111 5   1  126 128 1280 Clocks 129 Clocks  26 KHz      0   0   1   1   1   1
+101 000 6   1  4   1   22 Clocks   7 Clocks    1515 KHz    1   0   0   0   0   1
+101 001 6   1  4   2   32 Clocks   7 Clocks    1042 KHz    1   0   1   0   0   1
+101 010 6   1  6   4   56 Clocks   9 Clocks    595 KHz     1   0   0   1   0   1
+101 011 6   1  6   8   96 Clocks   9 Clocks    347 KHz     1   0   1   1   0   1
+101 100 6   1  14  16  192 Clocks  17 Clocks   174 KHz     1   0   0   0   1   1
+101 101 6   1  30  32  384 Clocks  33 Clocks   87 KHz      1   0   1   0   1   1
+101 110 6   1  62  64  768 Clocks  65 Clocks   43 KHz      1   0   0   1   1   1
+101 111 6   1  126 128 1536 Clocks 129 Clocks  22 KHz      1   0   1   1   1   1
+110 000 7   2  4   1   24 Clocks   8 Clocks    1389 KHz    0   1   0   0   0   1
+110 001 7   2  4   2   36 Clocks   9 Clocks    926 KHz     0   1   1   0   0   1
+110 010 7   2  6   4   64 Clocks   13 Clocks   521 KHz     0   1   0   1   0   1
+110 011 7   2  6   8   112 Clocks  17 Clocks   298 KHz     0   1   1   1   0   1
+110 100 7   2  14  16  224 Clocks  33 Clocks   149 KHz     0   1   0   0   1   1
+110 101 7   2  30  32  448 Clocks  65 Clocks   74 KHz      0   1   1   0   1   1
+110 110 7   2  62  64  896 Clocks  129 Clocks  37 KHz      0   1   0   1   1   1
+110 111 7   2  126 128 1792 Clocks 257 Clocks  19 KHz      0   1   1   1   1   1
+111 000 8   2  4   1   26 Clocks   8 Clocks    1282 KHz    1   1   0   0   0   1
+111 001 8   2  4   2   40 Clocks   9 Clocks    833 KHz     1   1   1   0   0   1
+111 010 8   2  6   4   72 Clocks   13 Clocks   463 KHz     1   1   0   1   0   1
+111 011 8   2  6   8   128 Clocks  17 Clocks   260 KHz     1   1   1   1   0   1
+111 100 8   2  14  16  256 Clocks  33 Clocks   130 KHz     1   1   0   0   1   1
+111 101 8   2  30  32  512 Clocks  65 Clocks   65 KHz      1   1   1   0   1   1
+111 110 8   2  62  64  1024 Clocks 129 Clocks  33 KHz      1   1   0   1   1   1
+111 111 8   2  126 128 2048 Clocks 257 Clocks  16 KHz      1   1   1   1   1   1
+*/
+STATUS SetI2cFDR (PSI2C pi2cRegs, int bitrate)
+{
+/* Constants */
+       const UINT8 div_hold[8][3] = { {9, 3}, {10, 3},
+       {12, 4}, {15, 4},
+       {5, 1}, {6, 1},
+       {7, 2}, {8, 2}
+       };
+
+       const UINT8 scl_tap[8][2] = { {4, 1}, {4, 2},
+       {6, 4}, {6, 8},
+       {14, 16}, {30, 32},
+       {62, 64}, {126, 128}
+       };
+
+       UINT8 mfdr_bits;
+
+       int i = 0;
+       int j = 0;
+
+       int Diff, min;
+       int WhichFreq, iRec, jRec;
+       int SCL_Period;
+       int SCL_Hold;
+       int I2C_Freq;
+
+       I2CCDBG (L2, ("Entering getBitRate: bitrate %d pi2cRegs 0x%08x\n",
+                     bitrate, (int) pi2cRegs, 0, 0, 0, 0));
+
+       if (bitrate < 0) {
+               I2CCDBG (NO, ("Invalid bitrate\n", 0, 0, 0, 0, 0, 0));
+               return ERROR;
+       }
+
+       /* Initialize */
+       mfdr_bits = 0;
+       min = 0x7fffffff;
+       WhichFreq = iRec = jRec = 0;
+
+       for (i = 0; i < 8; i++) {
+               for (j = 0; j < 8; j++) {
+                       /* SCL Period = 2 * (scl2tap + [(SCL_Tap - 1) * tap2tap] + 2)
+                        * SCL Hold   = scl2tap + ((SDA_Tap - 1) * tap2tap) + 3
+                        * Bit Rate (I2C Freq) = System Freq / SCL Period
+                        */
+                       SCL_Period =
+                               2 * (scl_tap[i][0] +
+                                    ((div_hold[j][0] - 1) * scl_tap[i][1]) +
+                                    2);
+
+                       /* Now get the I2C Freq */
+                       I2C_Freq = DEV_CLOCK_FREQ / SCL_Period;
+
+                       /* Take equal or slower */
+                       if (I2C_Freq > bitrate)
+                               continue;
+
+                       /* Take the differences */
+                       Diff = I2C_Freq - bitrate;
+
+                       Diff = ABS (Diff);
+
+                       /* Find the closer value */
+                       if (Diff < min) {
+                               min = Diff;
+                               WhichFreq = I2C_Freq;
+                               iRec = i;
+                               jRec = j;
+                       }
+
+                       I2CCDBG (L2,
+                                ("--- (%d,%d) I2C_Freq %d minDiff %d min %d\n",
+                                 i, j, I2C_Freq, Diff, min, 0));
+               }
+       }
+
+       SCL_Period =
+               2 * (scl_tap[iRec][0] +
+                    ((div_hold[jRec][0] - 1) * scl_tap[iRec][1]) + 2);
+
+       I2CCDBG (L2, ("\nmin %d WhichFreq %d iRec %d jRec %d\n",
+                     min, WhichFreq, iRec, jRec, 0, 0));
+       I2CCDBG (L2, ("--- scl2tap %d SCL_Tap %d tap2tap %d\n",
+                     scl_tap[iRec][0], div_hold[jRec][0], scl_tap[iRec][1],
+                     0, 0, 0));
+
+       /* This may no require */
+       SCL_Hold =
+               scl_tap[iRec][0] +
+               ((div_hold[jRec][1] - 1) * scl_tap[iRec][1]) + 3;
+       I2CCDBG (L2,
+                ("--- SCL_Period %d SCL_Hold %d\n", SCL_Period, SCL_Hold, 0,
+                 0, 0, 0));
+
+       I2CCDBG (L2, ("--- mfdr_bits %x\n", mfdr_bits, 0, 0, 0, 0, 0));
+
+       /* FDR 4,3,2 */
+       if ((iRec & 1) == 1)
+               mfdr_bits |= 0x04;      /* FDR 2 */
+       if ((iRec & 2) == 2)
+               mfdr_bits |= 0x08;      /* FDR 3 */
+       if ((iRec & 4) == 4)
+               mfdr_bits |= 0x10;      /* FDR 4 */
+       /* FDR 5,1,0 */
+       if ((jRec & 1) == 1)
+               mfdr_bits |= 0x01;      /* FDR 0 */
+       if ((jRec & 2) == 2)
+               mfdr_bits |= 0x02;      /* FDR 1 */
+       if ((jRec & 4) == 4)
+               mfdr_bits |= 0x20;      /* FDR 5 */
+
+       I2CCDBG (L2, ("--- mfdr_bits %x\n", mfdr_bits, 0, 0, 0, 0, 0));
+
+       pi2cRegs->fdr = mfdr_bits;
+
+       return OK;
+}
diff --git a/cpu/mpc8220/i2cCore.h b/cpu/mpc8220/i2cCore.h
new file mode 100644 (file)
index 0000000..72783fd
--- /dev/null
@@ -0,0 +1,103 @@
+/*
+ * i2cCore.h
+ *
+ * Prototypes, etc. for the Motorola MPC8220
+ * embedded cpu chips
+ *
+ * 2004 (c) Freescale, Inc.
+ * Author: TsiChung Liew <Tsi-Chung.Liew@freescale.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
+ */
+#ifndef __INCi2ccoreh
+#define __INCi2ccoreh
+#ifndef __ASSEMBLY__
+/* device types */
+#define I2C_DEVICE_TYPE_EEPROM 0
+#define I2C_EEPROM_ADRS 0xa0
+#define I2C_CTRL_ADRS   I2C_EEPROM_ADRS
+#define EEPROM_ADDR0    0xA2   /* on Dimm SPD eeprom */
+#define EEPROM_ADDR1    0xA4   /* on Board SPD eeprom */
+#define EEPROM_ADDR2    0xD2   /* non-standard eeprom - clock generator */
+/* Control Register */
+#define I2C_CTL_EN      0x80   /* I2C Enable                   */
+#define I2C_CTL_IEN     0x40   /* I2C Interrupt Enable         */
+#define I2C_CTL_STA     0x20   /* Master/Slave Mode select     */
+#define I2C_CTL_TX      0x10   /* Transmit/Receive Mode Select */
+#define I2C_CTL_TXAK    0x08   /* Transmit Acknowledge Enable  */
+#define I2C_CTL_RSTA    0x04   /* Repeat Start                 */
+/* Status Register */
+#define I2C_STA_CF      0x80   /* Data Transfer       */
+#define I2C_STA_AAS     0x40   /* Adressed As Slave   */
+#define I2C_STA_BB      0x20   /* Bus Busy            */
+#define I2C_STA_AL      0x10   /* Arbitration Lost    */
+#define I2C_STA_SRW     0x04   /* Slave Read/Write    */
+#define I2C_STA_IF      0x02   /* I2C Interrupt       */
+#define I2C_STA_RXAK    0x01   /* Receive Acknowledge */
+/* Interrupt Contol Register */
+#define I2C_INT_BNBE2   0x80   /* Bus Not Busy Enable 2 */
+#define I2C_INT_TE2     0x40   /* Transmit Enable 2     */
+#define I2C_INT_RE2     0x20   /* Receive Enable 2      */
+#define I2C_INT_IE2     0x10   /* Interrupt Enable 2    */
+#define I2C_INT_BNBE1   0x08   /* Bus Not Busy Enable 1 */
+#define I2C_INT_TE1     0x04   /* Transmit Enable 1     */
+#define I2C_INT_RE1     0x02   /* Receive Enable 1      */
+#define I2C_INT_IE1     0x01   /* Interrupt Enable 1    */
+#define I2C_POLL_COUNT 0x100000
+#define I2C_ENABLE      0x00000001
+#define I2C_DISABLE     0x00000002
+#define I2C_START       0x00000004
+#define I2C_REPSTART    0x00000008
+#define I2C_STOP        0x00000010
+#define I2C_BITRATE     0x00000020
+#define I2C_SLAVEADR    0x00000040
+#define I2C_STARTADR    0x00000080
+#undef TWOBYTES
+typedef struct i2c_settings {
+       /* Device settings */
+       int bit_rate;           /* Device bit rate */
+       u8 i2c_adr;             /* I2C address */
+       u8 slv_adr;             /* Slave address */
+#ifdef TWOBYTES
+       u16 str_adr;            /* Start address */
+#else
+       u8 str_adr;             /* Start address */
+#endif
+       int xfer_size;          /* Transfer Size */
+
+       int bI2c_en;            /* Enable or Disable */
+       int cmdFlag;            /* I2c Command Flags */
+} i2cset_t;
+
+/*
+int check_status(PSI2C pi2c, u8 sta_bit, u8 truefalse);
+int i2c_enable(PSI2C pi2c, PI2CSET pi2cSet);
+int i2c_disable(PSI2C pi2c);
+int i2c_start(PSI2C pi2c, PI2CSET pi2cSet);
+int i2c_stop(PSI2C pi2c);
+int i2c_clear(PSI2C pi2c);
+int i2c_readblock (PSI2C pi2c, PI2CSET pi2cSet, u8 *Data);
+int i2c_writeblock (PSI2C pi2c, PI2CSET pi2cSet, u8 *Data);
+int i2c_readbyte(PSI2C pi2c, u8 *readb, int *index);
+int i2c_writebyte(PSI2C pi2c, u8 *writeb);
+int SetI2cFDR( PSI2C pi2cRegs, int bitrate );
+*/
+#endif /* __ASSEMBLY__ */
+
+#endif /* __INCi2ccoreh */
diff --git a/cpu/mpc8220/interrupts.c b/cpu/mpc8220/interrupts.c
new file mode 100644 (file)
index 0000000..036378c
--- /dev/null
@@ -0,0 +1,80 @@
+/*
+ * (C) Copyright -2003
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * (C) Copyright 2001
+ * Josh Huber <huber@mclx.com>, Mission Critical Linux, Inc.
+ *
+ * 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
+ */
+
+/*
+ * interrupts.c - just enough support for the decrementer/timer
+ */
+
+#include <common.h>
+#include <asm/processor.h>
+#include <command.h>
+
+int interrupt_init_cpu (ulong * decrementer_count)
+{
+       *decrementer_count = get_tbclk () / CFG_HZ;
+
+       return (0);
+}
+
+/****************************************************************************/
+
+/*
+ * Handle external interrupts
+ */
+void external_interrupt (struct pt_regs *regs)
+{
+       puts ("external_interrupt (oops!)\n");
+}
+
+void timer_interrupt_cpu (struct pt_regs *regs)
+{
+       /* nothing to do here */
+       return;
+}
+
+/****************************************************************************/
+
+/*
+ * Install and free a interrupt handler.
+ */
+
+void irq_install_handler (int vec, interrupt_handler_t * handler, void *arg)
+{
+
+}
+
+void irq_free_handler (int vec)
+{
+
+}
+
+/****************************************************************************/
+
+void
+do_irqinfo (cmd_tbl_t * cmdtp, bd_t * bd, int flag, int argc, char *argv[])
+{
+       puts ("IRQ related functions are unimplemented currently.\n");
+}
diff --git a/cpu/mpc8220/io.S b/cpu/mpc8220/io.S
new file mode 100644 (file)
index 0000000..5ecdf55
--- /dev/null
@@ -0,0 +1,128 @@
+/*
+ *  Copyright (C) 1998 Dan Malek <dmalek@jlc.net>
+ *  Copyright (C) 1999 Magnus Damm <kieraypc01.p.y.kie.era.ericsson.se>
+ *  Copyright (C) 2001 Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ *                     Andreas Heppel <aheppel@sysgo.de>
+ *  Copyright (C) 2003 Wolfgang Denk <wd@denx.de>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.         See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <config.h>
+#include <ppc_asm.tmpl>
+
+/* ------------------------------------------------------------------------------- */
+/*  Function:    in8 */
+/*  Description:  Input 8 bits */
+/* ------------------------------------------------------------------------------- */
+       .globl  in8
+in8:
+       lbz     r3,0(r3)
+       sync
+       blr
+
+/* ------------------------------------------------------------------------------- */
+/*  Function:    in16 */
+/*  Description:  Input 16 bits */
+/* ------------------------------------------------------------------------------- */
+       .globl  in16
+in16:
+       lhz     r3,0(r3)
+       sync
+       blr
+
+/* ------------------------------------------------------------------------------- */
+/*  Function:    in16r */
+/*  Description:  Input 16 bits and byte reverse */
+/* ------------------------------------------------------------------------------- */
+       .globl  in16r
+in16r:
+       lhbrx   r3,0,r3
+       sync
+       blr
+
+/* ------------------------------------------------------------------------------- */
+/*  Function:    in32 */
+/*  Description:  Input 32 bits */
+/* ------------------------------------------------------------------------------- */
+       .globl  in32
+in32:
+       lwz     3,0(3)
+       sync
+       blr
+
+/* ------------------------------------------------------------------------------- */
+/*  Function:    in32r */
+/*  Description:  Input 32 bits and byte reverse */
+/* ------------------------------------------------------------------------------- */
+       .globl  in32r
+in32r:
+       lwbrx   r3,0,r3
+       sync
+       blr
+
+/* ------------------------------------------------------------------------------- */
+/*  Function:    out8 */
+/*  Description:  Output 8 bits */
+/* ------------------------------------------------------------------------------- */
+       .globl  out8
+out8:
+       stb     r4,0(r3)
+       sync
+       blr
+
+/* ------------------------------------------------------------------------------- */
+/*  Function:    out16 */
+/*  Description:  Output 16 bits */
+/* ------------------------------------------------------------------------------- */
+       .globl  out16
+out16:
+       sth     r4,0(r3)
+       sync
+       blr
+
+/* ------------------------------------------------------------------------------- */
+/*  Function:    out16r */
+/*  Description:  Byte reverse and output 16 bits */
+/* ------------------------------------------------------------------------------- */
+       .globl  out16r
+out16r:
+       sthbrx  r4,0,r3
+       sync
+       blr
+
+/* ------------------------------------------------------------------------------- */
+/*  Function:    out32 */
+/*  Description:  Output 32 bits */
+/* ------------------------------------------------------------------------------- */
+       .globl  out32
+out32:
+       stw     r4,0(r3)
+       sync
+       blr
+
+/* ------------------------------------------------------------------------------- */
+/*  Function:    out32r */
+/*  Description:  Byte reverse and output 32 bits */
+/* ------------------------------------------------------------------------------- */
+       .globl  out32r
+out32r:
+       stwbrx  r4,0,r3
+       sync
+       blr
diff --git a/cpu/mpc8220/loadtask.c b/cpu/mpc8220/loadtask.c
new file mode 100644 (file)
index 0000000..6d8b627
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ * (C) Copyright 2003
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * This file is based on code
+ * (C) Copyright Motorola, Inc., 2000
+ */
+
+#include <common.h>
+#include <mpc8220.h>
+
+/* Multichannel DMA microcode */
+extern int taskTable;
+
+void loadtask (int basetask, int tasks)
+{
+       int *sram = (int *) (MMAP_SRAM + 512);
+       int *task_org = &taskTable;
+       unsigned int start, offset, end;
+       int i;
+
+#ifdef DEBUG
+       printf ("basetask = %d, tasks = %d\n", basetask, tasks);
+       printf ("task_org = 0x%08x\n", (unsigned int) task_org);
+#endif
+
+       /* setup TaskBAR register */
+       *(vu_long *) MMAP_DMA = (MMAP_SRAM + 512);
+
+       /* relocate task table entries */
+       offset = (unsigned int) sram;
+       for (i = basetask; i < basetask + tasks; i++) {
+               sram[i * 8 + 0] = task_org[i * 8 + 0] + offset;
+               sram[i * 8 + 1] = task_org[i * 8 + 1] + offset;
+               sram[i * 8 + 2] = task_org[i * 8 + 2] + offset;
+               sram[i * 8 + 3] = task_org[i * 8 + 3] + offset;
+               sram[i * 8 + 4] = task_org[i * 8 + 4];
+               sram[i * 8 + 5] = task_org[i * 8 + 5];
+               sram[i * 8 + 6] = task_org[i * 8 + 6] + offset;
+               sram[i * 8 + 7] = task_org[i * 8 + 7];
+       }
+
+       /* relocate task descriptors */
+       start = (sram[basetask * 8] - (unsigned int) sram);
+       end = (sram[(basetask + tasks - 1) * 8 + 1] - (unsigned int) sram);
+
+#ifdef DEBUG
+       printf ("TDT start = 0x%08x, end = 0x%08x\n", start, end);
+#endif
+
+       start /= 4;
+       end /= 4;
+       for (i = start; i <= end; i++) {
+               sram[i] = task_org[i];
+       }
+
+       /* relocate variables */
+       start = (sram[basetask * 8 + 2] - (unsigned int) sram);
+       end = (sram[(basetask + tasks - 1) * 8 + 2] + 256 -
+              (unsigned int) sram);
+       start /= 4;
+       end /= 4;
+       for (i = start; i < end; i++) {
+               sram[i] = task_org[i];
+       }
+
+       /* relocate function decriptors */
+       start = ((sram[basetask * 8 + 3] & 0xfffffffc) - (unsigned int) sram);
+       end = ((sram[(basetask + tasks - 1) * 8 + 3] & 0xfffffffc) + 256 -
+              (unsigned int) sram);
+       start /= 4;
+       end /= 4;
+       for (i = start; i < end; i++) {
+               sram[i] = task_org[i];
+       }
+
+       asm volatile ("sync");
+}
diff --git a/cpu/mpc8220/speed.c b/cpu/mpc8220/speed.c
new file mode 100644 (file)
index 0000000..bd79911
--- /dev/null
@@ -0,0 +1,119 @@
+/*
+ * (C) Copyright 2004, Freescale, Inc
+ * TsiChung Liew, Tsi-Chung.Liew@freescale.com.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <mpc8220.h>
+#include <asm/processor.h>
+
+typedef struct pllmultiplier {
+       u8 hid1;
+       int multi;
+       int vco_div;
+} pllcfg_t;
+
+/* ------------------------------------------------------------------------- */
+
+/*
+ *
+ */
+
+int get_clocks (void)
+{
+       DECLARE_GLOBAL_DATA_PTR;
+
+       pllcfg_t bus2core[] = {
+               {0x10, 2, 8},   /* 1 */
+               {0x08, 2, 4},
+               {0x60, 3, 8},   /* 1.5 */
+               {0x00, 3, 4},
+               {0xc0, 3, 2},
+               {0x28, 4, 4},   /* 2 */
+               {0x20, 4, 2},
+               {0x88, 5, 4},   /* 2.5 */
+               {0x30, 5, 2},
+               {0x80, 6, 4},   /* 3 */
+               {0x40, 6, 2},
+               {0x70, 7, 2},   /* 3.5 */
+               {0x50, 8, 2},   /* 4 */
+               {0x38, 9, 2},   /* 4.5 */
+               {0x58, 10, 2},  /* 5 */
+               {0x48, 11, 2},  /* 5.5 */
+               {0x68, 12, 2},  /* 6 */
+               {0x90, 13, 2},  /* 6.5 */
+               {0xa0, 14, 2},  /* 7 */
+               {0xb0, 15, 2},  /* 7.5 */
+               {0xe0, 16, 2}   /* 8 */
+       };
+       u32 hid1;
+       int i, size;
+
+#if !defined(CFG_MPC8220_CLKIN)
+#error clock measuring not implemented yet - define CFG_MPC8220_CLKIN
+#endif
+
+       gd->inp_clk = CFG_MPC8220_CLKIN;
+
+       /* Bus clock is fixed at 120Mhz for now */
+       /* will do dynamic in the future */
+       gd->bus_clk = CFG_MPC8220_CLKIN * 4;
+
+       /* PCI clock is same as input clock */
+       gd->pci_clk = CFG_MPC8220_CLKIN;
+
+       /* FlexBus is temporary set as the same as input clock */
+       /* will do dynamic in the future */
+       gd->flb_clk = CFG_MPC8220_CLKIN;
+
+       /* CPU Clock - Read HID1 */
+       asm volatile ("mfspr %0, 1009":"=r" (hid1):);
+
+       size = sizeof (bus2core) / sizeof (pllcfg_t);
+       hid1 >>= 24;
+
+       for (i = 0; i < size; i++)
+               if (hid1 == bus2core[i].hid1) {
+                       gd->cpu_clk = (bus2core[i].multi * gd->bus_clk) >> 1;
+                       /* Input Multiplier is determined by MPLL,
+                          hardcoded for now at 16 */
+                       gd->vco_clk = gd->pci_clk * 16;
+                       break;
+               }
+
+       /* hardcoded 81MHz for now */
+       gd->pev_clk = 81000000;
+
+       return (0);
+}
+
+int prt_mpc8220_clks (void)
+{
+       DECLARE_GLOBAL_DATA_PTR;
+
+       printf ("       Bus %ld MHz, CPU %ld MHz, PCI %ld MHz, VCO %ld MHz\n",
+               gd->bus_clk / 1000000, gd->cpu_clk / 1000000,
+               gd->pci_clk / 1000000, gd->vco_clk / 1000000);
+
+       return (0);
+}
+
+/* ------------------------------------------------------------------------- */
diff --git a/cpu/mpc8220/start.S b/cpu/mpc8220/start.S
new file mode 100644 (file)
index 0000000..6072374
--- /dev/null
@@ -0,0 +1,774 @@
+/*
+ *  Copyright (C) 1998 Dan Malek <dmalek@jlc.net>
+ *  Copyright (C) 1999 Magnus Damm <kieraypc01.p.y.kie.era.ericsson.se>
+ *  Copyright (C) 2000 - 2003 Wolfgang Denk <wd@denx.de>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.         See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/*
+ *  U-Boot - Startup Code for MPC8220 CPUs
+ */
+#include <config.h>
+#include <mpc8220.h>
+#include <version.h>
+
+#define _LINUX_CONFIG_H 1   /* avoid reading Linux autoconf.h file  */
+
+#include <ppc_asm.tmpl>
+#include <ppc_defs.h>
+
+#include <asm/cache.h>
+#include <asm/mmu.h>
+
+#ifndef         CONFIG_IDENT_STRING
+#define         CONFIG_IDENT_STRING ""
+#endif
+
+/* We don't want the  MMU yet.
+*/
+#undef MSR_KERNEL
+/* Floating Point enable, Machine Check and Recoverable Interr. */
+#ifdef DEBUG
+#define MSR_KERNEL (MSR_FP|MSR_RI)
+#else
+#define MSR_KERNEL (MSR_FP|MSR_ME|MSR_RI)
+#endif
+
+/*
+ * Set up GOT: Global Offset Table
+ *
+ * Use r14 to access the GOT
+ */
+       START_GOT
+       GOT_ENTRY(_GOT2_TABLE_)
+       GOT_ENTRY(_FIXUP_TABLE_)
+
+       GOT_ENTRY(_start)
+       GOT_ENTRY(_start_of_vectors)
+       GOT_ENTRY(_end_of_vectors)
+       GOT_ENTRY(transfer_to_handler)
+
+       GOT_ENTRY(__init_end)
+       GOT_ENTRY(_end)
+       GOT_ENTRY(__bss_start)
+       END_GOT
+
+/*
+ * Version string
+ */
+       .data
+       .globl  version_string
+version_string:
+       .ascii U_BOOT_VERSION
+       .ascii " (", __DATE__, " - ", __TIME__, ")"
+       .ascii CONFIG_IDENT_STRING, "\0"
+
+/*
+ * Exception vectors
+ */
+       .text
+       . = EXC_OFF_SYS_RESET
+       .globl  _start
+_start:
+       li      r21, BOOTFLAG_COLD  /* Normal Power-On      */
+       nop
+       b       boot_cold
+
+       . = EXC_OFF_SYS_RESET + 0x10
+
+       .globl  _start_warm
+_start_warm:
+       li      r21, BOOTFLAG_WARM  /* Software reboot      */
+       b       boot_warm
+
+boot_cold:
+boot_warm:
+       mfmsr   r5                  /* save msr contents    */
+
+       /* replace default MBAR base address from 0x80000000
+           to 0xf0000000 */
+
+#if defined(CFG_DEFAULT_MBAR) && !defined(CFG_RAMBOOT)
+       lis     r3, CFG_MBAR@h
+       ori     r3, r3, CFG_MBAR@l
+
+       /* MBAR is mirrored into the MBAR SPR */
+       mtspr   MBAR,r3
+       lis     r4, CFG_DEFAULT_MBAR@h
+       stw     r3, 0(r4)
+#endif /* CFG_DEFAULT_MBAR */
+
+       /* Initialise the MPC8220 processor core                        */
+       /*--------------------------------------------------------------*/
+
+       bl  init_8220_core
+
+       /* initialize some things that are hard to access from C        */
+       /*--------------------------------------------------------------*/
+
+       /* set up stack in on-chip SRAM */
+       lis     r3, CFG_INIT_RAM_ADDR@h
+       ori     r3, r3, CFG_INIT_RAM_ADDR@l
+       ori     r1, r3, CFG_INIT_SP_OFFSET
+
+       li      r0, 0           /* Make room for stack frame header and */
+       stwu    r0, -4(r1)      /* clear final stack frame so that      */
+       stwu    r0, -4(r1)      /* stack backtraces terminate cleanly   */
+
+       /* let the C-code set up the rest                               */
+       /*                                                              */
+       /* Be careful to keep code relocatable !                        */
+       /*--------------------------------------------------------------*/
+
+       GET_GOT                 /* initialize GOT access                */
+
+       /* r3: IMMR */
+       bl      cpu_init_f      /* run low-level CPU init code (in Flash)*/
+
+       mr      r3, r21
+       /* r3: BOOTFLAG */
+       bl      board_init_f    /* run 1st part of board init code (in Flash)*/
+
+/*
+ * Vector Table
+ */
+
+       .globl  _start_of_vectors
+_start_of_vectors:
+
+/* Machine check */
+       STD_EXCEPTION(0x200, MachineCheck, MachineCheckException)
+
+/* Data Storage exception. */
+       STD_EXCEPTION(0x300, DataStorage, UnknownException)
+
+/* Instruction Storage exception. */
+       STD_EXCEPTION(0x400, InstStorage, UnknownException)
+
+/* External Interrupt exception. */
+       STD_EXCEPTION(0x500, ExtInterrupt, external_interrupt)
+
+/* Alignment exception. */
+       . = 0x600
+Alignment:
+       EXCEPTION_PROLOG
+       mfspr   r4,DAR
+       stw     r4,_DAR(r21)
+       mfspr   r5,DSISR
+       stw     r5,_DSISR(r21)
+       addi    r3,r1,STACK_FRAME_OVERHEAD
+       li      r20,MSR_KERNEL
+       rlwimi  r20,r23,0,16,16     /* copy EE bit from saved MSR */
+       rlwimi  r20,r23,0,25,25     /* copy IP bit from saved MSR */
+       lwz     r6,GOT(transfer_to_handler)
+       mtlr    r6
+       blrl
+.L_Alignment:
+       .long   AlignmentException - _start + EXC_OFF_SYS_RESET
+       .long   int_return - _start + EXC_OFF_SYS_RESET
+
+/* Program check exception */
+       . = 0x700
+ProgramCheck:
+       EXCEPTION_PROLOG
+       addi    r3,r1,STACK_FRAME_OVERHEAD
+       li      r20,MSR_KERNEL
+       rlwimi  r20,r23,0,16,16     /* copy EE bit from saved MSR */
+       rlwimi  r20,r23,0,25,25     /* copy IP bit from saved MSR */
+       lwz     r6,GOT(transfer_to_handler)
+       mtlr    r6
+       blrl
+.L_ProgramCheck:
+       .long   ProgramCheckException - _start + EXC_OFF_SYS_RESET
+       .long   int_return - _start + EXC_OFF_SYS_RESET
+
+       STD_EXCEPTION(0x800, FPUnavailable, UnknownException)
+
+       /* I guess we could implement decrementer, and may have
+        * to someday for timekeeping.
+        */
+       STD_EXCEPTION(0x900, Decrementer, timer_interrupt)
+
+       STD_EXCEPTION(0xa00, Trap_0a, UnknownException)
+       STD_EXCEPTION(0xb00, Trap_0b, UnknownException)
+       STD_EXCEPTION(0xc00, SystemCall, UnknownException)
+       STD_EXCEPTION(0xd00, SingleStep, UnknownException)
+
+       STD_EXCEPTION(0xe00, Trap_0e, UnknownException)
+       STD_EXCEPTION(0xf00, Trap_0f, UnknownException)
+
+       STD_EXCEPTION(0x1000, InstructionTLBMiss, UnknownException)
+       STD_EXCEPTION(0x1100, DataLoadTLBMiss, UnknownException)
+       STD_EXCEPTION(0x1200, DataStoreTLBMiss, UnknownException)
+#ifdef DEBUG
+       . = 0x1300
+       /*
+        * This exception occurs when the program counter matches the
+        * Instruction Address Breakpoint Register (IABR).
+        *
+        * I want the cpu to halt if this occurs so I can hunt around
+        * with the debugger and look at things.
+        *
+        * When DEBUG is defined, both machine check enable (in the MSR)
+        * and checkstop reset enable (in the reset mode register) are
+        * turned off and so a checkstop condition will result in the cpu
+        * halting.
+        *
+        * I force the cpu into a checkstop condition by putting an illegal
+        * instruction here (at least this is the theory).
+        *
+        * well - that didnt work, so just do an infinite loop!
+        */
+1:     b       1b
+#else
+       STD_EXCEPTION(0x1300, InstructionBreakpoint, DebugException)
+#endif
+       STD_EXCEPTION(0x1400, SMI, UnknownException)
+
+       STD_EXCEPTION(0x1500, Trap_15, UnknownException)
+       STD_EXCEPTION(0x1600, Trap_16, UnknownException)
+       STD_EXCEPTION(0x1700, Trap_17, UnknownException)
+       STD_EXCEPTION(0x1800, Trap_18, UnknownException)
+       STD_EXCEPTION(0x1900, Trap_19, UnknownException)
+       STD_EXCEPTION(0x1a00, Trap_1a, UnknownException)
+       STD_EXCEPTION(0x1b00, Trap_1b, UnknownException)
+       STD_EXCEPTION(0x1c00, Trap_1c, UnknownException)
+       STD_EXCEPTION(0x1d00, Trap_1d, UnknownException)
+       STD_EXCEPTION(0x1e00, Trap_1e, UnknownException)
+       STD_EXCEPTION(0x1f00, Trap_1f, UnknownException)
+       STD_EXCEPTION(0x2000, Trap_20, UnknownException)
+       STD_EXCEPTION(0x2100, Trap_21, UnknownException)
+       STD_EXCEPTION(0x2200, Trap_22, UnknownException)
+       STD_EXCEPTION(0x2300, Trap_23, UnknownException)
+       STD_EXCEPTION(0x2400, Trap_24, UnknownException)
+       STD_EXCEPTION(0x2500, Trap_25, UnknownException)
+       STD_EXCEPTION(0x2600, Trap_26, UnknownException)
+       STD_EXCEPTION(0x2700, Trap_27, UnknownException)
+       STD_EXCEPTION(0x2800, Trap_28, UnknownException)
+       STD_EXCEPTION(0x2900, Trap_29, UnknownException)
+       STD_EXCEPTION(0x2a00, Trap_2a, UnknownException)
+       STD_EXCEPTION(0x2b00, Trap_2b, UnknownException)
+       STD_EXCEPTION(0x2c00, Trap_2c, UnknownException)
+       STD_EXCEPTION(0x2d00, Trap_2d, UnknownException)
+       STD_EXCEPTION(0x2e00, Trap_2e, UnknownException)
+       STD_EXCEPTION(0x2f00, Trap_2f, UnknownException)
+
+
+       .globl  _end_of_vectors
+_end_of_vectors:
+
+       . = 0x3000
+
+/*
+ * This code finishes saving the registers to the exception frame
+ * and jumps to the appropriate handler for the exception.
+ * Register r21 is pointer into trap frame, r1 has new stack pointer.
+ */
+       .globl  transfer_to_handler
+transfer_to_handler:
+       stw     r22,_NIP(r21)
+       lis     r22,MSR_POW@h
+       andc    r23,r23,r22
+       stw     r23,_MSR(r21)
+       SAVE_GPR(7, r21)
+       SAVE_4GPRS(8, r21)
+       SAVE_8GPRS(12, r21)
+       SAVE_8GPRS(24, r21)
+       mflr    r23
+       andi.   r24,r23,0x3f00      /* get vector offset */
+       stw     r24,TRAP(r21)
+       li      r22,0
+       stw     r22,RESULT(r21)
+       lwz     r24,0(r23)              /* virtual address of handler */
+       lwz     r23,4(r23)              /* where to go when done */
+       mtspr   SRR0,r24
+       mtspr   SRR1,r20
+       mtlr    r23
+       SYNC
+       rfi                         /* jump to handler, enable MMU */
+
+int_return:
+       mfmsr   r28                 /* Disable interrupts */
+       li      r4,0
+       ori     r4,r4,MSR_EE
+       andc    r28,r28,r4
+       SYNC                        /* Some chip revs need this... */
+       mtmsr   r28
+       SYNC
+       lwz     r2,_CTR(r1)
+       lwz     r0,_LINK(r1)
+       mtctr   r2
+       mtlr    r0
+       lwz     r2,_XER(r1)
+       lwz     r0,_CCR(r1)
+       mtspr   XER,r2
+       mtcrf   0xFF,r0
+       REST_10GPRS(3, r1)
+       REST_10GPRS(13, r1)
+       REST_8GPRS(23, r1)
+       REST_GPR(31, r1)
+       lwz     r2,_NIP(r1)         /* Restore environment */
+       lwz     r0,_MSR(r1)
+       mtspr   SRR0,r2
+       mtspr   SRR1,r0
+       lwz     r0,GPR0(r1)
+       lwz     r2,GPR2(r1)
+       lwz     r1,GPR1(r1)
+       SYNC
+       rfi
+
+/*
+ * This code initialises the MPC8220 processor core
+ * (conforms to PowerPC 603e spec)
+ * Note: expects original MSR contents to be in r5.
+ */
+
+       .globl  init_8220_core
+init_8220_core:
+
+       /* Initialize machine status; enable machine check interrupt    */
+       /*--------------------------------------------------------------*/
+
+       li      r3, MSR_KERNEL      /* Set ME and RI flags              */
+       rlwimi  r3, r5, 0, 25, 25   /* preserve IP bit set by HRCW      */
+#ifdef DEBUG
+       rlwimi  r3, r5, 0, 21, 22   /* debugger might set SE & BE bits  */
+#endif
+       SYNC                        /* Some chip revs need this...      */
+       mtmsr   r3
+       SYNC
+       mtspr   SRR1, r3            /* Make SRR1 match MSR              */
+
+       /* Initialize the Hardware Implementation-dependent Registers   */
+       /* HID0 also contains cache control                             */
+       /*--------------------------------------------------------------*/
+
+       lis     r3, CFG_HID0_INIT@h
+       ori     r3, r3, CFG_HID0_INIT@l
+       SYNC
+       mtspr   HID0, r3
+
+       lis     r3, CFG_HID0_FINAL@h
+       ori     r3, r3, CFG_HID0_FINAL@l
+       SYNC
+       mtspr   HID0, r3
+
+       /* Enable Extra BATs */
+       mfspr   r3, 1011    /* HID2 */
+       lis     r4, 0x0004
+       ori     r4, r4, 0x0000
+       or      r4, r4, r3
+       mtspr   1011, r4
+       sync
+
+       /* clear all BAT's                                              */
+       /*--------------------------------------------------------------*/
+
+       li      r0, 0
+       mtspr   DBAT0U, r0
+       mtspr   DBAT0L, r0
+       mtspr   DBAT1U, r0
+       mtspr   DBAT1L, r0
+       mtspr   DBAT2U, r0
+       mtspr   DBAT2L, r0
+       mtspr   DBAT3U, r0
+       mtspr   DBAT3L, r0
+       mtspr   DBAT4U, r0
+       mtspr   DBAT4L, r0
+       mtspr   DBAT5U, r0
+       mtspr   DBAT5L, r0
+       mtspr   DBAT6U, r0
+       mtspr   DBAT6L, r0
+       mtspr   DBAT7U, r0
+       mtspr   DBAT7L, r0
+       mtspr   IBAT0U, r0
+       mtspr   IBAT0L, r0
+       mtspr   IBAT1U, r0
+       mtspr   IBAT1L, r0
+       mtspr   IBAT2U, r0
+       mtspr   IBAT2L, r0
+       mtspr   IBAT3U, r0
+       mtspr   IBAT3L, r0
+       mtspr   IBAT4U, r0
+       mtspr   IBAT4L, r0
+       mtspr   IBAT5U, r0
+       mtspr   IBAT5L, r0
+       mtspr   IBAT6U, r0
+       mtspr   IBAT6L, r0
+       mtspr   IBAT7U, r0
+       mtspr   IBAT7L, r0
+       SYNC
+
+       /* invalidate all tlb's                                         */
+       /*                                                              */
+       /* From the 603e User Manual: "The 603e provides the ability to */
+       /* invalidate a TLB entry. The TLB Invalidate Entry (tlbie)     */
+       /* instruction invalidates the TLB entry indexed by the EA, and */
+       /* operates on both the instruction and data TLBs simultaneously*/
+       /* invalidating four TLB entries (both sets in each TLB). The   */
+       /* index corresponds to bits 15-19 of the EA. To invalidate all */
+       /* entries within both TLBs, 32 tlbie instructions should be    */
+       /* issued, incrementing this field by one each time."           */
+       /*                                                              */
+       /* "Note that the tlbia instruction is not implemented on the   */
+       /* 603e."                                                       */
+       /*                                                              */
+       /* bits 15-19 correspond to addresses 0x00000000 to 0x0001F000  */
+       /* incrementing by 0x1000 each time. The code below is sort of  */
+       /* based on code in "flush_tlbs" from arch/ppc/kernel/head.S    */
+       /*                                                              */
+       /*--------------------------------------------------------------*/
+
+       li      r3, 32
+       mtctr   r3
+       li      r3, 0
+1:     tlbie   r3
+       addi    r3, r3, 0x1000
+       bdnz    1b
+       SYNC
+
+       /* Done!                                                        */
+       /*--------------------------------------------------------------*/
+
+       blr
+
+/* Cache functions.
+ *
+ * Note: requires that all cache bits in
+ * HID0 are in the low half word.
+ */
+       .globl  icache_enable
+icache_enable:
+       lis     r4, 0
+       ori     r4, r4, CFG_HID0_INIT /* set ICE & ICFI bit             */
+       rlwinm  r3, r4, 0, 21, 19     /* clear the ICFI bit             */
+
+       /*
+        * The setting of the instruction cache enable (ICE) bit must be
+        * preceded by an isync instruction to prevent the cache from being
+        * enabled or disabled while an instruction access is in progress.
+        */
+       isync
+       mtspr   HID0, r4              /* Enable Instr Cache & Inval cache */
+       mtspr   HID0, r3              /* using 2 consec instructions    */
+       isync
+       blr
+
+       .globl  icache_disable
+icache_disable:
+       mfspr   r3, HID0
+       rlwinm  r3, r3, 0, 17, 15     /* clear the ICE bit              */
+       mtspr   HID0, r3
+       isync
+       blr
+
+       .globl  icache_status
+icache_status:
+       mfspr   r3, HID0
+       rlwinm  r3, r3, HID0_ICE_BITPOS + 1, 31, 31
+       blr
+
+       .globl  dcache_enable
+dcache_enable:
+       lis     r4, 0
+       ori     r4, r4, HID0_DCE|HID0_DCFI /* set DCE & DCFI bit        */
+       rlwinm  r3, r4, 0, 22, 20     /* clear the DCFI bit             */
+
+       /* Enable address translation in MSR bit */
+       mfmsr   r5
+       ori     r5, r5, 0x
+
+
+       /*
+        * The setting of the instruction cache enable (ICE) bit must be
+        * preceded by an isync instruction to prevent the cache from being
+        * enabled or disabled while an instruction access is in progress.
+        */
+       isync
+       mtspr   HID0, r4              /* Enable Data Cache & Inval cache*/
+       mtspr   HID0, r3              /* using 2 consec instructions    */
+       isync
+       blr
+
+       .globl  dcache_disable
+dcache_disable:
+       mfspr   r3, HID0
+       rlwinm  r3, r3, 0, 18, 16     /* clear the DCE bit */
+       mtspr   HID0, r3
+       isync
+       blr
+
+       .globl  dcache_status
+dcache_status:
+       mfspr   r3, HID0
+       rlwinm  r3, r3, HID0_DCE_BITPOS + 1, 31, 31
+       blr
+
+       .globl  get_pvr
+get_pvr:
+       mfspr   r3, PVR
+       blr
+
+/*------------------------------------------------------------------------------*/
+
+/*
+ * void relocate_code (addr_sp, gd, addr_moni)
+ *
+ * This "function" does not return, instead it continues in RAM
+ * after relocating the monitor code.
+ *
+ * r3 = dest
+ * r4 = src
+ * r5 = length in bytes
+ * r6 = cachelinesize
+ */
+       .globl  relocate_code
+relocate_code:
+       mr      r1,  r3     /* Set new stack pointer            */
+       mr      r9,  r4     /* Save copy of Global Data pointer */
+       mr      r10, r5     /* Save copy of Destination Address */
+
+       mr      r3,  r5     /* Destination Address              */
+       lis     r4, CFG_MONITOR_BASE@h  /* Source Address       */
+       ori     r4, r4, CFG_MONITOR_BASE@l
+       lwz     r5, GOT(__init_end)
+       sub     r5, r5, r4
+       li      r6, CFG_CACHELINE_SIZE  /* Cache Line Size      */
+
+       /*
+        * Fix GOT pointer:
+        *
+        * New GOT-PTR = (old GOT-PTR - CFG_MONITOR_BASE) + Destination Address
+        *
+        * Offset:
+        */
+       sub     r15, r10, r4
+
+       /* First our own GOT */
+       add     r14, r14, r15
+       /* then the one used by the C code */
+       add     r30, r30, r15
+
+       /*
+        * Now relocate code
+        */
+
+       cmplw   cr1,r3,r4
+       addi    r0,r5,3
+       srwi.   r0,r0,2
+       beq     cr1,4f      /* In place copy is not necessary   */
+       beq     7f          /* Protect against 0 count          */
+       mtctr   r0
+       bge     cr1,2f
+
+       la      r8,-4(r4)
+       la      r7,-4(r3)
+1:     lwzu    r0,4(r8)
+       stwu    r0,4(r7)
+       bdnz    1b
+       b       4f
+
+2:     slwi    r0,r0,2
+       add     r8,r4,r0
+       add     r7,r3,r0
+3:     lwzu    r0,-4(r8)
+       stwu    r0,-4(r7)
+       bdnz    3b
+
+/*
+ * Now flush the cache: note that we must start from a cache aligned
+ * address. Otherwise we might miss one cache line.
+ */
+4:     cmpwi   r6,0
+       add     r5,r3,r5
+       beq     7f          /* Always flush prefetch queue in any case  */
+       subi    r0,r6,1
+       andc    r3,r3,r0
+       mfspr   r7,HID0     /* don't do dcbst if dcache is disabled     */
+       rlwinm  r7,r7,HID0_DCE_BITPOS+1,31,31
+       cmpwi   r7,0
+       beq     9f
+       mr      r4,r3
+5:     dcbst   0,r4
+       add     r4,r4,r6
+       cmplw   r4,r5
+       blt     5b
+       sync                /* Wait for all dcbst to complete on bus    */
+9:     mfspr   r7,HID0     /* don't do icbi if icache is disabled      */
+       rlwinm  r7,r7,HID0_ICE_BITPOS+1,31,31
+       cmpwi   r7,0
+       beq     7f
+       mr      r4,r3
+6:     icbi    0,r4
+       add     r4,r4,r6
+       cmplw   r4,r5
+       blt     6b
+7:     sync                /* Wait for all icbi to complete on bus     */
+       isync
+
+/*
+ * We are done. Do not return, instead branch to second part of board
+ * initialization, now running from RAM.
+ */
+
+       addi    r0, r10, in_ram - _start + EXC_OFF_SYS_RESET
+       mtlr    r0
+       blr
+
+in_ram:
+
+       /*
+        * Relocation Function, r14 point to got2+0x8000
+        *
+        * Adjust got2 pointers, no need to check for 0, this code
+        * already puts a few entries in the table.
+        */
+       li      r0,__got2_entries@sectoff@l
+       la      r3,GOT(_GOT2_TABLE_)
+       lwz     r11,GOT(_GOT2_TABLE_)
+       mtctr   r0
+       sub     r11,r3,r11
+       addi    r3,r3,-4
+1:     lwzu    r0,4(r3)
+       add     r0,r0,r11
+       stw     r0,0(r3)
+       bdnz    1b
+
+       /*
+        * Now adjust the fixups and the pointers to the fixups
+        * in case we need to move ourselves again.
+        */
+2:     li      r0,__fixup_entries@sectoff@l
+       lwz     r3,GOT(_FIXUP_TABLE_)
+       cmpwi   r0,0
+       mtctr   r0
+       addi    r3,r3,-4
+       beq     4f
+3:     lwzu    r4,4(r3)
+       lwzux   r0,r4,r11
+       add     r0,r0,r11
+       stw     r10,0(r3)
+       stw     r0,0(r4)
+       bdnz    3b
+4:
+clear_bss:
+       /*
+        * Now clear BSS segment
+        */
+       lwz     r3,GOT(__bss_start)
+       lwz     r4,GOT(_end)
+
+       cmplw   0, r3, r4
+       beq     6f
+
+       li      r0, 0
+5:
+       stw     r0, 0(r3)
+       addi    r3, r3, 4
+       cmplw   0, r3, r4
+       bne     5b
+6:
+
+       mr      r3, r9      /* Global Data pointer      */
+       mr      r4, r10     /* Destination Address      */
+       bl      board_init_r
+
+       /*
+        * Copy exception vector code to low memory
+        *
+        * r3: dest_addr
+        * r7: source address, r8: end address, r9: target address
+        */
+       .globl  trap_init
+trap_init:
+       lwz     r7, GOT(_start)
+       lwz     r8, GOT(_end_of_vectors)
+
+       li      r9, 0x100   /* reset vector always at 0x100     */
+
+       cmplw   0, r7, r8
+       bgelr               /* return if r7>=r8 - just in case  */
+
+       mflr    r4          /* save link register               */
+1:
+       lwz     r0, 0(r7)
+       stw     r0, 0(r9)
+       addi    r7, r7, 4
+       addi    r9, r9, 4
+       cmplw   0, r7, r8
+       bne     1b
+
+       /*
+        * relocate `hdlr' and `int_return' entries
+        */
+       li      r7, .L_MachineCheck - _start + EXC_OFF_SYS_RESET
+       li      r8, Alignment - _start + EXC_OFF_SYS_RESET
+2:
+       bl      trap_reloc
+       addi    r7, r7, 0x100       /* next exception vector        */
+       cmplw   0, r7, r8
+       blt     2b
+
+       li      r7, .L_Alignment - _start + EXC_OFF_SYS_RESET
+       bl      trap_reloc
+
+       li      r7, .L_ProgramCheck - _start + EXC_OFF_SYS_RESET
+       bl      trap_reloc
+
+       li      r7, .L_FPUnavailable - _start + EXC_OFF_SYS_RESET
+       li      r8, SystemCall - _start + EXC_OFF_SYS_RESET
+3:
+       bl      trap_reloc
+       addi    r7, r7, 0x100       /* next exception vector        */
+       cmplw   0, r7, r8
+       blt     3b
+
+       li      r7, .L_SingleStep - _start + EXC_OFF_SYS_RESET
+       li      r8, _end_of_vectors - _start + EXC_OFF_SYS_RESET
+4:
+       bl      trap_reloc
+       addi    r7, r7, 0x100       /* next exception vector        */
+       cmplw   0, r7, r8
+       blt     4b
+
+       mfmsr   r3                  /* now that the vectors have    */
+       lis     r7, MSR_IP@h        /* relocated into low memory    */
+       ori     r7, r7, MSR_IP@l    /* MSR[IP] can be turned off    */
+       andc    r3, r3, r7          /* (if it was on)               */
+       SYNC                        /* Some chip revs need this...  */
+       mtmsr   r3
+       SYNC
+
+       mtlr    r4                  /* restore link register        */
+       blr
+
+       /*
+        * Function: relocate entries for one exception vector
+        */
+trap_reloc:
+       lwz     r0, 0(r7)           /* hdlr ...                     */
+       add     r0, r0, r3          /*  ... += dest_addr            */
+       stw     r0, 0(r7)
+
+       lwz     r0, 4(r7)           /* int_return ...               */
+       add     r0, r0, r3          /*  ... += dest_addr            */
+       stw     r0, 4(r7)
+
+       blr
diff --git a/cpu/mpc8220/traps.c b/cpu/mpc8220/traps.c
new file mode 100644 (file)
index 0000000..cdee2be
--- /dev/null
@@ -0,0 +1,239 @@
+/*
+ * linux/arch/ppc/kernel/traps.c
+ *
+ * Copyright (C) 1995-1996  Gary Thomas (gdt@linuxppc.org)
+ *
+ * Modified by Cort Dougan (cort@cs.nmt.edu)
+ * and Paul Mackerras (paulus@cs.anu.edu.au)
+ * fixed Machine Check Reasons by Reinhard Meyer (r.meyer@emk-elektronik.de)
+ *
+ * (C) Copyright 2000-2003
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/*
+ * This file handles the architecture-dependent parts of hardware exceptions
+ */
+
+#include <common.h>
+#include <command.h>
+#include <asm/processor.h>
+
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+int (*debugger_exception_handler) (struct pt_regs *) = 0;
+#endif
+
+/* Returns 0 if exception not found and fixup otherwise.  */
+extern unsigned long search_exception_table (unsigned long);
+
+/* THIS NEEDS CHANGING to use the board info structure.
+*/
+#define END_OF_MEM      0x02000000
+
+/*
+ * Trap & Exception support
+ */
+
+void print_backtrace (unsigned long *sp)
+{
+       int cnt = 0;
+       unsigned long i;
+
+       printf ("Call backtrace: ");
+       while (sp) {
+               if ((uint) sp > END_OF_MEM)
+                       break;
+
+               i = sp[1];
+               if (cnt++ % 7 == 0)
+                       printf ("\n");
+               printf ("%08lX ", i);
+               if (cnt > 32)
+                       break;
+               sp = (unsigned long *) *sp;
+       }
+       printf ("\n");
+}
+
+void show_regs (struct pt_regs *regs)
+{
+       int i;
+
+       printf ("NIP: %08lX XER: %08lX LR: %08lX REGS: %p TRAP: %04lx DAR: %08lX\n",
+               regs->nip, regs->xer, regs->link, regs, regs->trap, regs->dar);
+       printf ("MSR: %08lx EE: %01x PR: %01x FP: %01x ME: %01x IR/DR: %01x%01x\n",
+               regs->msr,
+               regs->msr & MSR_EE ? 1 : 0, regs->msr & MSR_PR ? 1 : 0,
+               regs->msr & MSR_FP ? 1 : 0, regs->msr & MSR_ME ? 1 : 0,
+               regs->msr & MSR_IR ? 1 : 0, regs->msr & MSR_DR ? 1 : 0);
+
+       printf ("\n");
+       for (i = 0; i < 32; i++) {
+               if ((i % 8) == 0) {
+                       printf ("GPR%02d: ", i);
+               }
+
+               printf ("%08lX ", regs->gpr[i]);
+               if ((i % 8) == 7) {
+                       printf ("\n");
+               }
+       }
+}
+
+
+void _exception (int signr, struct pt_regs *regs)
+{
+       show_regs (regs);
+       print_backtrace ((unsigned long *) regs->gpr[1]);
+       panic ("Exception in kernel pc %lx signal %d", regs->nip, signr);
+}
+
+void MachineCheckException (struct pt_regs *regs)
+{
+       unsigned long fixup;
+
+       /* Probing PCI using config cycles cause this exception
+        * when a device is not present.  Catch it and return to
+        * the PCI exception handler.
+        */
+       if ((fixup = search_exception_table (regs->nip)) != 0) {
+               regs->nip = fixup;
+               return;
+       }
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+       if (debugger_exception_handler
+           && (*debugger_exception_handler) (regs))
+               return;
+#endif
+
+       printf ("Machine check in kernel mode.\n");
+       printf ("Caused by (from msr): ");
+       printf ("regs %p ", regs);
+       /* refer to 603e Manual (MPC603EUM/AD), chapter 4.5.2.1 */
+       switch (regs->msr & 0x000F0000) {
+       case (0x80000000 >> 12):
+               printf ("Machine check signal - probably due to mm fault\n"
+                       "with mmu off\n");
+               break;
+       case (0x80000000 >> 13):
+               printf ("Transfer error ack signal\n");
+               break;
+       case (0x80000000 >> 14):
+               printf ("Data parity signal\n");
+               break;
+       case (0x80000000 >> 15):
+               printf ("Address parity signal\n");
+               break;
+       default:
+               printf ("Unknown values in msr\n");
+       }
+       show_regs (regs);
+       print_backtrace ((unsigned long *) regs->gpr[1]);
+       panic ("machine check");
+}
+
+void AlignmentException (struct pt_regs *regs)
+{
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+       if (debugger_exception_handler
+           && (*debugger_exception_handler) (regs))
+               return;
+#endif
+       show_regs (regs);
+       print_backtrace ((unsigned long *) regs->gpr[1]);
+       panic ("Alignment Exception");
+}
+
+void ProgramCheckException (struct pt_regs *regs)
+{
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+       if (debugger_exception_handler
+           && (*debugger_exception_handler) (regs))
+               return;
+#endif
+       show_regs (regs);
+       print_backtrace ((unsigned long *) regs->gpr[1]);
+       panic ("Program Check Exception");
+}
+
+void SoftEmuException (struct pt_regs *regs)
+{
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+       if (debugger_exception_handler
+           && (*debugger_exception_handler) (regs))
+               return;
+#endif
+       show_regs (regs);
+       print_backtrace ((unsigned long *) regs->gpr[1]);
+       panic ("Software Emulation Exception");
+}
+
+
+void UnknownException (struct pt_regs *regs)
+{
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+       if (debugger_exception_handler
+           && (*debugger_exception_handler) (regs))
+               return;
+#endif
+       printf ("Bad trap at PC: %lx, SR: %lx, vector=%lx\n",
+               regs->nip, regs->msr, regs->trap);
+       _exception (0, regs);
+}
+
+#if (CONFIG_COMMANDS & CFG_CMD_BEDBUG)
+extern void do_bedbug_breakpoint (struct pt_regs *);
+#endif
+
+void DebugException (struct pt_regs *regs)
+{
+
+       printf ("Debugger trap at @ %lx\n", regs->nip);
+       show_regs (regs);
+#if (CONFIG_COMMANDS & CFG_CMD_BEDBUG)
+       do_bedbug_breakpoint (regs);
+#endif
+}
+
+/* Probe an address by reading.  If not present, return -1, otherwise
+ * return 0.
+ */
+int addr_probe (uint * addr)
+{
+#if 0
+       int retval;
+
+       __asm__ __volatile__ ("1: lwz %0,0(%1)\n"
+                             "   eieio\n"
+                             "   li %0,0\n"
+                             "2:\n"
+                             ".section .fixup,\"ax\"\n"
+                             "3: li %0,-1\n"
+                             "   b 2b\n"
+                             ".section __ex_table,\"a\"\n"
+                             "   .align 2\n"
+                             "   .long 1b,3b\n"
+                             ".text":"=r" (retval):"r" (addr));
+
+       return (retval);
+#endif
+       return 0;
+}
diff --git a/cpu/mpc8220/uart.c b/cpu/mpc8220/uart.c
new file mode 100644 (file)
index 0000000..fcf947d
--- /dev/null
@@ -0,0 +1,128 @@
+/*
+ * (C) Copyright 2004, Freescale, Inc
+ * TsiChung Liew, Tsi-Chung.Liew@freescale.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
+ *
+ */
+
+/*
+ * Minimal serial functions needed to use one of the PSC ports
+ * as serial console interface.
+ */
+
+#include <common.h>
+#include <mpc8220.h>
+
+#define PSC_BASE   MMAP_PSC1
+
+#if defined(CONFIG_PSC_CONSOLE)
+int psc_serial_init (void)
+{
+       DECLARE_GLOBAL_DATA_PTR;
+       volatile psc8220_t *psc = (psc8220_t *) PSC_BASE;
+       u32 counter;
+
+       /* write to SICR: SIM2 = uart mode,dcd does not affect rx */
+       psc->cr = 0;
+       psc->ipcr_acr = 0;
+       psc->isr_imr = 0;
+
+       /* write to CSR: RX/TX baud rate from timers */
+       psc->sr_csr = 0xdd000000;
+
+       psc->mr1_2 = PSC_MR1_BITS_CHAR_8 | PSC_MR1_NO_PARITY | PSC_MR1_RX_RTS;
+       psc->mr1_2 = PSC_MR2_STOP_BITS_1 | PSC_MR2_TX_CTS;
+
+       /* Setting up BaudRate */
+       counter = ((gd->bus_clk / gd->baudrate)) >> 5;
+       counter++;
+
+       /* write to CTUR: divide counter upper byte */
+       psc->ctur = ((counter & 0xff00) << 16);
+       /* write to CTLR: divide counter lower byte */
+       psc->ctlr = ((counter & 0x00ff) << 24);
+
+       psc->cr = PSC_CR_RST_RX_CMD;
+       psc->cr = PSC_CR_RST_TX_CMD;
+       psc->cr = PSC_CR_RST_ERR_STS_CMD;
+       psc->cr = PSC_CR_RST_BRK_INT_CMD;
+       psc->cr = PSC_CR_RST_MR_PTR_CMD;
+
+       psc->cr = PSC_CR_RX_ENABLE | PSC_CR_TX_ENABLE;
+       return (0);
+}
+
+void psc_serial_putc (const char c)
+{
+       volatile psc8220_t *psc = (psc8220_t *) PSC_BASE;
+
+       if (c == '\n')
+               serial_putc ('\r');
+
+       /* Wait for last character to go. */
+       while (!(psc->sr_csr & PSC_SR_TXEMT));
+
+       psc->xmitbuf[0] = c;
+}
+
+void psc_serial_puts (const char *s)
+{
+       while (*s) {
+               serial_putc (*s++);
+       }
+}
+
+int psc_serial_getc (void)
+{
+       volatile psc8220_t *psc = (psc8220_t *) PSC_BASE;
+
+       /* Wait for a character to arrive. */
+       while (!(psc->sr_csr & PSC_SR_RXRDY));
+       return psc->xmitbuf[2];
+}
+
+int psc_serial_tstc (void)
+{
+       volatile psc8220_t *psc = (psc8220_t *) PSC_BASE;
+
+       return (psc->sr_csr & PSC_SR_RXRDY);
+}
+
+void psc_serial_setbrg (void)
+{
+       DECLARE_GLOBAL_DATA_PTR;
+
+       volatile psc8220_t *psc = (psc8220_t *) PSC_BASE;
+       u32 counter;
+
+       counter = ((gd->bus_clk / gd->baudrate)) >> 5;
+       counter++;
+
+       /* write to CTUR: divide counter upper byte */
+       psc->ctur = ((counter & 0xff00) << 16);
+       /* write to CTLR: divide counter lower byte */
+       psc->ctlr = ((counter & 0x00ff) << 24);
+
+       psc->cr = PSC_CR_RST_RX_CMD;
+       psc->cr = PSC_CR_RST_TX_CMD;
+
+       psc->cr = PSC_CR_RX_ENABLE | PSC_CR_TX_ENABLE;
+}
+#endif /* CONFIG_PSC_CONSOLE */
diff --git a/doc/README.alaska8220 b/doc/README.alaska8220
new file mode 100644 (file)
index 0000000..8e659f3
--- /dev/null
@@ -0,0 +1,482 @@
+Freescale Alaska MPC8220 board
+==============================
+
+TsiChung Liew(Tsi-Chung.Liew@freescale.com)
+Created 9/21/04
+===========================================
+
+
+Changed files:
+==============
+
+- Makefile                 added MPC8220 and Alaska8220_config
+- MAKEALL                  added MPC8220 and Alaska8220
+- README                   added CONFIG_MPC8220, Alaska8220_config
+
+- common/cmd_bdinfo.c      added board information members for MPC8220
+- common/cmd_bootm.c       added clocks for MPC8220 in do_bootm_linux()
+
+- include/common.h         added CONFIG_MPC8220
+
+- include/asm-ppc/u-boot.h  added board information members for MPC8220
+- include/asm-ppc/global_data.h added global variables - inp_clk, pci_clk,
+                           vco_clk, pev_clk, flb_clk, and bExtUart
+
+- lib_ppc/board.c          added CONFIG_MPC8220 support
+
+- net/eth.c                added FEC support for MPC8220
+
+Added files:
+============
+- board/alaska             directory for Alaska MPC8220
+- board/alaska/alaska.c            Alaska dram and BATs setup
+- board/alaska/extserial.c  external serial (debug card serial) support
+- board/alaska/flash.c     Socket (AMD) and Onboard (INTEL) flash support
+- board/alaska/serial.c            to determine which int/ext serial to use
+- board/alaska/Makefile            Makefile
+- board/alaska/config.mk    config make
+- board/alaska/u-boot.lds   Linker description
+
+- cpu/mpc8220/dma.h        multi-channel dma header file
+- cpu/mpc8220/dramSetup.h   dram setup header file
+- cpu/mpc8220/fec.h        MPC8220 FEC header file
+- cpu/mpc8220/cpu.c        cpu specific code
+- cpu/mpc8220/cpu_init.c    Flexbus ChipSelect and Mux pins setup
+- cpu/mpc8220/dramSetup.c   MPC8220 DDR SDRAM setup
+- cpu/mpc8220/fec.c        MPC8220 FEC driver
+- cpu/mpc8220/i2c.c        MPC8220 I2C driver
+- cpu/mpc8220/interrupts.c  interrupt support (not enable)
+- cpu/mpc8220/loadtask.c    load dma
+- cpu/mpc8220/speed.c      system, pci, flexbus, pev, and cpu clock
+- cpu/mpc8220/traps.c      exception
+- cpu/mpc8220/uart.c       MPC8220 UART driver
+- cpu/mpc8220/Makefile     Makefile
+- cpu/mpc8220/config.mk            config make
+- cpu/mpc8220/fec_dma_task.S MPC8220 FEC multi-channel dma program
+- cpu/mpc8220/io.S         io functions
+- cpu/mpc8220/start.S      start up
+
+- include/mpc8220.h
+
+- include/asm-ppc/immap_8220.h
+
+- include/configs/Alaska8220.h
+
+
+1. SWITCH SETTINGS
+==================
+1.1 SW1: 0 - Boot from Socket Flash (AMD) or 1 - Onboard Flash (INTEL)
+    SW2: 0 - Select MPC8220 UART or 1 - Debug Card UART
+    SW3: unsed
+    SW4: 0 - 1284 or 1 - FEC1
+    SW5: 0 - PEV or 1 - FEC2
+
+
+2. MEMORY MAP UNDER U-BOOT AND LINUX KERNEL
+===========================================
+2.1. For the initial bringup, we adopted a consistent memory scheme between u-boot and
+     linux kernel, you can customize it based on your system requirements:
+      DDR:         0x00000000-0x1fffffff (max 512MB)
+      MBAR:        0xf0000000-0xf0027fff (128KB)
+      CPLD:        0xf1000000-0xf103ffff (256KB)
+      FPGA:        0xf2000000-0xf203ffff (256KB)
+      Flash:       0xfe000000-0xffffffff (max 32MB)
+
+3. DEFINITIONS AND COMPILATION
+==============================
+3.1 Explanation on NEW definitions in include/configs/alaska8220.h
+    CONFIG_MPC8220         MPC8220 specific
+    CONFIG_ALASKA8220      Alaska board specific
+    CFG_MPC8220_CLKIN      Define Alaska Input Clock
+    CONFIG_PSC_CONSOLE     Enable MPC8220 UART
+    CONFIG_EXTUART_CONSOLE  Enable External 16552 UART
+    CFG_AMD_BOOT           To determine the u-boot is booted from AMD or Intel
+    CFG_MBAR               MBAR base address
+    CFG_DEFAULT_MBAR       Reset MBAR base address
+
+3.2 Compilation
+   export CROSS_COMPILE=cross-compile-prefix
+   cd u-boot-1-1-x
+   make distclean
+   make Alaska8220_config
+   make
+
+
+4. SCREEN DUMP
+==============
+4.1 Alaska MPC8220 board
+    Boot from AMD (NOTE: May not show exactly the same)
+
+U-Boot 1.1.1 (Sep 22 2004 - 22:14:41)
+
+CPU:   MPC8220 (JTAG ID 1640301d) at 300 MHz
+       Bus 120 MHz, CPU 300 MHz, PCI 30 MHz, VCO 480 MHz
+Board: Alaska MPC8220 Evaluation Board
+I2C:   93 kHz, ready
+DRAM:  256 MB
+Reserving 167k for U-Boot at: 0ffd6000
+FLASH: 16.5 MB
+*** Warning - bad CRC, using default environment
+
+In:    serial
+Out:   serial
+Err:   serial
+Net:   FEC ETHERNET
+=> flinfo
+
+Bank # 1: INTEL 28F128J3A
+  Size: 8 MB in 64 Sectors
+  Sector Start Addresses:
+    FE000000     FE020000      FE040000      FE060000      FE080000
+    FE0A0000     FE0C0000      FE0E0000      FE100000      FE120000
+    FE140000     FE160000      FE180000      FE1A0000      FE1C0000
+    FE1E0000     FE200000      FE220000      FE240000      FE260000
+    FE280000     FE2A0000      FE2C0000      FE2E0000      FE300000
+    FE320000     FE340000      FE360000      FE380000      FE3A0000
+    FE3C0000     FE3E0000      FE400000      FE420000      FE440000
+    FE460000     FE480000      FE4A0000      FE4C0000      FE4E0000
+    FE500000     FE520000      FE540000      FE560000      FE580000
+    FE5A0000     FE5C0000      FE5E0000      FE600000      FE620000
+    FE640000     FE660000      FE680000      FE6A0000      FE6C0000
+    FE6E0000     FE700000      FE720000      FE740000      FE760000
+    FE780000     FE7A0000      FE7C0000      FE7E0000
+
+Bank # 2: INTEL 28F128J3A
+  Size: 8 MB in 64 Sectors
+  Sector Start Addresses:
+    FE800000     FE820000      FE840000      FE860000      FE880000
+    FE8A0000     FE8C0000      FE8E0000      FE900000      FE920000
+    FE940000     FE960000      FE980000      FE9A0000      FE9C0000
+    FE9E0000     FEA00000      FEA20000      FEA40000      FEA60000
+    FEA80000     FEAA0000      FEAC0000      FEAE0000      FEB00000
+    FEB20000     FEB40000      FEB60000      FEB80000      FEBA0000
+    FEBC0000     FEBE0000      FEC00000      FEC20000      FEC40000
+    FEC60000     FEC80000      FECA0000      FECC0000      FECE0000
+    FED00000     FED20000      FED40000      FED60000      FED80000
+    FEDA0000     FEDC0000      FEDE0000      FEE00000      FEE20000
+    FEE40000     FEE60000      FEE80000      FEEA0000      FEEC0000
+    FEEE0000     FEF00000 (RO) FEF20000 (RO) FEF40000      FEF60000
+    FEF80000     FEFA0000      FEFC0000      FEFE0000 (RO)
+
+Bank # 3: AMD AMD29F040B
+  Size: 0 MB in 7 Sectors
+  Sector Start Addresses:
+    FFF00000 (RO) FFF10000 (RO) FFF20000 (RO) FFF30000     FFF40000
+    FFF50000     FFF60000
+
+Bank # 4: AMD AMD29F040B
+  Size: 0 MB in 1 Sectors
+  Sector Start Addresses:
+    FFF70000 (RO)
+=> bdinfo
+
+memstart    = 0xF0009800
+memsize            = 0x10000000
+flashstart  = 0xFFF00000
+flashsize   = 0x01080000
+flashoffset = 0x00025000
+sramstart   = 0xF0020000
+sramsize    = 0x00008000
+bootflags   = 0x00000001
+intfreq            =    300 MHz
+busfreq            =    120 MHz
+inpfreq            =     30 MHz
+flbfreq            =     30 MHz
+pcifreq            =     30 MHz
+vcofreq            =    480 MHz
+pevfreq            =     81 MHz
+ethaddr            = 00:E0:0C:BC:E0:60
+eth1addr    = 00:E0:0C:BC:E0:61
+IP addr            = 192.162.1.2
+baudrate    = 115200 bps
+=> printenv
+bootargs=root=/dev/ram rw
+bootdelay=5
+baudrate=115200
+ethaddr=00:e0:0c:bc:e0:60
+eth1addr=00:e0:0c:bc:e0:61
+ipaddr=192.162.1.2
+serverip=192.162.1.1
+gatewayip=192.162.1.1
+netmask=255.255.255.0
+hostname=Alaska
+stdin=serial
+stdout=serial
+stderr=serial
+ethact=FEC ETHERNET
+
+Environment size: 268/65532 bytes
+=> setenv ipaddr 192.160.1.2
+=> setenv serverip 192.160.1.1
+=> setenv gatewayip 192.160.1.1
+=> saveenv
+Saving Environment to Flash...
+
+.
+Un-Protected 1 sectors
+Erasing Flash...
+Erasing sector 0 ...  done
+Erased 1 sectors
+Writing to Flash... done
+
+.
+Protected 1 sectors
+=> tftp 0x10000 linux.elf
+Using FEC ETHERNET device
+TFTP from server 192.160.1.1; our IP address is 192.160.1.2; sending through gateway 192.160.1.1
+Filename 'linux.elf'.
+Load address: 0x10000
+Loading: invalid RARP header
+#################################################################
+        #################################################################
+        #################################################################
+        #################################################################
+        #################################################################
+        #################################################################
+        #################################################################
+        #################################################################
+        ##################################################
+done
+Bytes transferred = 2917494 (2c8476 hex)
+=> bootelf
+Loading .text @ 0x00a00000 (23820 bytes)
+Loading .data @ 0x00a06000 (2752512 bytes)
+Clearing .bss @ 0x00ca6000 (12764 bytes)
+## Starting application at 0x00a00000 ...
+
+Collect some entropy from RAM........done
+loaded at:     00A00000 00CA91DC
+zimage at:     00A06A93 00AD7756
+initrd at:     00AD8000 00CA5565
+avail ram:     00CAA000 014AA000
+
+Linux/PPC load: ip=off console=ttyS0,115200
+Uncompressing Linux...done.
+Now booting the kernel
+Total memory in system: 256 MB
+Memory BAT mapping: BAT2=256Mb, BAT3=0Mb, residual: 0Mb
+Linux version 2.4.21-rc1 (r61688@bluesocks.sps.mot.com) (gcc version 3.3.1) #17 Wed Sep 8 11:49:16 CDT 2004
+Motorola Alaska port (C) 2003 Motorola, Inc.
+CPLD rev 3
+CPLD switches 0x1b
+Set Pin Mux for FEC1
+Set Pin Mux for FEC2
+Alaska Pin Multiplexing:
+Port Configuration Register 0 = 0
+Port Configuration Register 1 = 0
+Port Configuration Register 2 = 0
+Port Configuration Register 3 = 50000000
+Port Configuration Register 3 - PCI = 51400180
+Setup Alaska FPGA PIC:
+Interrupt Enable Register *(u32) = 0
+Interrupt Status Register = 2f0000
+Interrupt Enable Register in_be32 = 0
+Interrupt Status Register = 2f0000
+Interrupt Enable Register in_le32 = 0
+Interrupt Status Register = 2f00
+Interrupt Enable Register readl = 0
+Interrupt Status Register = 2f00
+Interrupt Enable Register = 0
+Interrupt Status Register = 2f0000
+Setup Alaska PCI Controller:
+On node 0 totalpages: 65536
+zone(0): 65536 pages.
+zone(1): 0 pages.
+zone(2): 0 pages.
+Kernel command line: ip=off console=ttyS0,115200
+Using XLB clock (120.00 MHz) to set up decrementer
+Calibrating delay loop... 199.88 BogoMIPS
+Memory: 254792k available (1476k kernel code, 708k data, 228k init, 0k highmem)
+Dentry cache hash table entries: 32768 (order: 6, 262144 bytes)
+Inode cache hash table entries: 16384 (order: 5, 131072 bytes)
+Mount cache hash table entries: 512 (order: 0, 4096 bytes)
+Buffer-cache hash table entries: 16384 (order: 4, 65536 bytes)
+Page-cache hash table entries: 65536 (order: 6, 262144 bytes)
+POSIX conformance testing by UNIFIX
+PCI: Probing PCI hardware
+PCI: (pcibios_init) Global-Hose = 0xc029d000
+Scanning bus 00
+Fixups for bus 00
+Bus scan for 00 returning with max=00
+PCI: (pcibios_init) finished pci_scan_bus(hose->first_busno = 0, hose->ops = c01a1a74, hose = c029d000)
+PCI: (pcibios_init) PCI Bus Count = 0 =?= Next Bus# = 1
+PCI: (pcibios_init@pci_fixup_irqs) finished machine dependent PCI interrupt routing!
+PCI: bridge rsrc 81000000..81ffffff (100), parent c01a7f88
+PCI: bridge rsrc 84000000..87ffffff (200), parent c01a7fa4
+PCI: (pcibios_init) finished allocating and assigning resources!
+initDma!
+Using 90 DMA buffer descriptors
+descUsed f0023600, descriptors f002360c freeSram f0024140
+unmask SDMA tasks: 0xf0008018 = 0x6f000000
+Linux NET4.0 for Linux 2.4
+Based upon Swansea University Computer Society NET3.039
+Initializing RT netlink socket
+Starting kswapd
+Journalled Block Device driver loaded
+JFFS version 1.0, (C) 1999, 2000  Axis Communications AB
+JFFS2 version 2.1. (C) 2001 Red Hat, Inc., designed by Axis Communications AB.
+pty: 256 Unix98 ptys configured
+tracek: Copyright (C) Motorola, 2003.
+Serial driver version 5.05c (2001-07-08) with MANY_PORTS SHARE_IRQ SERIAL_PCI enabled
+ttyS00 at 0xf1001008 (irq = 73) is a ST16650
+ttyS01 at 0xf1001010 (irq = 74) is a ST16650
+elp-fpanel: Copyright (C) Motorola, 2003.
+fpanel: fpanelWait timeout
+elp-engine: Copyright (C) Motorola, 2003.
+Video disabled due to configuration switch 4
+Alpine 1284 driver: Copyright (C) Motorola, 2003.
+1284 disabled due to configuration switch 5
+Alpine USB driver: Copyright (C) Motorola, 2003.
+OK
+USB: Descriptor download completed OK
+enable_irq(41) unbalanced
+enable_irq(75) unbalanced
+elp-dmaram: Copyright (C) Motorola, 2003.
+Total memory in system: 256 MB
+elp_dmaram: offset is 0x10000000, size is 0
+Xicor NVRAM driver: Copyright (C) Motorola, 2003.
+elp-video: Copyright (C) Motorola, 2003.
+Video disabled due to configuration switch 4
+elp-pfm: Copyright (C) Motorola, 2003.
+paddle: Copyright (C) Motorola, 2001, present.
+RAMDISK driver initialized: 16 RAM disks of 12288K size 1024 blocksize
+loop: loaded (max 8 devices)
+PPP generic driver version 2.4.2
+PPP Deflate Compression module registered
+Uniform Multi-Platform E-IDE driver Revision: 7.00beta-2.4
+ide: Assuming 50MHz system bus speed for PIO modes; override with idebus=xx
+init_alaska_mtd: chip probing count 0
+cfi_cmdset_0001: Erase suspend on write enabled
+Using buffer write method
+init_alaska_mtd: bank1, name:ALASKA0, size:16777216bytes
+ALASKA flash0: Using Static image partition definition
+Creating 3 MTD partitions on "ALASKA0":
+0x00000000-0x00280000 : "kernel"
+0x00280000-0x00fe0000 : "user"
+0x00fe0000-0x01000000 : "signature"
+mgt_fec_module_init
+mgt_fec_init()
+mgt_fec_init
+mgt_init_fec_dev(0xc05f6000,0)
+dev c05f6000 fec_priv c05f6160 fec f0009000
+mgt_init_fec_dev(0xc05f6800,1)
+dev c05f6800 fec_priv c05f6960 fec f0009800
+NET4: Linux TCP/IP 1.0 for NET4.0
+IP Protocols: ICMP, UDP, TCP, IGMP
+IP: routing cache hash table of 2048 buckets, 16Kbytes
+TCP: Hash tables configured (established 16384 bind 32768)
+NET4: Unix domain sockets 1.0/SMP for Linux NET4.0.
+RAMDISK: Compressed image found at block 0
+Freeing initrd memory: 1845k freed
+JFFS: Trying to mount a non-mtd device.
+VFS: Mounted root (romfs filesystem) readonly.
+Freeing unused kernel memory: 228k init
+INIT: version 2.78 booting
+INIT: Entering runlevel: 1
+"Space, a great big place of unknown stuff."  -Dexter, for our MotD.
+[01/Jan/1970:00:00:01 +0000] boa: server version Boa/0.94.8.3
+[01/Jan/1970:00:00:01 +0000] boa: server built Sep  7 2004 at 17:40:55.
+[01/Jan/1970:00:00:01 +0000] boa: starting server pid=28, port 80
+Mounting flash filesystem, will take a minute...
+/etc/rc: line 30: /dev/lp0: No such devish-2.05b#
+sh-2.05b# ifup eth0
+client (v0.9.9-pre) started
+adapter index 2
+adapter hardware address 00:e0:0c:bc:e0:60
+execle'ing /usr/share/udhcpc/default.script
+/sbin/ifconfig eth0
+eth0     Link encap:Ethernet  HWaddr 00:E0:0C:BC:E0:60
+         BROADCAST MULTICAST  MTU:1500  Metric:1
+        mgt_fec_open
+ Rfec request irq
+X fec_open: rcv_ring_size 8, xmt_ring_size 8
+packmgt_fec_open(): call netif_start_queue()
+ets:0 errors:0 dropped:0 overruns:0 frame:0
+         TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
+         collisions:0 txqueuelen:100
+         RX bytes:0 (0.0 b)  TX bytes:0 (0.0 b)
+         Base address:0x9000
+
+/sbin/ifconfig eth0 up
+entering raw listen mode
+Opening raw socket on ifindex 2
+adding option 0x35
+adding option 0x3d
+adding option 0x3c
+Sending discover...
+Waiting on select...
+unrelated/bogus packet
+Waiting on select...
+oooooh!!! got some!
+adding option 0x35
+adding option 0x3d
+adding option 0x3c
+adding option 0x32
+adding option 0x36
+Sending select for 163.12.48.146...
+Waiting on select...
+oooooh!!! got some!
+Waiting on select...
+oooooh!!! got some!
+Lease of 163.12.48.146 obtained, lease time 345600
+execle'ing /usr/share/udhcpc/default.script
+/sbin/ifconfig eth0 163.12.48.146 netmask 255.255.254.0
+/sbin/ifconfig eth0 up
+deleting routers
+/sbin/route del default
+/sbin/route add default gw 163.12.49.254 dev eth0
+adding dns 163.12.252.230
+adding dns 192.55.22.4
+adding dns 192.5.249.4
+entering none listen mode
+sh-2.05b#
+
+5. REPROGRAM U-BOOT
+===================
+5.1 Reprogram u-boot (boot from AMD)
+    1. Unprotect the boot sector
+    => protect off bank 3
+    2. Download new u-boot binary file
+    => tftp 0x10000 u-boot.bin
+    3. Erase bootsector (max 7 sectors)
+    => erase 0xfff00000 0xfff6ffff
+    4. Program the u-boot to flash
+    => cp.b 0x10000 0xfff00000
+    5. Reset for the new u-boot to take place
+    => reset
+
+5.2 Reprogram u-boot (boot from AMD program at INTEL)
+    1. Unprotect the boot sector
+    => protect off bank 2
+    2. Download new u-boot binary file
+    => tftp 0x10000 u-boot.bin
+    3. Erase bootsector (max 7 sectors)
+    => erase 0xfef00000 0xfefdffff
+    4. Program the u-boot to flash
+    => cp.b 0x10000 0xfef00000
+    5. Reset for the new u-boot to take place
+    => reset
+
+5.3 Reprogram u-boot (boot from INTEL)
+    1. Unprotect the boot sector
+    => protect off bank 4
+    2. Download new u-boot binary file
+    => tftp 0x10000 u-boot.bin
+    3. Erase bootsector (max 7 sectors)
+    => erase 0xfff00000 0xfffdffff
+    4. Program the u-boot to flash
+    => cp.b 0x10000 0xfff00000
+    5. Reset for the new u-boot to take place
+    => reset
+
+5.4 Reprogram u-boot (boot from INTEL program at AMD)
+    1. Unprotect the boot sector
+    => protect off bank 1
+    2. Download new u-boot binary file
+    => tftp 0x10000 u-boot.bin
+    3. Erase bootsector (max 7 sectors)
+    => erase 0xfe080000 0xfe0effff
+    4. Program the u-boot to flash
+    => cp.b 0x10000 0xfe080000
+    5. Reset for the new u-boot to take place
+    => reset
index e3ff631eb3808d24b641f265465f9ad741f260f7..b12fe3af4ed4e978d9343e132ac8d8106b67d760 100644 (file)
@@ -49,6 +49,14 @@ typedef      struct  global_data {
 #if defined(CONFIG_MPC5xxx)
        unsigned long   ipb_clk;
        unsigned long   pci_clk;
+#endif
+#if defined(CONFIG_MPC8220)
+       unsigned long   bExtUart;
+       unsigned long   inp_clk;
+       unsigned long   pci_clk;
+       unsigned long   vco_clk;
+       unsigned long   pev_clk;
+       unsigned long   flb_clk;
 #endif
        unsigned long   ram_size;       /* RAM size */
        unsigned long   reloc_off;      /* Relocation Offset */
diff --git a/include/asm-ppc/immap_8220.h b/include/asm-ppc/immap_8220.h
new file mode 100644 (file)
index 0000000..f9595f4
--- /dev/null
@@ -0,0 +1,246 @@
+/*
+ * MPC8220 Internal Memory Map
+ * Copyright (c) 2004 TsiChung Liew (Tsi-Chung.Liew@freescale.com)
+ *
+ * The Internal Memory Map of the 8220.
+ *
+ */
+#ifndef __IMMAP_MPC8220__
+#define __IMMAP_MPC8220__
+
+/*
+ * System configuration registers.
+ */
+typedef struct sys_conf {
+    u16     mbar;       /* 0x00 */
+    u16     res1;
+
+    u16     res2;       /* 0x04 */
+    u16     sdramds;
+
+    u32     res3[6];    /* 0x08 */
+
+    u32     cscfg[6];   /* 0x20 */
+
+    u32     res4[2];    /* 0x38 */
+
+    u8      res5[3];    /* 0x40 */
+    u8      rstctrl;
+
+    u8      res6[3];    /* 0x44 */
+    u8      rststat;
+
+    u32     res7[2];    /* 0x48 */
+
+    u32     jtagid;     /* 0x50 */
+} sysconf8220_t;
+
+
+/*
+ * Memory controller registers.
+ */
+typedef struct mem_ctlr {
+    ushort  mode;           /* 0x100 */
+    ushort  res1;
+    u32     ctrl;           /* 0x104 */
+    u32     cfg1;           /* 0x108 */
+    u32     cfg2;           /* 0x10c */
+} memctl8220_t;
+
+/*
+ * XLB Arbitration registers
+ */
+typedef struct xlb_arb
+{
+    uint    res1[16];       /* 0x200 */
+    uint    config;         /* 0x240 */
+    uint    version;        /* 0x244 */
+    uint    status;         /* 0x248 */
+    uint    intEnable;      /* 0x24c */
+    uint    addrCap;        /* 0x250 */
+    uint    busSigCap;      /* 0x254 */
+    uint    addrTenTimeOut; /* 0x258 */
+    uint    dataTenTimeOut; /* 0x25c */
+    uint    busActTimeOut;  /* 0x260 */
+    uint    mastPriEn;      /* 0x264 */
+    uint    mastPriority;   /* 0x268 */
+    uint    baseAddr;       /* 0x26c */
+} xlbarb8220_t;
+
+/*
+ * Flexbus registers
+ */
+typedef struct flexbus
+{
+    ushort  csar0;          /* 0x00 */
+    ushort  res1;
+    uint    csmr0;          /* 0x04 */
+    uint    cscr0;          /* 0x08 */
+
+    ushort  csar1;          /* 0x0c */
+    ushort  res2;
+    uint    csmr1;          /* 0x10 */
+    uint    cscr1;          /* 0x14 */
+
+    ushort  csar2;          /* 0x18 */
+    ushort  res3;
+    uint    csmr2;          /* 0x1c */
+    uint    cscr2;          /* 0x20 */
+
+    ushort  csar3;          /* 0x24 */
+    ushort  res4;
+    uint    csmr3;          /* 0x28 */
+    uint    cscr3;          /* 0x2c */
+
+    ushort  csar4;          /* 0x30 */
+    ushort  res5;
+    uint    csmr4;          /* 0x34 */
+    uint    cscr4;          /* 0x38 */
+
+    ushort  csar5;          /* 0x3c */
+    ushort  res6;
+    uint    csmr5;          /* 0x40 */
+    uint    cscr5;          /* 0x44 */
+} flexbus8220_t;
+
+/*
+ * GPIO registers
+ */
+typedef struct gpio
+{
+    u32     out;        /* 0x00 */
+    u32     obs;        /* 0x04 */
+    u32     obc;        /* 0x08 */
+    u32     obt;        /* 0x0c */
+    u32     en;         /* 0x10 */
+    u32     ebs;        /* 0x14 */
+    u32     ebc;        /* 0x18 */
+    u32     ebt;        /* 0x1c */
+    u32     mc;         /* 0x20 */
+    u32     st;         /* 0x24 */
+    u32     intr;       /* 0x28 */
+} gpio8220_t;
+
+/*
+ * General Purpose Timer registers
+ */
+typedef struct gptimer
+{
+    u8  OCPW;
+    u8  OctIct;
+    u8  Control;
+    u8  Mode;
+
+    u16 Prescl;  /* Prescale */
+    u16 Count;   /* Count */
+
+    u16 PwmWid;  /* PWM Width */
+    u8  PwmOp;   /* Output Polarity */
+    u8  PwmLd;   /* Immediate Update */
+
+    u16 Capture; /* Capture internal counter */
+    u8  OvfPin;  /* Ovf and Pin */
+    u8  Int;     /* Interrupts */
+} gptmr8220_t;
+
+/*
+ * PSC registers
+ */
+typedef struct psc
+{
+    u32 mr1_2;             /* 0x00 Mode reg 1 & 2 */
+    u32 sr_csr;            /* 0x04 Status/Clock Select reg */
+    u32 cr;                /* 0x08 Command reg */
+    u8  xmitbuf[4];        /* 0x0c Receive/Transmit Buffer */
+    u32 ipcr_acr;          /* 0x10 Input Port Change/Auxiliary Control reg */
+    u32 isr_imr;           /* 0x14 Interrupt Status/Mask reg */
+    u32 ctur;              /* 0x18 Counter Timer Upper reg */
+    u32 ctlr;              /* 0x1c Counter Timer Lower reg */
+    u32 rsvd1[4];          /* 0x20 ... 0x2c */
+    u32 ivr;               /* 0x30 Interrupt Vector reg */
+    u32 ipr;               /* 0x34 Input Port reg */
+    u32 opsetr;            /* 0x38 Output Port Set reg */
+    u32 opresetr;          /* 0x3c Output Port Reset reg */
+    u32 sicr;              /* 0x40 PSC/IrDA control reg */
+    u32 ircr1;             /* 0x44 IrDA control reg 1*/
+    u32 ircr2;             /* 0x48 IrDA control reg 2*/
+    u32 irsdr;             /* 0x4c IrDA SIR Divide reg */
+    u32 irmdr;             /* 0x50 IrDA MIR Divide reg */
+    u32 irfdr;             /* 0x54 PSC IrDA FIR Divide reg */
+    u32 rfnum;             /* 0x58 RX-FIFO counter */
+    u32 txnum;             /* 0x5c TX-FIFO counter */
+    u32 rfdata;            /* 0x60 RX-FIFO data */
+    u32 rfstat;            /* 0x64 RX-FIFO status */
+    u32 rfcntl;            /* 0x68 RX-FIFO control */
+    u32 rfalarm;           /* 0x6c RX-FIFO alarm */
+    u32 rfrptr;            /* 0x70 RX-FIFO read pointer */
+    u32 rfwptr;            /* 0x74 RX-FIFO write pointer */
+    u32 rflfrptr;          /* 0x78 RX-FIFO last read frame pointer */
+    u32 rflfwptr;          /* 0x7c RX-FIFO last write frame pointer */
+
+    u32 tfdata;            /* 0x80 TX-FIFO data */
+    u32 tfstat;            /* 0x84 TX-FIFO status */
+    u32 tfcntl;            /* 0x88 TX-FIFO control */
+    u32 tfalarm;           /* 0x8c TX-FIFO alarm */
+    u32 tfrptr;            /* 0x90 TX-FIFO read pointer */
+    u32 tfwptr;            /* 0x94 TX-FIFO write pointer */
+    u32 tflfrptr;          /* 0x98 TX-FIFO last read frame pointer */
+    u32 tflfwptr;          /* 0x9c TX-FIFO last write frame pointer */
+} psc8220_t;
+
+/*
+ * Interrupt Controller registers
+ */
+typedef struct interrupt_controller {
+} intctl8220_t;
+
+
+/* Fast controllers
+*/
+
+/*
+ * I2C registers
+ */
+typedef struct i2c
+{
+    u8   adr;            /* 0x00 */
+    u8   res1[3];
+    u8   fdr;            /* 0x04 */
+    u8   res2[3];
+    u8   cr;             /* 0x08 */
+    u8   res3[3];
+    u8   sr;             /* 0x0C */
+    u8   res4[3];
+    u8   dr;             /* 0x10 */
+    u8   res5[3];
+    u32  reserved0;      /* 0x14 */
+    u32  reserved1;      /* 0x18 */
+    u32  reserved2;      /* 0x1c */
+    u8   icr;            /* 0x20 */
+    u8   res6[3];
+} i2c8220_t;
+
+/*
+ * Port Configuration Registers
+ */
+typedef struct pcfg
+{
+    uint    pcfg0;          /* 0x00 */
+    uint    pcfg1;          /* 0x04 */
+    uint    pcfg2;          /* 0x08 */
+    uint    pcfg3;          /* 0x0c */
+} pcfg8220_t;
+
+/* ...and the whole thing wrapped up....
+*/
+typedef struct immap {
+    sysconf8220_t   im_sysconf; /* System Configuration */
+    memctl8220_t    im_memctl;  /* Memory Controller */
+    xlbarb8220_t    im_xlbarb;  /* XLB Arbitration */
+    psc8220_t       im_psc;     /* PSC controller */
+    flexbus8220_t   im_fb;      /* FlexBus Controller */
+    i2c8220_t       im_i2c;     /* I2C control/status */
+    pcfg8220_t      im_pcfg;    /* Port configuration */
+} immap_t;
+
+#endif /* __IMMAP_MPC8220__ */
index 4608a288b9b861ae5e46203d8c02781de7c9eed8..72eabb495d9cc328195e8e525a1a5f56958c760a 100644 (file)
@@ -44,6 +44,14 @@ typedef struct bd_info {
 #endif
 #if defined(CONFIG_MPC5xxx)
        unsigned long   bi_mbar_base;   /* base of internal registers */
+#endif
+#if defined(CONFIG_MPC8220)
+       unsigned long   bi_mbar_base;   /* base of internal registers */
+       unsigned long   bi_inpfreq;     /* Input Freq, In MHz */
+       unsigned long   bi_pcifreq;     /* PCI Freq, in MHz */
+       unsigned long   bi_pevfreq;     /* PEV Freq, in MHz */
+       unsigned long   bi_flbfreq;     /* Flexbus Freq, in MHz */
+       unsigned long   bi_vcofreq;     /* VCO Freq, in MHz */
 #endif
        unsigned long   bi_bootflags;   /* boot / reboot flag (for LynxOS) */
        unsigned long   bi_ip_addr;     /* IP Address */
index 353a15ac5688121674c67ad3f0f8bbc4a8fa16c8..697bd7da81c659c3de12091ac8838dad3d8ea9fa 100644 (file)
@@ -63,6 +63,8 @@ typedef volatile unsigned char        vu_char;
 #endif
 #elif defined(CONFIG_5xx)
 #include <asm/5xx_immap.h>
+#elif defined(CONFIG_MPC8220)
+#include <asm/immap_8220.h>
 #elif defined(CONFIG_8260)
 #if   defined(CONFIG_MPC8247) \
    || defined(CONFIG_MPC8248) \
@@ -355,6 +357,7 @@ void        trap_init     (ulong);
     defined (CONFIG_74x)       || \
     defined (CONFIG_75x)       || \
     defined (CONFIG_74xx)      || \
+    defined (CONFIG_MPC8220)   || \
     defined(CONFIG_MPC85xx)
 unsigned char  in8(unsigned int);
 void           out8(unsigned int, unsigned char);
@@ -399,6 +402,9 @@ int prt_8260_clks (void);
 #if defined(CONFIG_MPC5xxx)
 int    prt_mpc5xxx_clks (void);
 #endif
+#if defined(CONFIG_MPC8220)
+int    prt_mpc8220_clks (void);
+#endif
 #ifdef CONFIG_4xx
 ulong  get_OPB_freq (void);
 ulong  get_PCI_freq (void);
diff --git a/include/configs/Alaska8220.h b/include/configs/Alaska8220.h
new file mode 100644 (file)
index 0000000..5cf2a04
--- /dev/null
@@ -0,0 +1,309 @@
+/*
+ * (C) Copyright 2004
+ * TsiChung Liew, Freescale Software Engineering, Tsi-Chung.Liew@freescale.
+ *
+ * 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 __CONFIG_H
+#define __CONFIG_H
+
+/*
+ * High Level Configuration Options
+ * (easy to change)
+ */
+#define CONFIG_MPC8220         1
+#define CONFIG_ALASKA8220      1       /* ... on Alaska board  */
+
+/* Input clock running at 30Mhz, read Hid1 for the CPU multiplier to
+   determine the CPU speed. */
+#define CFG_MPC8220_CLKIN      30000000/* ... running at 30MHz */
+
+#define BOOTFLAG_COLD          0x01    /* Normal Power-On: Boot from FLASH */
+#define BOOTFLAG_WARM          0x02    /* Software reboot      */
+
+#define CFG_CACHELINE_SIZE     32      /* For MPC8220 CPUs */
+
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+#  define CFG_CACHELINE_SHIFT  5   /* log base 2 of the above value */
+#endif
+
+/*
+ * Serial console configuration
+ */
+#define CONFIG_PSC_CONSOLE     1       /* console is on PSC */
+#define CONFIG_EXTUART_CONSOLE 1
+
+#ifdef CONFIG_EXTUART_CONSOLE
+#   define CFG_NS16550
+#   define CFG_NS16550_REG_SIZE 1
+#   define CFG_NS16550_COM1    (CFG_CPLD_BASE + 0x1008)
+#endif
+
+#define CONFIG_BAUDRATE                115200      /* ... at 115200 bps */
+
+
+#define CFG_BAUDRATE_TABLE     { 9600, 19200, 38400, 57600, 115200, 230400 }
+
+/*
+ * Supported commands
+ */
+/* CONFIG_CMD_DFL includes CFG_CMD_BDI (bdinfo), CFG_CMD_LOADS (loads),
+   CFG_CMD_LOADB (loadb), CFG_CMD_IMI (iminfo), CFG_CMD_FLASH
+   (flinfo, erase, protect), CFG_CMD_MEMORY (md, mm, nm, mw, cp, cmp,
+   crc, base, loop, mtest), CFG_CMD_ENV (printenv, setenv, saveenv),
+   CFG_CMD_BOOTD (bootd), CFG_CMD_CONSOLE (coninfo), CFG_CMD_NET (bootp,
+   tftpboot, rarpboot), CFG_CMD_RUN, CFG_CMD_MISC (sleep, etc),
+   CFG_CMD_BSP, CFG_CMD_IMLS, CFG_CMD_FPGA */
+
+#define CONFIG_COMMANDS            (CONFIG_CMD_DFL  | \
+                            CFG_CMD_BOOTD   | \
+                            CFG_CMD_CACHE   | \
+                            CFG_CMD_DIAG    | \
+                            CFG_CMD_EEPROM  | \
+                            CFG_CMD_ELF     | \
+                            CFG_CMD_I2C     | \
+                            CFG_CMD_NET     | \
+                            CFG_CMD_PING    | \
+                            CFG_CMD_REGINFO | \
+                            CFG_CMD_SDRAM     \
+                            )
+/*                            CFG_CMD_DHCP    | \ */
+/*                            CFG_CMD_MII     | \ */
+/*                            CFG_CMD_PCI     | \ */
+/*                            CFG_CMD_USB */
+
+#   define CONFIG_NET_MULTI
+/*#if (CONFIG_COMMANDS & CFG_CMD_NET)
+#   define CONFIG_NET_MULTI
+#else
+#   undef CONFIG_NET_MULTI
+#endif*/
+
+
+/* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */
+#include <cmd_confdefs.h>
+
+/*
+ * Autobooting
+ */
+#define CONFIG_BOOTDELAY       5    /* autoboot after 5 seconds */
+#define CONFIG_BOOTARGS                "root=/dev/ram rw"
+#define CONFIG_ETHADDR         00:e0:0c:bc:e0:60
+#define CONFIG_ETH1ADDR                00:e0:0c:bc:e0:61
+#define CONFIG_IPADDR          192.162.1.2
+#define CONFIG_NETMASK         255.255.255.0
+#define CONFIG_SERVERIP                192.162.1.1
+#define CONFIG_GATEWAYIP       192.162.1.1
+#define CONFIG_HOSTNAME                Alaska
+#define CONFIG_OVERWRITE_ETHADDR_ONCE
+
+
+/*
+ * I2C configuration
+ */
+#define CONFIG_HARD_I2C                1
+#define CFG_I2C_MODULE         1
+
+#define CFG_I2C_SPEED          100000 /* 100 kHz */
+#define CFG_I2C_SLAVE          0x7F
+
+/*
+ * EEPROM configuration
+ */
+#define CFG_I2C_EEPROM_ADDR            0x52    /* 1011000xb */
+#define CFG_I2C_EEPROM_ADDR_LEN                1
+#define CFG_EEPROM_PAGE_WRITE_BITS     3
+#define CFG_EEPROM_PAGE_WRITE_DELAY_MS 70
+/*
+#define CFG_ENV_IS_IN_EEPROM   1
+#define CFG_ENV_OFFSET         0
+#define CFG_ENV_SIZE           256
+*/
+
+/* If CFG_AMD_BOOT is defined, the the system will boot from AMD.
+   else undefined it will boot from Intel Strata flash */
+#define CFG_AMD_BOOT           1
+
+/*
+ * Flexbus Chipselect configuration
+ */
+#if defined (CFG_AMD_BOOT)
+#define CFG_CS0_BASE           0xfff0
+#define CFG_CS0_MASK           0x00080000  /* 512 KB */
+#define CFG_CS0_CTRL           0x003f0d40
+
+#define CFG_CS1_BASE           0xfe00
+#define CFG_CS1_MASK           0x01000000  /* 16 MB */
+#define CFG_CS1_CTRL           0x003f1540
+#else
+#define CFG_CS0_BASE           0xff00
+#define CFG_CS0_MASK           0x01000000  /* 16 MB */
+#define CFG_CS0_CTRL           0x003f1540
+
+#define CFG_CS1_BASE           0xfe08
+#define CFG_CS1_MASK           0x00080000  /* 512 KB */
+#define CFG_CS1_CTRL           0x003f0d40
+#endif
+
+#define CFG_CS2_BASE           0xf100
+#define CFG_CS2_MASK           0x00040000
+#define CFG_CS2_CTRL           0x003f1140
+
+#define CFG_CS3_BASE           0xf200
+#define CFG_CS3_MASK           0x00040000
+#define CFG_CS3_CTRL           0x003f1100
+
+
+#define CFG_FLASH0_BASE                (CFG_CS0_BASE << 16)
+#define CFG_FLASH1_BASE                (CFG_CS1_BASE << 16)
+
+#if defined (CFG_AMD_BOOT)
+#define CFG_AMD_BASE           CFG_FLASH0_BASE
+#define CFG_INTEL_BASE         CFG_FLASH1_BASE + 0xf00000
+#define CFG_FLASH_BASE         CFG_AMD_BASE
+#else
+#define CFG_INTEL_BASE         CFG_FLASH0_BASE + 0xf00000
+#define CFG_AMD_BASE           CFG_FLASH1_BASE
+#define CFG_FLASH_BASE         CFG_INTEL_BASE
+#endif
+
+#define CFG_CPLD_BASE          (CFG_CS2_BASE << 16)
+#define CFG_FPGA_BASE          (CFG_CS3_BASE << 16)
+
+
+#define CFG_MAX_FLASH_BANKS    4       /* max num of memory banks      */
+#define CFG_MAX_FLASH_SECT     128     /* max num of sects on one chip */
+
+#define CFG_FLASH_ERASE_TOUT   240000  /* Flash Erase Timeout (in ms)  */
+#define CFG_FLASH_WRITE_TOUT   500     /* Flash Write Timeout (in ms)  */
+#define CFG_FLASH_LOCK_TOUT    5       /* Timeout for Flash Set Lock Bit (in ms) */
+#define CFG_FLASH_UNLOCK_TOUT  10000   /* Timeout for Flash Clear Lock Bits (in ms) */
+#define CFG_FLASH_PROTECTION           /* "Real" (hardware) sectors protection */
+
+#define PHYS_AMD_SECT_SIZE     0x00010000 /*  64 KB sectors (x2) */
+#define PHYS_INTEL_SECT_SIZE   0x00020000 /* 128 KB sectors (x2) */
+
+#define CFG_FLASH_CHECKSUM
+/*
+ * Environment settings
+ */
+#define CFG_ENV_IS_IN_FLASH    1
+#if defined (CFG_AMD_BOOT)
+#define CFG_ENV_ADDR           (CFG_FLASH0_BASE + CFG_CS0_MASK - PHYS_AMD_SECT_SIZE)
+#define CFG_ENV_SIZE           PHYS_AMD_SECT_SIZE
+#define CFG_ENV_SECT_SIZE      PHYS_AMD_SECT_SIZE
+#define CFG_ENV1_ADDR          (CFG_FLASH1_BASE + CFG_CS1_MASK - PHYS_INTEL_SECT_SIZE)
+#define CFG_ENV1_SIZE          PHYS_INTEL_SECT_SIZE
+#define CFG_ENV1_SECT_SIZE     PHYS_INTEL_SECT_SIZE
+#else
+#define CFG_ENV_ADDR           (CFG_FLASH0_BASE + CFG_CS0_MASK - PHYS_INTEL_SECT_SIZE)
+#define CFG_ENV_SIZE           PHYS_INTEL_SECT_SIZE
+#define CFG_ENV_SECT_SIZE      PHYS_INTEL_SECT_SIZE
+#define CFG_ENV1_ADDR          (CFG_FLASH1_BASE + CFG_CS1_MASK - PHYS_AMD_SECT_SIZE)
+#define CFG_ENV1_SIZE          PHYS_AMD_SECT_SIZE
+#define CFG_ENV1_SECT_SIZE     PHYS_AMD_SECT_SIZE
+#endif
+
+#define CONFIG_ENV_OVERWRITE   1
+
+#if defined CFG_ENV_IS_IN_FLASH
+#undef CFG_ENV_IS_IN_NVRAM
+#undef CFG_ENV_IS_IN_EEPROM
+#elif defined CFG_ENV_IS_IN_NVRAM
+#undef CFG_ENV_IS_IN_FLASH
+#undef CFG_ENV_IS_IN_EEPROM
+#elif defined CFG_ENV_IS_IN_EEPROM
+#undef CFG_ENV_IS_IN_NVRAM
+#undef CFG_ENV_IS_IN_FLASH
+#endif
+
+#ifndef CFG_JFFS2_FIRST_SECTOR
+#define CFG_JFFS2_FIRST_SECTOR 0
+#endif
+#ifndef CFG_JFFS2_FIRST_BANK
+#define CFG_JFFS2_FIRST_BANK   0
+#endif
+#ifndef CFG_JFFS2_NUM_BANKS
+#define CFG_JFFS2_NUM_BANKS    1
+#endif
+#define CFG_JFFS2_LAST_BANK (CFG_JFFS2_FIRST_BANK + CFG_JFFS2_NUM_BANKS - 1)
+
+/*
+ * Memory map
+ */
+#define CFG_MBAR               0xF0000000
+#define CFG_SDRAM_BASE         0x00000000
+#define CFG_DEFAULT_MBAR       0x80000000
+#define CFG_SRAM_BASE          (CFG_MBAR + 0x20000)
+#define CFG_SRAM_SIZE          0x8000
+
+/* Use SRAM until RAM will be available */
+#define CFG_INIT_RAM_ADDR      (CFG_MBAR + 0x20000)
+#define CFG_INIT_RAM_END       0x8000  /* End of used area in DPRAM */
+
+#define CFG_GBL_DATA_SIZE      128     /* size in bytes reserved for initial data */
+#define CFG_GBL_DATA_OFFSET    (CFG_INIT_RAM_END - CFG_GBL_DATA_SIZE)
+#define CFG_INIT_SP_OFFSET     CFG_GBL_DATA_OFFSET
+
+#define CFG_MONITOR_BASE       TEXT_BASE
+#if (CFG_MONITOR_BASE < CFG_FLASH_BASE)
+#   define CFG_RAMBOOT         1
+#endif
+
+#define CFG_MONITOR_LEN                (256 << 10) /* Reserve 256 kB for Monitor   */
+#define CFG_MALLOC_LEN         (128 << 10) /* Reserve 128 kB for malloc()  */
+#define CFG_BOOTMAPSZ          (8 << 20)   /* Initial Memory map for Linux */
+
+/*
+ * Ethernet configuration
+ */
+#define CONFIG_MPC8220_FEC     1
+#define CONFIG_FEC_10MBIT      1 /* Workaround for FEC 100Mbit problem */
+#define CONFIG_PHY_ADDR                0x18
+
+
+/*
+ * Miscellaneous configurable options
+ */
+#define CFG_LONGHELP                       /* undef to save memory     */
+#define CFG_PROMPT             "=> "       /* Monitor Command Prompt   */
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+#define CFG_CBSIZE             1024        /* Console I/O Buffer Size  */
+#else
+#define CFG_CBSIZE             256         /* Console I/O Buffer Size  */
+#endif
+#define CFG_PBSIZE (CFG_CBSIZE+sizeof(CFG_PROMPT)+16)  /* Print Buffer Size */
+#define CFG_MAXARGS            16          /* max number of command args   */
+#define CFG_BARGSIZE           CFG_CBSIZE  /* Boot Argument Buffer Size    */
+
+#define CFG_MEMTEST_START      0x00100000  /* memtest works on */
+#define CFG_MEMTEST_END                0x00f00000  /* 1 ... 15 MB in DRAM  */
+
+#define CFG_LOAD_ADDR          0x100000    /* default load address */
+
+#define CFG_HZ                 1000        /* decrementer freq: 1 ms ticks */
+
+/*
+ * Various low-level settings
+ */
+#define CFG_HID0_INIT          HID0_ICE | HID0_ICFI
+#define CFG_HID0_FINAL         HID0_ICE
+
+#endif /* __CONFIG_H */
diff --git a/include/mpc8220.h b/include/mpc8220.h
new file mode 100644 (file)
index 0000000..fe22b8e
--- /dev/null
@@ -0,0 +1,551 @@
+/*
+ * include/mpc8220.h
+ *
+ * Prototypes, etc. for the Motorola MPC8220
+ * embedded cpu chips
+ *
+ * 2004 (c) Freescale, Inc.
+ * Author: TsiChung Liew <Tsi-Chung.Liew@freescale.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
+ */
+#ifndef __MPC8220_H__
+#define __MPC8220_H__
+
+/* Processor name */
+#if defined(CONFIG_MPC8220)
+#define CPU_ID_STR         "MPC8220"
+#endif
+
+/* Exception offsets (PowerPC standard) */
+#define EXC_OFF_SYS_RESET   0x0100
+
+/* Internal memory map */
+/* MPC8220 Internal Register MMAP */
+#define MMAP_MBAR      (CFG_MBAR + 0x00000000) /* chip selects              */
+#define MMAP_MEMCTL    (CFG_MBAR + 0x00000100) /* sdram controller          */
+#define MMAP_XLBARB    (CFG_MBAR + 0x00000200) /* xlb arbitration control   */
+#define MMAP_CDM       (CFG_MBAR + 0x00000300) /* clock distribution module */
+#define MMAP_VDOPLL    (CFG_MBAR + 0x00000400) /* video PLL                 */
+#define MMAP_FB                (CFG_MBAR + 0x00000500) /* flex bus controller       */
+#define MMAP_PCFG      (CFG_MBAR + 0x00000600) /* port config               */
+#define MMAP_ICTL      (CFG_MBAR + 0x00000700) /* interrupt controller      */
+#define MMAP_GPTMR     (CFG_MBAR + 0x00000800) /* general purpose timers    */
+#define MMAP_SLTMR     (CFG_MBAR + 0x00000900) /* slice timers              */
+#define MMAP_GPIO      (CFG_MBAR + 0x00000A00) /* gpio module               */
+#define MMAP_XCPCI     (CFG_MBAR + 0x00000B00) /* pci controller            */
+#define MMAP_PCIARB    (CFG_MBAR + 0x00000C00) /* pci arbiter               */
+#define MMAP_EXTDMA1   (CFG_MBAR + 0x00000D00) /* external dma1             */
+#define MMAP_EXTDMA2   (CFG_MBAR + 0x00000E00) /* external dma1             */
+#define MMAP_USBH      (CFG_MBAR + 0x00001000) /* usb host                  */
+#define MMAP_CMTMR     (CFG_MBAR + 0x00007f00) /* comm timers               */
+#define MMAP_DMA       (CFG_MBAR + 0x00008000) /* dma                       */
+#define MMAP_USBD      (CFG_MBAR + 0x00008200) /* usb device                */
+#define MMAP_COMMPCI   (CFG_MBAR + 0x00008400) /* pci comm Bus regs         */
+#define MMAP_1284      (CFG_MBAR + 0x00008500) /* 1284                      */
+#define MMAP_PEV       (CFG_MBAR + 0x00008600) /* print engine video        */
+#define MMAP_PSC1      (CFG_MBAR + 0x00008800) /* psc1 block                */
+#define MMAP_I2C       (CFG_MBAR + 0x00008f00) /* i2c controller            */
+#define MMAP_FEC1      (CFG_MBAR + 0x00009000) /* fast ethernet 1           */
+#define MMAP_FEC2      (CFG_MBAR + 0x00009800) /* fast ethernet 2           */
+#define MMAP_JBIGRAM   (CFG_MBAR + 0x0000a000) /* jbig RAM                  */
+#define MMAP_JBIG      (CFG_MBAR + 0x0000c000) /* jbig                      */
+#define MMAP_PDLA      (CFG_MBAR + 0x00010000) /*                           */
+#define MMAP_SRAMCFG   (CFG_MBAR + 0x0001ff00) /* SRAM config               */
+#define MMAP_SRAM      (CFG_MBAR + 0x00020000) /* SRAM                      */
+
+#define SRAM_SIZE      0x8000                  /* 32 KB */
+
+/* ------------------------------------------------------------------------ */
+/*
+ * Macro for Programmable Serial Channel
+ */
+/* equates for mode reg. 1 for channel A or B */
+#define PSC_MR1_RX_RTS         0x80000000    /* receiver RTS enabled */
+#define PSC_MR1_RX_INT         0x40000000    /* receiver intrupt enabled */
+#define PSC_MR1_ERR_MODE       0x20000000    /* block error mode */
+#define PSC_MR1_PAR_MODE_MULTI 0x18000000    /* multi_drop mode */
+#define PSC_MR1_NO_PARITY      0x10000000    /* no parity mode */
+#define PSC_MR1_ALWAYS_0       0x08000000    /* force parity mode */
+#define PSC_MR1_ALWAYS_1       0x0c000000    /* force parity mode */
+#define PSC_MR1_EVEN_PARITY    0x00000000    /* parity mode */
+#define PSC_MR1_ODD_PARITY     0x04000000    /* 0 = even, 1 = odd */
+#define PSC_MR1_BITS_CHAR_8    0x03000000    /* 8 bits */
+#define PSC_MR1_BITS_CHAR_7    0x02000000    /* 7 bits */
+#define PSC_MR1_BITS_CHAR_6    0x01000000    /* 6 bits */
+#define PSC_MR1_BITS_CHAR_5    0x00000000    /* 5 bits */
+
+/* equates for mode reg. 2 for channel A or B */
+#define PSC_MR2_NORMAL_MODE    0x00000000    /* normal channel mode */
+#define PSC_MR2_AUTO_MODE      0x40000000    /* automatic channel mode */
+#define PSC_MR2_LOOPBACK_LOCL  0x80000000    /* local loopback channel mode */
+#define PSC_MR2_LOOPBACK_REMT  0xc0000000    /* remote loopback channel mode */
+#define PSC_MR2_TX_RTS         0x20000000    /* transmitter RTS enabled */
+#define PSC_MR2_TX_CTS         0x10000000    /* transmitter CTS enabled */
+#define PSC_MR2_STOP_BITS_2    0x0f000000    /* 2 stop bits */
+#define PSC_MR2_STOP_BITS_1    0x07000000    /* 1 stop bit */
+
+/* equates for status reg. A or B */
+#define PSC_SR_BREAK           0x80000000    /* received break */
+#define PSC_SR_NEOF            PSC_SR_BREAK  /* Next byte is EOF - MIR/FIR */
+#define PSC_SR_FRAMING         0x40000000    /* framing error */
+#define PSC_SR_PHYERR          PSC_SR_FRAMING/* Physical Layer error - MIR/FIR */
+#define PSC_SR_PARITY          0x20000000    /* parity error */
+#define PSC_SR_CRCERR          PSC_SR_PARITY /* CRC error */
+#define PSC_SR_OVERRUN         0x10000000    /* overrun error */
+#define PSC_SR_TXEMT           0x08000000    /* transmitter empty */
+#define PSC_SR_TXRDY           0x04000000    /* transmitter ready*/
+#define PSC_SR_FFULL           0x02000000    /* fifo full */
+#define PSC_SR_RXRDY           0x01000000    /* receiver ready */
+#define PSC_SR_DEOF            0x00800000    /* Detect EOF or RX-FIFO contain EOF */
+#define PSC_SR_ERR             0x00400000    /* Error Status including FIFO */
+
+/* equates for clock select reg. */
+#define PSC_CSRX16EXT_CLK      0x1110  /* x 16 ext_clock */
+#define PSC_CSRX1EXT_CLK       0x1111  /* x 1 ext_clock  */
+
+/* equates for command reg. A or B */
+#define PSC_CR_NO_COMMAND      0x00000000    /* no command */
+#define PSC_CR_RST_MR_PTR_CMD  0x10000000    /* reset mr pointer command */
+#define PSC_CR_RST_RX_CMD      0x20000000    /* reset receiver command */
+#define PSC_CR_RST_TX_CMD      0x30000000    /* reset transmitter command */
+#define PSC_CR_RST_ERR_STS_CMD 0x40000000    /* reset error status cmnd */
+#define PSC_CR_RST_BRK_INT_CMD 0x50000000    /* reset break int. command */
+#define PSC_CR_STR_BREAK_CMD   0x60000000    /* start break command */
+#define PSC_CR_STP_BREAK_CMD   0x70000000    /* stop break command */
+#define PSC_CR_RX_ENABLE       0x01000000    /* receiver enabled */
+#define PSC_CR_RX_DISABLE      0x02000000    /* receiver disabled */
+#define PSC_CR_TX_ENABLE       0x04000000    /* transmitter enabled */
+#define PSC_CR_TX_DISABLE      0x08000000    /* transmitter disabled */
+
+/* equates for input port change reg. */
+#define PSC_IPCR_SYNC          0x80000000    /* Sync Detect */
+#define PSC_IPCR_D_CTS         0x10000000    /* Delta CTS */
+#define PSC_IPCR_CTS           0x01000000    /* CTS - current state of PSC_CTS */
+
+/* equates for auxiliary control reg. (timer and counter clock selects) */
+#define PSC_ACR_BRG            0x80000000    /* for 68681 compatibility
+                                                baud rate gen select
+                                                0 = set 1; 1 = set 2
+                                                equates are set 2 ONLY */
+#define PSC_ACR_TMR_EXT_CLK_16 0x70000000    /* xtnl clock divided by 16 */
+#define PSC_ACR_TMR_EXT_CLK    0x60000000    /* external clock */
+#define PSC_ACR_TMR_IP2_16     0x50000000    /* ip2 divided by 16 */
+#define PSC_ACR_TMR_IP2                0x40000000    /* ip2 */
+#define PSC_ACR_CTR_EXT_CLK_16 0x30000000    /* xtnl clock divided by 16 */
+#define PSC_ACR_CTR_TXCB       0x20000000    /* channel B xmitr clock */
+#define PSC_ACR_CTR_TXCA       0x10000000    /* channel A xmitr clock */
+#define PSC_ACR_CTR_IP2                0x00000000    /* ip2 */
+#define PSC_ACR_IEC0           0x01000000    /* interrupt enable ctrl for D_CTS */
+
+/* equates for int. status reg. */
+#define PSC_ISR_IPC            0x80000000    /* input port change*/
+#define PSC_ISR_BREAK          0x04000000    /* delta break */
+#define PSC_ISR_RX_RDY         0x02000000    /* receiver rdy /fifo full */
+#define PSC_ISR_TX_RDY         0x01000000    /* transmitter ready */
+#define PSC_ISR_DEOF           0x00800000    /* Detect EOF / RX-FIFO contains EOF */
+#define PSC_ISR_ERR            0x00400000    /* Error Status including FIFO */
+
+/* equates for int. mask reg. */
+#define PSC_IMR_CLEAR          0xff000000    /* Clear the imr */
+#define PSC_IMR_IPC            0x80000000    /* input port change*/
+#define PSC_IMR_BREAK          0x04000000    /* delta break */
+#define PSC_IMR_RX_RDY         0x02000000    /* rcvr ready / fifo full */
+#define PSC_IMR_TX_RDY         0x01000000    /* transmitter ready */
+#define PSC_IMR_DEOF           0x00800000    /* Detect EOF / RX-FIFO contains EOF */
+#define PSC_IMR_ERR            0x00400000    /* Error Status including FIFO */
+
+/* equates for input port reg. */
+#define PSC_IP_LPWRB           0x80000000    /* Low power mode in Ac97 */
+#define PSC_IP_TGL             0x40000000    /* test usage */
+#define PSC_IP_CTS             0x01000000    /* CTS */
+
+/* equates for output port bit set reg. */
+#define PSC_OPSET_RTS          0x01000000    /* Assert PSC_RTS output */
+
+/* equates for output port bit reset reg. */
+#define PSC_OPRESET_RTS                0x01000000    /* Assert PSC_RTS output */
+
+/* equates for rx FIFO number of data reg. */
+#define PSC_RFNUM(x)           ((x&0xff)<<24)/* receive count */
+
+/* equates for tx FIFO number of data reg. */
+#define PSC_TFNUM(x)           ((x&0xff)<<24)/* receive count */
+
+/* equates for rx FIFO status reg */
+#define PSC_RFSTAT_TAG(x)      ((x&3)<<28)   /* tag */
+#define PSC_RFSTAT_FRAME0      0x08          /* Frame Indicator 0 */
+#define PSC_RFSTAT_FRAME1      0x04          /* Frame Indicator 1 */
+#define PSC_RFSTAT_FRAME2      0x02          /* Frame Indicator 2 */
+#define PSC_RFSTAT_FRAME3      0x01          /* Frame Indicator 3 */
+#define PSC_RFSTAT_FRAME(x)    ((x&0x0f)<<24)/* Frame indicator */
+#define PSC_RFSTAT_ERR         0x00400000    /* Fifo err */
+#define PSC_RFSTAT_UF          0x00200000    /* Underflow */
+#define PSC_RFSTAT_OF          0x00100000    /* overflow */
+#define PSC_RFSTAT_FR          0x00080000    /* frame ready */
+#define PSC_RFSTAT_FULL                0x00040000    /* full */
+#define PSC_RFSTAT_ALARM       0x00020000    /* alarm */
+#define PSC_RFSTAT_EMPTY       0x00010000    /* empty */
+
+/* equates for tx FIFO status reg */
+#define PSC_TFSTAT_TAG(x)      ((x&3)<<28)   /* tag */
+#define PSC_TFSTAT_FRAME0      0x08          /* Frame Indicator 0 */
+#define PSC_TFSTAT_FRAME1      0x04          /* Frame Indicator 1 */
+#define PSC_TFSTAT_FRAME2      0x02          /* Frame Indicator 2 */
+#define PSC_TFSTAT_FRAME3      0x01          /* Frame Indicator 3 */
+#define PSC_TFSTAT_FRAME(x)    ((x&0x0f)<<24)/* Frame indicator */
+#define PSC_TFSTAT_ERR         0x00400000    /* Fifo err */
+#define PSC_TFSTAT_UF          0x00200000    /* Underflow */
+#define PSC_TFSTAT_OF          0x00100000    /* overflow */
+#define PSC_TFSTAT_FR          0x00080000    /* frame ready */
+#define PSC_TFSTAT_FULL                0x00040000    /* full */
+#define PSC_TFSTAT_ALARM       0x00020000    /* alarm */
+#define PSC_TFSTAT_EMPTY       0x00010000    /* empty */
+
+/* equates for rx FIFO control reg. */
+#define PSC_RFCNTL_WTAG(x)     ((x&3)<<29)   /* Write tag */
+#define PSC_RFCNTL_FRAME       0x08000000    /* Frame mode enable */
+#define PSC_RFCNTL_GR(x)       ((x&7)<<24)   /* Granularity */
+
+/* equates for tx FIFO control reg. */
+#define PSC_TFCNTL_WTAG(x)     ((x&3)<<29)   /* Write tag */
+#define PSC_TFCNTL_FRAME       0x08000000    /* Frame mode enable */
+#define PSC_TFCNTL_GR(x)       ((x&7)<<24)   /* Granularity */
+
+/* equates for rx FIFO alarm reg */
+#define PSC_RFALARM(x)         (x&0x1ff)     /* Alarm */
+
+/* equates for tx FIFO alarm reg */
+#define PSC_TFALARM(x)         (x&0x1ff)     /* Alarm */
+
+/* equates for rx FIFO read pointer */
+#define PSC_RFRPTR(x)          (x&0x1ff)     /* read pointer */
+
+/* equates for tx FIFO read pointer */
+#define PSC_TFRPTR(x)          (x&0x1ff)     /* read pointer */
+
+/* equates for rx FIFO write pointer */
+#define PSC_RFWPTR(x)          (x&0x1ff)     /* write pointer */
+
+/* equates for rx FIFO write pointer */
+#define PSC_TFWPTR(x)          (x&0x1ff)     /* write pointer */
+
+/* equates for rx FIFO last read frame pointer reg */
+#define PSC_RFLRFPTR(x)                (x&0x1ff)     /* last read frame pointer */
+
+/* equates for tx FIFO last read frame pointer reg */
+#define PSC_TFLRFPTR(x)                (x&0x1ff)     /* last read frame pointer */
+
+/* equates for rx FIFO last write frame pointer reg */
+#define PSC_RFLWFPTR(x)                (x&0x1ff)     /* last write frame pointer */
+
+/* equates for tx FIFO last write frame pointer reg */
+#define PSC_TFLWFPTR(x)                (x&0x1ff)     /* last write frame pointer */
+
+
+/* ------------------------------------------------------------------------ */
+/*
+ * Macro for General Purpose Timer
+ */
+/* Enable and Mode Select */
+#define GPT_OCT(x)         (x & 0x3)<<4/* Output Compare Type */
+#define GPT_ICT(x)         (x & 0x3)   /* Input Capture Type */
+#define GPT_CTRL_WDEN      0x80        /* Watchdog Enable */
+#define GPT_CTRL_CE        0x10        /* Counter Enable */
+#define GPT_CTRL_STPCNT            0x04        /* Stop continous */
+#define GPT_CTRL_ODRAIN            0x02        /* Open Drain */
+#define GPT_CTRL_INTEN     0x01        /* Interrupt Enable */
+#define GPT_MODE_GPIO(x)    (x & 0x3)<<4/* Gpio Mode Type */
+#define GPT_TMS_ICT        0x01        /* Input Capture Enable */
+#define GPT_TMS_OCT        0x02        /* Output Capture Enable */
+#define GPT_TMS_PWM        0x03        /* PWM Capture Enable */
+#define GPT_TMS_SGPIO      0x04        /* PWM Capture Enable */
+
+#define GPT_PWM_WIDTH(x)    (x & 0xffff)
+
+/* Status */
+#define GPT_STA_CAPTURE(x)  (x & 0xffff)/* Read of internal counter */
+
+#define GPT_OVFPIN_OVF(x)   (x & 0x70) /* Internal counter roll over */
+#define GPT_OVFPIN_PIN     0x01        /* Input pin - Timer 0 and 1 */
+
+#define GPT_INT_TEXP       0x08        /* Timer Expired in Internal Timer mode */
+#define GPT_INT_PWMP       0x04        /* PWM end of period occurred */
+#define GPT_INT_COMP       0x02        /* OC reference event occurred */
+#define GPT_INT_CAPT       0x01        /* IC reference event occurred */
+
+/* ------------------------------------------------------------------------ */
+/*
+ * Port configuration
+ */
+#define CFG_FEC1_PORT0_CONFIG  0x00000000
+#define CFG_FEC1_PORT1_CONFIG  0x00000000
+#define CFG_1284_PORT0_CONFIG  0x55555557
+#define CFG_1284_PORT1_CONFIG  0x80000000
+#define CFG_FEC2_PORT2_CONFIG  0x00000000
+#define CFG_PEV_PORT2_CONFIG   0x55555540
+#define CFG_GP0_PORT0_CONFIG   0xaaaaaaa0
+#define CFG_GP1_PORT2_CONFIG   0xaaaaa000
+#define CFG_PSC_PORT3_CONFIG   0x00000000
+#define CFG_CS2_PORT3_CONFIG   0x10000000
+#define CFG_CS3_PORT3_CONFIG   0x40000000
+#define CFG_CS4_PORT3_CONFIG   0x00000400
+#define CFG_CS5_PORT3_CONFIG   0x00000100
+#define CFG_I2C_PORT3_CONFIG   0x003c0000
+
+/* ------------------------------------------------------------------------ */
+/*
+ * DRAM configuration
+ */
+
+/* Field definitions for the control register */
+#define CTL_MODE_ENABLE_SHIFT      31
+#define CTL_CKE_SHIFT              30
+#define CTL_DDR_SHIFT              29
+#define CTL_REFRESH_SHIFT          28
+#define CTL_ADDRMUX_SHIFT          24
+#define CTL_PRECHARGE_SHIFT        23
+#define CTL_DRIVE_RULE_SHIFT       22
+#define CTL_REFRESH_INTERVAL_SHIFT  16
+#define CTL_DQSOEN_SHIFT           8
+#define CTL_BUFFERED_SHIFT         4
+#define CTL_REFRESH_CMD_SHIFT      2
+#define CTL_PRECHARGE_CMD_SHIFT            1
+
+#define CTL_MODE_ENABLE                    (1<<CTL_MODE_ENABLE_SHIFT)
+#define CTL_CKE_HIGH               (1<<CTL_CKE_SHIFT)
+#define CTL_DDR_MODE               (1<<CTL_DDR_SHIFT)
+#define CTL_REFRESH_ENABLE         (1<<CTL_REFRESH_SHIFT)
+#define CTL_ADDRMUX(value)         ((value)<<CTL_ADDRMUX_SHIFT)
+#define CTL_A8PRECHARGE                    (1<<CTL_PRECHARGE_SHIFT)
+#define CTL_REFRESH_INTERVAL(value) ((value)<<CTL_REFRESH_INTERVAL_SHIFT)
+#define CTL_DQSOEN(value)          ((value)<<CTL_DQSOEN_SHIFT)
+#define CTL_BUFFERED               (1<<CTL_BUFFERED_SHIFT)
+#define CTL_REFRESH_CMD                    (1<<CTL_REFRESH_CMD_SHIFT)
+#define CTL_PRECHARGE_CMD          (1<<CTL_PRECHARGE_CMD_SHIFT)
+
+/* Field definitions for config register 1 */
+
+#define CFG1_SRD2RWP_SHIFT         28
+#define CFG1_SWT2RWP_SHIFT         24
+#define CFG1_RLATENCY_SHIFT        20
+#define CFG1_ACT2WR_SHIFT          16
+#define CFG1_PRE2ACT_SHIFT         12
+#define CFG1_REF2ACT_SHIFT         8
+#define CFG1_WLATENCY_SHIFT        4
+
+#define CFG1_SRD2RWP(value)        ((value)<<CFG1_SRD2RWP_SHIFT)
+#define CFG1_SWT2RWP(value)        ((value)<<CFG1_SWT2RWP_SHIFT)
+#define CFG1_RLATENCY(value)       ((value)<<CFG1_RLATENCY_SHIFT)
+#define CFG1_ACT2WR(value)         ((value)<<CFG1_ACT2WR_SHIFT)
+#define CFG1_PRE2ACT(value)        ((value)<<CFG1_PRE2ACT_SHIFT)
+#define CFG1_REF2ACT(value)        ((value)<<CFG1_REF2ACT_SHIFT)
+#define CFG1_WLATENCY(value)       ((value)<<CFG1_WLATENCY_SHIFT)
+
+/* Field definitions for config register 2 */
+#define CFG2_BRD2RP_SHIFT          28
+#define CFG2_BWT2RWP_SHIFT         24
+#define CFG2_BRD2WT_SHIFT          20
+#define CFG2_BURSTLEN_SHIFT        16
+
+#define CFG2_BRD2RP(value)         ((value)<<CFG2_BRD2RP_SHIFT)
+#define CFG2_BWT2RWP(value)        ((value)<<CFG2_BWT2RWP_SHIFT)
+#define CFG2_BRD2WT(value)         ((value)<<CFG2_BRD2WT_SHIFT)
+#define CFG2_BURSTLEN(value)       ((value)<<CFG2_BURSTLEN_SHIFT)
+
+/* Field definitions for the mode/extended mode register - mode
+ * register access
+ */
+#define MODE_REG_SHIFT             30
+#define MODE_OPMODE_SHIFT          25
+#define MODE_CL_SHIFT              22
+#define MODE_BT_SHIFT              21
+#define MODE_BURSTLEN_SHIFT        18
+#define MODE_CMD_SHIFT             16
+
+#define MODE_MODE                  0
+#define MODE_OPMODE(value)         ((value)<<MODE_OPMODE_SHIFT)
+#define MODE_CL(value)             ((value)<<MODE_CL_SHIFT)
+#define MODE_BT_INTERLEAVED        (1<<MODE_BT_SHIFT)
+#define MODE_BT_SEQUENTIAL         (0<<MODE_BT_SHIFT)
+#define MODE_BURSTLEN(value)       ((value)<<MODE_BURSTLEN_SHIFT)
+#define MODE_CMD                   (1<<MODE_CMD_SHIFT)
+
+#define MODE_BURSTLEN_8                    3
+#define MODE_BURSTLEN_4                    2
+#define MODE_BURSTLEN_2                    1
+
+#define MODE_CL_2                  2
+#define MODE_CL_2p5                6
+#define MODE_OPMODE_NORMAL         0
+#define MODE_OPMODE_RESETDLL       2
+
+
+/* Field definitions for the mode/extended mode register - extended
+ * mode register access
+ */
+#define MODE_X_DLL_SHIFT           18 /* DLL enable/disable */
+#define MODE_X_DS_SHIFT                    19 /* Drive strength normal/reduced */
+#define MODE_X_QFC_SHIFT           20 /* QFC function (whatever that is) */
+#define MODE_X_OPMODE_SHIFT        21
+
+#define MODE_EXTENDED              (1<<MODE_REG_SHIFT)
+#define MODE_X_DLL_ENABLE          0
+#define MODE_X_DLL_DISABLE         (1<<MODE_X_DLL_SHIFT)
+#define MODE_X_DS_NORMAL           0
+#define MODE_X_DS_REDUCED          (1<<MODE_X_DS_SHIFT)
+#define MODE_X_QFC_DISABLED        0
+#define MODE_X_OPMODE(value)       ((value)<<MODE_X_OPMODE_SHIFT)
+
+#ifndef __ASSEMBLY__
+/*
+ * DMA control/status registers.
+ */
+struct mpc8220_dma {
+    u32 taskBar;       /* DMA + 0x00 */
+    u32 currentPointer; /* DMA + 0x04 */
+    u32 endPointer;    /* DMA + 0x08 */
+    u32 variablePointer;/* DMA + 0x0c */
+
+    u8 IntVect1;       /* DMA + 0x10 */
+    u8 IntVect2;       /* DMA + 0x11 */
+    u16 PtdCntrl;      /* DMA + 0x12 */
+
+    u32 IntPend;       /* DMA + 0x14 */
+    u32 IntMask;       /* DMA + 0x18 */
+
+    u16 tcr_0;         /* DMA + 0x1c */
+    u16 tcr_1;         /* DMA + 0x1e */
+    u16 tcr_2;         /* DMA + 0x20 */
+    u16 tcr_3;         /* DMA + 0x22 */
+    u16 tcr_4;         /* DMA + 0x24 */
+    u16 tcr_5;         /* DMA + 0x26 */
+    u16 tcr_6;         /* DMA + 0x28 */
+    u16 tcr_7;         /* DMA + 0x2a */
+    u16 tcr_8;         /* DMA + 0x2c */
+    u16 tcr_9;         /* DMA + 0x2e */
+    u16 tcr_a;         /* DMA + 0x30 */
+    u16 tcr_b;         /* DMA + 0x32 */
+    u16 tcr_c;         /* DMA + 0x34 */
+    u16 tcr_d;         /* DMA + 0x36 */
+    u16 tcr_e;         /* DMA + 0x38 */
+    u16 tcr_f;         /* DMA + 0x3a */
+
+    u8 IPR0;           /* DMA + 0x3c */
+    u8 IPR1;           /* DMA + 0x3d */
+    u8 IPR2;           /* DMA + 0x3e */
+    u8 IPR3;           /* DMA + 0x3f */
+    u8 IPR4;           /* DMA + 0x40 */
+    u8 IPR5;           /* DMA + 0x41 */
+    u8 IPR6;           /* DMA + 0x42 */
+    u8 IPR7;           /* DMA + 0x43 */
+    u8 IPR8;           /* DMA + 0x44 */
+    u8 IPR9;           /* DMA + 0x45 */
+    u8 IPR10;          /* DMA + 0x46 */
+    u8 IPR11;          /* DMA + 0x47 */
+    u8 IPR12;          /* DMA + 0x48 */
+    u8 IPR13;          /* DMA + 0x49 */
+    u8 IPR14;          /* DMA + 0x4a */
+    u8 IPR15;          /* DMA + 0x4b */
+    u8 IPR16;          /* DMA + 0x4c */
+    u8 IPR17;          /* DMA + 0x4d */
+    u8 IPR18;          /* DMA + 0x4e */
+    u8 IPR19;          /* DMA + 0x4f */
+    u8 IPR20;          /* DMA + 0x50 */
+    u8 IPR21;          /* DMA + 0x51 */
+    u8 IPR22;          /* DMA + 0x52 */
+    u8 IPR23;          /* DMA + 0x53 */
+    u8 IPR24;          /* DMA + 0x54 */
+    u8 IPR25;          /* DMA + 0x55 */
+    u8 IPR26;          /* DMA + 0x56 */
+    u8 IPR27;          /* DMA + 0x57 */
+    u8 IPR28;          /* DMA + 0x58 */
+    u8 IPR29;          /* DMA + 0x59 */
+    u8 IPR30;          /* DMA + 0x5a */
+    u8 IPR31;          /* DMA + 0x5b */
+
+    u32 res1;          /* DMA + 0x5c */
+    u32 res2;          /* DMA + 0x60 */
+    u32 res3;          /* DMA + 0x64 */
+    u32 MDEDebug;      /* DMA + 0x68 */
+    u32 ADSDebug;      /* DMA + 0x6c */
+    u32 Value1;                /* DMA + 0x70 */
+    u32 Value2;                /* DMA + 0x74 */
+    u32 Control;       /* DMA + 0x78 */
+    u32 Status;                /* DMA + 0x7c */
+    u32 EU00;          /* DMA + 0x80 */
+    u32 EU01;          /* DMA + 0x84 */
+    u32 EU02;          /* DMA + 0x88 */
+    u32 EU03;          /* DMA + 0x8c */
+    u32 EU04;          /* DMA + 0x90 */
+    u32 EU05;          /* DMA + 0x94 */
+    u32 EU06;          /* DMA + 0x98 */
+    u32 EU07;          /* DMA + 0x9c */
+    u32 EU10;          /* DMA + 0xa0 */
+    u32 EU11;          /* DMA + 0xa4 */
+    u32 EU12;          /* DMA + 0xa8 */
+    u32 EU13;          /* DMA + 0xac */
+    u32 EU14;          /* DMA + 0xb0 */
+    u32 EU15;          /* DMA + 0xb4 */
+    u32 EU16;          /* DMA + 0xb8 */
+    u32 EU17;          /* DMA + 0xbc */
+    u32 EU20;          /* DMA + 0xc0 */
+    u32 EU21;          /* DMA + 0xc4 */
+    u32 EU22;          /* DMA + 0xc8 */
+    u32 EU23;          /* DMA + 0xcc */
+    u32 EU24;          /* DMA + 0xd0 */
+    u32 EU25;          /* DMA + 0xd4 */
+    u32 EU26;          /* DMA + 0xd8 */
+    u32 EU27;          /* DMA + 0xdc */
+    u32 EU30;          /* DMA + 0xe0 */
+    u32 EU31;          /* DMA + 0xe4 */
+    u32 EU32;          /* DMA + 0xe8 */
+    u32 EU33;          /* DMA + 0xec */
+    u32 EU34;          /* DMA + 0xf0 */
+    u32 EU35;          /* DMA + 0xf4 */
+    u32 EU36;          /* DMA + 0xf8 */
+    u32 EU37;          /* DMA + 0xfc */
+};
+
+
+/* function prototypes */
+void loadtask(int basetask, int tasks);
+u32 dramSetup(void);
+
+#if defined(CONFIG_PSC_CONSOLE)
+int psc_serial_init (void);
+void psc_serial_putc(const char c);
+void psc_serial_puts (const char *s);
+int psc_serial_getc(void);
+int psc_serial_tstc(void);
+void psc_serial_setbrg(void);
+#endif
+
+#if defined (CONFIG_EXTUART_CONSOLE)
+int ext_serial_init (void);
+void ext_serial_putc(const char c);
+void ext_serial_puts (const char *s);
+int ext_serial_getc(void);
+int ext_serial_tstc(void);
+void ext_serial_setbrg(void);
+#endif
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* __MPC8220_H__ */
index d4d3b74478b43acdceb17567852ce005c90f5ebd..72d690ef0f841473cab652d6474cf78132c9c641 100644 (file)
 #define IM_IMMR                (IM_REGBASE+0x01a8)
 #define IM_SCCR                (IM_REGBASE+0x0c80)
 
-#elif defined(CONFIG_MPC5xxx)
+#elif defined(CONFIG_MPC5xxx) || defined(CONFIG_MPC8220)
 
 #define HID0_ICE_BITPOS        16
 #define HID0_DCE_BITPOS        17
index 12439fe7d78ffa286ed8cd1680254352d4b3fb70..10f70087a392c81cf21e951ea05c64f2d9633d65 100644 (file)
@@ -297,6 +297,9 @@ init_fnc_t *init_sequence[] = {
 #if defined(CONFIG_MPC5xxx)
        prt_mpc5xxx_clks,
 #endif /* CONFIG_MPC5xxx */
+#if defined(CONFIG_MPC8220)
+       prt_mpc8220_clks,
+#endif
        checkboard,
        INIT_FUNC_WATCHDOG_INIT
 #if defined(CONFIG_MISC_INIT_F)
@@ -477,6 +480,9 @@ void board_init_f (ulong bootflag)
 #ifdef CONFIG_IP860
        bd->bi_sramstart = SRAM_BASE;   /* start of  SRAM memory        */
        bd->bi_sramsize  = SRAM_SIZE;   /* size  of  SRAM memory        */
+#elif defined CONFIG_MPC8220
+       bd->bi_sramstart = CFG_SRAM_BASE;       /* start of  SRAM memory        */
+       bd->bi_sramsize  = CFG_SRAM_SIZE;       /* size  of  SRAM memory        */
 #else
        bd->bi_sramstart = 0;           /* FIXME */ /* start of  SRAM memory    */
        bd->bi_sramsize  = 0;           /* FIXME */ /* size  of  SRAM memory    */
@@ -489,6 +495,26 @@ void board_init_f (ulong bootflag)
 #if defined(CONFIG_MPC5xxx)
        bd->bi_mbar_base = CFG_MBAR;    /* base of internal registers */
 #endif
+#if defined(CONFIG_MPC8220)
+       bd->bi_mbar_base = CFG_MBAR;    /* base of internal registers */
+       bd->bi_inpfreq   = gd->inp_clk;
+       bd->bi_pcifreq   = gd->pci_clk;
+       bd->bi_vcofreq   = gd->vco_clk;
+       bd->bi_pevfreq   = gd->pev_clk;
+       bd->bi_flbfreq   = gd->flb_clk;
+
+    /* store bootparam to sram (backward compatible), here? */
+    {
+        u32 *sram = (u32 *)CFG_SRAM_BASE;
+        *sram++ = gd->ram_size;
+        *sram++ = gd->bus_clk;
+        *sram++ = gd->inp_clk;
+        *sram++ = gd->cpu_clk;
+        *sram++ = gd->vco_clk;
+        *sram++ = gd->flb_clk;
+        *sram++ = 0xb8c3ba11;  /* boot signature */
+    }
+#endif
 
        bd->bi_bootflags = bootflag;    /* boot / reboot flag (for LynxOS)    */
 
index 7059123b4ee5a1ea51dc447cdf8141b0e6516358..f59a356d266b17f36bebd8a323d7d27e5b2c927f 100644 (file)
--- a/net/eth.c
+++ b/net/eth.c
@@ -39,6 +39,7 @@ extern int eth_3com_initialize(bd_t*);
 extern int fec_initialize(bd_t*);
 extern int inca_switch_initialize(bd_t*);
 extern int mpc5xxx_fec_initialize(bd_t*);
+extern int mpc8220_fec_initialize(bd_t*);
 extern int mv6436x_eth_initialize(bd_t *);
 extern int mv6446x_eth_initialize(bd_t *);
 extern int natsemi_initialize(bd_t*);
@@ -144,6 +145,9 @@ int eth_initialize(bd_t *bis)
 #if defined(CONFIG_MPC5xxx_FEC)
        mpc5xxx_fec_initialize(bis);
 #endif
+#if defined(CONFIG_MPC8220)
+       mpc8220_fec_initialize(bis);
+#endif
 #if defined(CONFIG_SK98)
        skge_initialize(bis);
 #endif