summaryrefslogtreecommitdiff
path: root/cpu/arm920t
diff options
context:
space:
mode:
authorKevin2014-11-15 11:48:36 +0800
committerKevin2014-11-15 11:48:36 +0800
commitd04075478d378d9e15f3e1abfd14b0bd124077d4 (patch)
tree733dd964582f388b9e3e367c249946cd32a2851f /cpu/arm920t
downloadFOSSEE-netbook-uboot-source-d04075478d378d9e15f3e1abfd14b0bd124077d4.tar.gz
FOSSEE-netbook-uboot-source-d04075478d378d9e15f3e1abfd14b0bd124077d4.tar.bz2
FOSSEE-netbook-uboot-source-d04075478d378d9e15f3e1abfd14b0bd124077d4.zip
init commit via android 4.4 uboot
Diffstat (limited to 'cpu/arm920t')
-rwxr-xr-xcpu/arm920t/Makefile43
-rwxr-xr-xcpu/arm920t/at91rm9200/Makefile44
-rwxr-xr-xcpu/arm920t/at91rm9200/arm920t/Makefile43
-rwxr-xr-xcpu/arm920t/at91rm9200/arm920t/config.mk34
-rwxr-xr-xcpu/arm920t/at91rm9200/arm920t/cpu.c186
-rwxr-xr-xcpu/arm920t/at91rm9200/arm920t/interrupts.c174
-rwxr-xr-xcpu/arm920t/at91rm9200/arm920t/start.S441
-rwxr-xr-xcpu/arm920t/at91rm9200/bcm5221.c232
-rwxr-xr-xcpu/arm920t/at91rm9200/dm9161.c225
-rwxr-xr-xcpu/arm920t/at91rm9200/ether.c299
-rwxr-xr-xcpu/arm920t/at91rm9200/i2c.c206
-rwxr-xr-xcpu/arm920t/at91rm9200/interrupts.c210
-rwxr-xr-xcpu/arm920t/at91rm9200/lowlevel_init.S205
-rwxr-xr-xcpu/arm920t/at91rm9200/lxt972.c191
-rwxr-xr-xcpu/arm920t/at91rm9200/serial.c112
-rwxr-xr-xcpu/arm920t/at91rm9200/usb_ohci.c1635
-rwxr-xr-xcpu/arm920t/at91rm9200/usb_ohci.h419
-rwxr-xr-xcpu/arm920t/config.mk34
-rwxr-xr-xcpu/arm920t/cpu.c204
-rwxr-xr-xcpu/arm920t/imx/Makefile42
-rwxr-xr-xcpu/arm920t/imx/generic.c90
-rwxr-xr-xcpu/arm920t/imx/interrupts.c139
-rwxr-xr-xcpu/arm920t/imx/serial.c201
-rwxr-xr-xcpu/arm920t/imx/speed.c102
-rwxr-xr-xcpu/arm920t/interrupts.c174
-rwxr-xr-xcpu/arm920t/ks8695/Makefile43
-rwxr-xr-xcpu/arm920t/ks8695/interrupts.c112
-rwxr-xr-xcpu/arm920t/ks8695/lowlevel_init.S205
-rwxr-xr-xcpu/arm920t/ks8695/serial.c116
-rwxr-xr-xcpu/arm920t/s3c24x0/Makefile43
-rwxr-xr-xcpu/arm920t/s3c24x0/i2c.c447
-rwxr-xr-xcpu/arm920t/s3c24x0/interrupts.c217
-rwxr-xr-xcpu/arm920t/s3c24x0/serial.c182
-rwxr-xr-xcpu/arm920t/s3c24x0/speed.c101
-rwxr-xr-xcpu/arm920t/s3c24x0/usb_ohci.c1688
-rwxr-xr-xcpu/arm920t/s3c24x0/usb_ohci.h417
-rwxr-xr-xcpu/arm920t/start.S528
-rwxr-xr-xcpu/arm920t/wmt/Makefile72
-rwxr-xr-xcpu/arm920t/wmt/adapter.c503
-rwxr-xr-xcpu/arm920t/wmt/adapter.h201
-rwxr-xr-xcpu/arm920t/wmt/alloct.c289
-rwxr-xr-xcpu/arm920t/wmt/alloct.h94
-rwxr-xr-xcpu/arm920t/wmt/api-loader.c66
-rwxr-xr-xcpu/arm920t/wmt/card.h73
-rwxr-xr-xcpu/arm920t/wmt/cypher.c415
-rwxr-xr-xcpu/arm920t/wmt/cypher.h159
-rwxr-xr-xcpu/arm920t/wmt/cypherif.c180
-rwxr-xr-xcpu/arm920t/wmt/dbg.h47
-rwxr-xr-xcpu/arm920t/wmt/desc.h191
-rwxr-xr-xcpu/arm920t/wmt/diag.h98
-rwxr-xr-xcpu/arm920t/wmt/dma.c926
-rwxr-xr-xcpu/arm920t/wmt/ether.c85
-rwxr-xr-xcpu/arm920t/wmt/gadapter.c631
-rwxr-xr-xcpu/arm920t/wmt/galloct.c349
-rwxr-xr-xcpu/arm920t/wmt/gcard.c170
-rwxr-xr-xcpu/arm920t/wmt/gisr.c779
-rwxr-xr-xcpu/arm920t/wmt/gisr.h72
-rwxr-xr-xcpu/arm920t/wmt/gmac.c1238
-rwxr-xr-xcpu/arm920t/wmt/gmacif.c409
-rwxr-xr-xcpu/arm920t/wmt/gmacif.h64
-rwxr-xr-xcpu/arm920t/wmt/gmib.c453
-rwxr-xr-xcpu/arm920t/wmt/gmii.c535
-rwxr-xr-xcpu/arm920t/wmt/gpio.h317
-rwxr-xr-xcpu/arm920t/wmt/interrupts.c231
-rwxr-xr-xcpu/arm920t/wmt/mac.c737
-rwxr-xr-xcpu/arm920t/wmt/mac.h844
-rwxr-xr-xcpu/arm920t/wmt/macif.c336
-rwxr-xr-xcpu/arm920t/wmt/macif.h71
-rwxr-xr-xcpu/arm920t/wmt/mem.c113
-rwxr-xr-xcpu/arm920t/wmt/mem.h90
-rwxr-xr-xcpu/arm920t/wmt/mib.h228
-rwxr-xr-xcpu/arm920t/wmt/mii.c352
-rwxr-xr-xcpu/arm920t/wmt/mii.h270
-rwxr-xr-xcpu/arm920t/wmt/mmc.c2854
-rwxr-xr-xcpu/arm920t/wmt/pcinet.c263
-rwxr-xr-xcpu/arm920t/wmt/pcinet.h139
-rwxr-xr-xcpu/arm920t/wmt/pmc.h370
-rwxr-xr-xcpu/arm920t/wmt/proto.h92
-rwxr-xr-xcpu/arm920t/wmt/read me.txt29
-rwxr-xr-xcpu/arm920t/wmt/sdc.h508
-rwxr-xr-xcpu/arm920t/wmt/serial.c264
-rwxr-xr-xcpu/arm920t/wmt/setup.h108
-rwxr-xr-xcpu/arm920t/wmt/tascii.h145
-rwxr-xr-xcpu/arm920t/wmt/tbit.h69
-rwxr-xr-xcpu/arm920t/wmt/tconvert.c262
-rwxr-xr-xcpu/arm920t/wmt/tconvert.h55
-rwxr-xr-xcpu/arm920t/wmt/tcrc.c139
-rwxr-xr-xcpu/arm920t/wmt/tcrc.h57
-rwxr-xr-xcpu/arm920t/wmt/tether.h188
-rwxr-xr-xcpu/arm920t/wmt/tmacro.h133
-rwxr-xr-xcpu/arm920t/wmt/tmem.h99
-rwxr-xr-xcpu/arm920t/wmt/tpci.h94
-rwxr-xr-xcpu/arm920t/wmt/ttchar.h245
-rwxr-xr-xcpu/arm920t/wmt/ttype.h181
-rwxr-xr-xcpu/arm920t/wmt/uart.h290
-rwxr-xr-xcpu/arm920t/wmt/uassert.h79
-rwxr-xr-xcpu/arm920t/wmt/upc.h94
-rwxr-xr-xcpu/arm920t/wmt/upci.h78
-rwxr-xr-xcpu/arm920t/wmt/upcix.c194
-rwxr-xr-xcpu/arm920t/wmt/upcix.h59
-rwxr-xr-xcpu/arm920t/wmt/version.h41
-rwxr-xr-xcpu/arm920t/wmt/vpci.c170
-rwxr-xr-xcpu/arm920t/wmt/vpci.h212
-rwxr-xr-xcpu/arm920t/wmt/zde.c111
104 files changed, 29094 insertions, 0 deletions
diff --git a/cpu/arm920t/Makefile b/cpu/arm920t/Makefile
new file mode 100755
index 0000000..8f256e9
--- /dev/null
+++ b/cpu/arm920t/Makefile
@@ -0,0 +1,43 @@
+#
+# (C) Copyright 2000, 2001, 2002
+# 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
+OBJS = cpu.o interrupts.o
+
+all: .depend $(START) $(LIB)
+
+$(LIB): $(OBJS)
+ $(AR) crv $@ $(OBJS)
+
+#########################################################################
+
+.depend: Makefile $(START:.o=.S) $(OBJS:.o=.c)
+ $(CC) -M $(CFLAGS) $(START:.o=.S) $(OBJS:.o=.c) > $@
+
+sinclude .depend
+
+#########################################################################
diff --git a/cpu/arm920t/at91rm9200/Makefile b/cpu/arm920t/at91rm9200/Makefile
new file mode 100755
index 0000000..aec9cb6
--- /dev/null
+++ b/cpu/arm920t/at91rm9200/Makefile
@@ -0,0 +1,44 @@
+#
+# (C) Copyright 2000-2005
+# 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$(SOC).a
+
+OBJS = bcm5221.o dm9161.o ether.o i2c.o interrupts.o \
+ lxt972.o serial.o usb_ohci.o
+SOBJS = lowlevel_init.o
+
+all: .depend $(LIB)
+
+$(LIB): $(OBJS) $(SOBJS)
+ $(AR) crv $@ $(OBJS) $(SOBJS)
+
+#########################################################################
+
+.depend: Makefile $(SOBJS:.o=.S) $(OBJS:.o=.c)
+ $(CC) -M $(CFLAGS) $(SOBJS:.o=.S) $(OBJS:.o=.c) > $@
+
+sinclude .depend
+
+#########################################################################
diff --git a/cpu/arm920t/at91rm9200/arm920t/Makefile b/cpu/arm920t/at91rm9200/arm920t/Makefile
new file mode 100755
index 0000000..0a5169f
--- /dev/null
+++ b/cpu/arm920t/at91rm9200/arm920t/Makefile
@@ -0,0 +1,43 @@
+#
+# (C) Copyright 2000, 2001, 2002
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# Some descriptions of such software. Copyright (c) 2008 WonderMedia Technologies, Inc.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+#
+# WonderMedia Technologies, Inc.
+# 10F, 529, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C.
+#
+
+include $(TOPDIR)/config.mk
+
+LIB = lib$(CPU).a
+
+START = start.o
+OBJS = cpu.o interrupts.o
+
+all: .depend $(START) $(LIB)
+
+$(LIB): $(OBJS)
+ $(AR) crv $@ $(OBJS)
+
+#########################################################################
+
+.depend: Makefile $(START:.o=.S) $(OBJS:.o=.c)
+ $(CC) -M $(CFLAGS) $(START:.o=.S) $(OBJS:.o=.c) > $@
+
+sinclude .depend
+
+#########################################################################
diff --git a/cpu/arm920t/at91rm9200/arm920t/config.mk b/cpu/arm920t/at91rm9200/arm920t/config.mk
new file mode 100755
index 0000000..35d5369
--- /dev/null
+++ b/cpu/arm920t/at91rm9200/arm920t/config.mk
@@ -0,0 +1,34 @@
+#
+# (C) Copyright 2002
+# Gary Jennejohn, DENX Software Engineering, <gj@denx.de>
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# Some descriptions of such software. Copyright (c) 2008 WonderMedia Technologies, Inc.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+#
+# WonderMedia Technologies, Inc.
+# 10F, 529, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C.
+#
+
+PLATFORM_RELFLAGS += -fno-strict-aliasing -fno-common -ffixed-r8 \
+ -msoft-float
+
+PLATFORM_CPPFLAGS += -march=armv6
+# =========================================================================
+#
+# Supply options according to compiler version
+#
+# =========================================================================
+PLATFORM_CPPFLAGS +=$(call cc-option,-mapcs-32)
+PLATFORM_RELFLAGS +=$(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,))
diff --git a/cpu/arm920t/at91rm9200/arm920t/cpu.c b/cpu/arm920t/at91rm9200/arm920t/cpu.c
new file mode 100755
index 0000000..b39587e
--- /dev/null
+++ b/cpu/arm920t/at91rm9200/arm920t/cpu.c
@@ -0,0 +1,186 @@
+/*
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Marius Groeger <mgroeger@sysgo.de>
+ *
+ * (C) Copyright 2002
+ * Gary Jennejohn, DENX Software Engineering, <gj@denx.de>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * Copyright (c) 2008 WonderMedia Technologies, Inc.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ *
+ * WonderMedia Technologies, Inc.
+ * 10F, 529, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C.
+ */
+
+/*
+ * CPU specific code
+ */
+
+#include <common.h>
+#include <command.h>
+#include <arm920t.h>
+
+#ifdef CONFIG_USE_IRQ
+DECLARE_GLOBAL_DATA_PTR;
+#endif
+
+/* read co-processor 15, register #1 (control register) */
+static unsigned long read_p15_c1(void)
+{
+ unsigned long value;
+
+ __asm__ __volatile__(
+ "mrc p15, 0, %0, c1, c0, 0 @ read control reg\n"
+ : "=r" (value)
+ :
+ : "memory");
+
+#ifdef MMU_DEBUG
+ printf("p15/c1 is = %08lx\n", value);
+#endif
+ return value;
+}
+
+/* write to co-processor 15, register #1 (control register) */
+static void write_p15_c1(unsigned long value)
+{
+#ifdef MMU_DEBUG
+ printf("write %08lx to p15/c1\n", value);
+#endif
+ __asm__ __volatile__(
+ "mcr p15, 0, %0, c1, c0, 0 @ write it back\n"
+ :
+ : "r" (value)
+ : "memory");
+
+ read_p15_c1();
+}
+
+static void cp_delay(void)
+{
+ volatile int i;
+
+ /* copro seems to need some delay between reading and writing */
+ for (i = 0; i < 100; i++)
+ ;
+}
+
+/* See also ARM920T Technical reference Manual */
+#define C1_MMU (1<<0) /* mmu off/on */
+#define C1_ALIGN (1<<1) /* alignment faults off/on */
+#define C1_DC (1<<2) /* dcache off/on */
+
+#define C1_BIG_ENDIAN (1<<7) /* big endian off/on */
+#define C1_SYS_PROT (1<<8) /* system protection */
+#define C1_ROM_PROT (1<<9) /* ROM protection */
+#define C1_IC (1<<12) /* icache off/on */
+#define C1_HIGH_VECTORS (1<<13) /* location of vectors: low/high addresses */
+
+
+int cpu_init(void)
+{
+ /*
+ * setup up stacks if necessary
+ */
+#ifdef CONFIG_USE_IRQ
+ IRQ_STACK_START = _armboot_start - CFG_MALLOC_LEN - CFG_GBL_DATA_SIZE - 4;
+ FIQ_STACK_START = IRQ_STACK_START - CONFIG_STACKSIZE_IRQ;
+#endif
+ return 0;
+}
+
+int cleanup_before_linux(void)
+{
+ /*
+ * this function is called just before we call linux
+ * it prepares the processor for linux
+ *
+ * we turn off caches etc ...
+ */
+
+ unsigned long i;
+
+ disable_interrupts();
+
+ /* turn off I/D-cache */
+ asm ("mrc p15, 0, %0, c1, c0, 0" : "=r" (i));
+ i &= ~(C1_DC | C1_IC);
+ asm ("mcr p15, 0, %0, c1, c0, 0" : : "r" (i));
+
+ /* flush I/D-cache */
+ i = 0;
+ asm ("mcr p15, 0, %0, c7, c7, 0" : : "r" (i));
+
+ return 0;
+}
+
+int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+ disable_interrupts();
+ reset_cpu(0);
+ /*NOTREACHED*/
+ return 0;
+}
+
+void icache_enable(void)
+{
+ ulong reg;
+
+ reg = read_p15_c1(); /* get control reg. */
+ cp_delay();
+ write_p15_c1(reg | C1_IC);
+}
+
+void icache_disable(void)
+{
+ ulong reg;
+
+ reg = read_p15_c1();
+ cp_delay();
+ write_p15_c1(reg & ~C1_IC);
+}
+
+int icache_status(void)
+{
+ return (read_p15_c1() & C1_IC) != 0;
+}
+
+#ifdef USE_920T_MMU
+/* It makes no sense to use the dcache if the MMU is not enabled */
+void dcache_enable(void)
+{
+ ulong reg;
+
+ reg = read_p15_c1();
+ cp_delay();
+ write_p15_c1(reg | C1_DC);
+}
+
+void dcache_disable(void)
+{
+ ulong reg;
+
+ reg = read_p15_c1();
+ cp_delay();
+ reg &= ~C1_DC;
+ write_p15_c1(reg);
+}
+
+int dcache_status(void)
+{
+ return (read_p15_c1() & C1_DC) != 0;
+}
+#endif
diff --git a/cpu/arm920t/at91rm9200/arm920t/interrupts.c b/cpu/arm920t/at91rm9200/arm920t/interrupts.c
new file mode 100755
index 0000000..e90e385
--- /dev/null
+++ b/cpu/arm920t/at91rm9200/arm920t/interrupts.c
@@ -0,0 +1,174 @@
+/*
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Marius Groeger <mgroeger@sysgo.de>
+ *
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Alex Zuepke <azu@sysgo.de>
+ *
+ * (C) Copyright 2002
+ * Gary Jennejohn, DENX Software Engineering, <gj@denx.de>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * Copyright (c) 2008 WonderMedia Technologies, Inc.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ *
+ * WonderMedia Technologies, Inc.
+ * 10F, 529, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C.
+ */
+
+#include <common.h>
+#include <arm920t.h>
+#include <asm/proc-armv/ptrace.h>
+
+#ifdef CONFIG_USE_IRQ
+/* enable IRQ interrupts */
+void enable_interrupts(void)
+{
+ unsigned long temp;
+ __asm__ __volatile__("mrs %0, cpsr\n"
+ "bic %0, %0, #0x80\n"
+ "msr cpsr_c, %0"
+ : "=r" (temp)
+ :
+ : "memory");
+}
+
+
+/*
+ * disable IRQ/FIQ interrupts
+ * returns true if interrupts had been enabled before we disabled them
+ */
+int disable_interrupts(void)
+{
+ unsigned long old, temp;
+ __asm__ __volatile__("mrs %0, cpsr\n"
+ "orr %1, %0, #0xc0\n"
+ "msr cpsr_c, %1"
+ : "=r" (old), "=r" (temp)
+ :
+ : "memory");
+ return (old & 0x80) == 0;
+}
+#else
+void enable_interrupts(void)
+{
+ return;
+}
+int disable_interrupts(void)
+{
+ return 0;
+}
+#endif
+
+
+void bad_mode(void)
+{
+ panic("Resetting CPU ...\n");
+ reset_cpu(0);
+}
+
+void show_regs(struct pt_regs *regs)
+{
+ unsigned long flags;
+ const char *processor_modes[] = {
+ "USER_26", "FIQ_26", "IRQ_26", "SVC_26",
+ "UK4_26", "UK5_26", "UK6_26", "UK7_26",
+ "UK8_26", "UK9_26", "UK10_26", "UK11_26",
+ "UK12_26", "UK13_26", "UK14_26", "UK15_26",
+ "USER_32", "FIQ_32", "IRQ_32", "SVC_32",
+ "UK4_32", "UK5_32", "UK6_32", "ABT_32",
+ "UK8_32", "UK9_32", "UK10_32", "UND_32",
+ "UK12_32", "UK13_32", "UK14_32", "SYS_32",
+ };
+
+ flags = condition_codes(regs);
+
+ printf("pc : [<%08lx>] lr : [<%08lx>]\n"
+ "sp : %08lx ip : %08lx fp : %08lx\n",
+ instruction_pointer(regs),
+ regs->ARM_lr, regs->ARM_sp, regs->ARM_ip, regs->ARM_fp);
+ printf("r10: %08lx r9 : %08lx r8 : %08lx\n",
+ regs->ARM_r10, regs->ARM_r9, regs->ARM_r8);
+ printf("r7 : %08lx r6 : %08lx r5 : %08lx r4 : %08lx\n",
+ regs->ARM_r7, regs->ARM_r6, regs->ARM_r5, regs->ARM_r4);
+ printf("r3 : %08lx r2 : %08lx r1 : %08lx r0 : %08lx\n",
+ regs->ARM_r3, regs->ARM_r2, regs->ARM_r1, regs->ARM_r0);
+ printf("Flags: %c%c%c%c",
+ flags & CC_N_BIT ? 'N' : 'n',
+ flags & CC_Z_BIT ? 'Z' : 'z',
+ flags & CC_C_BIT ? 'C' : 'c', flags & CC_V_BIT ? 'V' : 'v');
+ printf(" IRQs %s FIQs %s Mode %s%s\n",
+ interrupts_enabled(regs) ? "on" : "off",
+ fast_interrupts_enabled(regs) ? "on" : "off",
+ processor_modes[processor_mode(regs)],
+ thumb_mode(regs) ? " (T)" : "");
+}
+
+void do_undefined_instruction(struct pt_regs *pt_regs)
+{
+ printf("undefined instruction\n");
+ show_regs(pt_regs);
+ bad_mode();
+}
+
+void do_software_interrupt(struct pt_regs *pt_regs)
+{
+ printf("software interrupt\n");
+ show_regs(pt_regs);
+ bad_mode();
+}
+
+void do_prefetch_abort(struct pt_regs *pt_regs)
+{
+ printf("prefetch abort\n");
+ show_regs(pt_regs);
+ bad_mode();
+}
+
+void do_data_abort(struct pt_regs *pt_regs)
+{
+ printf("data abort\n");
+ show_regs(pt_regs);
+ bad_mode();
+}
+
+void do_not_used(struct pt_regs *pt_regs)
+{
+ printf("not used\n");
+ show_regs(pt_regs);
+ bad_mode();
+}
+
+void do_fiq(struct pt_regs *pt_regs)
+{
+ printf("fast interrupt request\n");
+ show_regs(pt_regs);
+ bad_mode();
+}
+
+void do_irq(struct pt_regs *pt_regs)
+{
+#if defined(CONFIG_USE_IRQ) && defined(CONFIG_ARCH_INTEGRATOR)
+ /* ASSUMED to be a timer interrupt */
+ /* Just clear it - count handled in */
+ /* integratorap.c */
+ *(volatile ulong*)(CFG_TIMERBASE + 0x0C) = 0;
+#else
+ printf("interrupt request\n");
+ show_regs(pt_regs);
+ bad_mode();
+#endif
+}
diff --git a/cpu/arm920t/at91rm9200/arm920t/start.S b/cpu/arm920t/at91rm9200/arm920t/start.S
new file mode 100755
index 0000000..66c12bf
--- /dev/null
+++ b/cpu/arm920t/at91rm9200/arm920t/start.S
@@ -0,0 +1,441 @@
+/*
+ * armboot - Startup Code for ARM920 CPU-core
+ *
+ * Copyright (c) 2001 Marius Gröger <mag@sysgo.de>
+ * Copyright (c) 2002 Alex Züpke <azu@sysgo.de>
+ * Copyright (c) 2002 Gary Jennejohn <gj@denx.de>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * Copyright (c) 2008 WonderMedia Technologies, Inc.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ *
+ * WonderMedia Technologies, Inc.
+ * 10F, 529, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C.
+ */
+
+
+#include <config.h>
+#include <version.h>
+
+
+/*
+ *************************************************************************
+ *
+ * Jump vector table as in table 3.1 in [1]
+ *
+ *************************************************************************
+ */
+
+
+.globl _start
+_start: b reset
+ ldr pc, _undefined_instruction
+ ldr pc, _software_interrupt
+ ldr pc, _prefetch_abort
+ ldr pc, _data_abort
+ ldr pc, _not_used
+ ldr pc, _irq
+ ldr pc, _fiq
+
+_undefined_instruction: .word undefined_instruction
+_software_interrupt: .word software_interrupt
+_prefetch_abort: .word prefetch_abort
+_data_abort: .word data_abort
+_not_used: .word not_used
+_irq: .word irq
+_fiq: .word fiq
+
+ .balignl 16,0xdeadbeef
+
+
+/*
+ *************************************************************************
+ *
+ * Startup Code (reset vector)
+ *
+ * do important init only if we don't start from memory!
+ * relocate armboot to ram
+ * setup stack
+ * jump to second stage
+ *
+ *************************************************************************
+ */
+
+_TEXT_BASE:
+ .word TEXT_BASE
+
+.globl _armboot_start
+_armboot_start:
+ .word _start
+
+/*
+ * These are defined in the board-specific linker script.
+ */
+.globl _bss_start
+_bss_start:
+ .word __bss_start
+
+.globl _bss_end
+_bss_end:
+ .word _end
+
+#ifdef CONFIG_USE_IRQ
+/* IRQ stack memory (calculated at run-time) */
+.globl IRQ_STACK_START
+IRQ_STACK_START:
+ .word 0x0badc0de
+
+/* IRQ stack memory (calculated at run-time) */
+.globl FIQ_STACK_START
+FIQ_STACK_START:
+ .word 0x0badc0de
+#endif
+
+
+/*
+ * the actual reset code
+ */
+
+reset:
+ /*
+ * set the cpu to SVC32 mode
+ */
+ mrs r0,cpsr
+ bic r0,r0,#0x1f
+ orr r0,r0,#0xd3
+ msr cpsr,r0
+
+/* turn off the watchdog */
+#if defined(CONFIG_S3C2400)
+# define pWTCON 0x15300000
+# define INTMSK 0x14400008 /* Interupt-Controller base addresses */
+# define CLKDIVN 0x14800014 /* clock divisor register */
+#elif defined(CONFIG_S3C2410)
+# define pWTCON 0x53000000
+# define INTMSK 0x4A000008 /* Interupt-Controller base addresses */
+# define INTSUBMSK 0x4A00001C
+# define CLKDIVN 0x4C000014 /* clock divisor register */
+#endif
+
+#if defined(CONFIG_S3C2400) || defined(CONFIG_S3C2410)
+ ldr r0, =pWTCON
+ mov r1, #0x0
+ str r1, [r0]
+
+ /*
+ * mask all IRQs by setting all bits in the INTMR - default
+ */
+ mov r1, #0xffffffff
+ ldr r0, =INTMSK
+ str r1, [r0]
+# if defined(CONFIG_S3C2410)
+ ldr r1, =0x3ff
+ ldr r0, =INTSUBMSK
+ str r1, [r0]
+# endif
+
+ /* FCLK:HCLK:PCLK = 1:2:4 */
+ /* default FCLK is 120 MHz ! */
+ ldr r0, =CLKDIVN
+ mov r1, #3
+ str r1, [r0]
+#endif /* CONFIG_S3C2400 || CONFIG_S3C2410 */
+
+ /*
+ * we do sys-critical inits only at reboot,
+ * not when booting from ram!
+ */
+#ifndef CONFIG_SKIP_LOWLEVEL_INIT
+ bl cpu_init_crit
+#endif
+
+#ifndef CONFIG_SKIP_RELOCATE_UBOOT
+relocate: /* relocate U-Boot to RAM */
+ adr r0, _start /* r0 <- current position of code */
+ ldr r1, _TEXT_BASE /* test if we run from flash or RAM */
+ cmp r0, r1 /* don't reloc during debug */
+ beq stack_setup
+
+ ldr r2, _armboot_start
+ ldr r3, _bss_start
+ sub r2, r3, r2 /* r2 <- size of armboot */
+ add r2, r0, r2 /* r2 <- source end address */
+
+copy_loop:
+ ldmia r0!, {r3-r10} /* copy from source address [r0] */
+ stmia r1!, {r3-r10} /* copy to target address [r1] */
+ cmp r0, r2 /* until source end addreee [r2] */
+ ble copy_loop
+#endif /* CONFIG_SKIP_RELOCATE_UBOOT */
+
+ /* Set up the stack */
+stack_setup:
+ ldr r0, _TEXT_BASE /* upper 128 KiB: relocated uboot */
+ sub r0, r0, #CFG_MALLOC_LEN /* malloc area */
+ sub r0, r0, #CFG_GBL_DATA_SIZE /* bdinfo */
+#ifdef CONFIG_USE_IRQ
+ sub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ)
+#endif
+ sub sp, r0, #12 /* leave 3 words for abort-stack */
+
+clear_bss:
+ ldr r0, _bss_start /* find start of bss segment */
+ ldr r1, _bss_end /* stop here */
+ mov r2, #0x00000000 /* clear */
+
+clbss_l:str r2, [r0] /* clear loop... */
+ add r0, r0, #4
+ cmp r0, r1
+ ble clbss_l
+
+#if 0
+ /* try doing this stuff after the relocation */
+ ldr r0, =pWTCON
+ mov r1, #0x0
+ str r1, [r0]
+
+ /*
+ * mask all IRQs by setting all bits in the INTMR - default
+ */
+ mov r1, #0xffffffff
+ ldr r0, =INTMR
+ str r1, [r0]
+
+ /* FCLK:HCLK:PCLK = 1:2:4 */
+ /* default FCLK is 120 MHz ! */
+ ldr r0, =CLKDIVN
+ mov r1, #3
+ str r1, [r0]
+ /* END stuff after relocation */
+#endif
+
+ ldr pc, _start_armboot
+
+_start_armboot: .word start_armboot
+
+
+/*
+ *************************************************************************
+ *
+ * CPU_init_critical registers
+ *
+ * setup important registers
+ * setup memory timing
+ *
+ *************************************************************************
+ */
+
+
+cpu_init_crit:
+
+ /*
+ * flush v4 I/D caches
+ */
+ mov r0, #0
+ mcr p15, 0, r0, c7, c7, 0 /* flush v3/v4 cache */
+ mcr p15, 0, r0, c8, c7, 0 /* flush v4 TLB */
+
+ /*
+ * disable MMU stuff and caches
+ */
+ mrc p15, 0, r0, c1, c0, 0
+
+#if defined (CONFIG_WMT)
+ bic r0, r0, #0x00000300 @ clear bits 9:8 (---- --RS)
+ bic r0, r0, #0x0000000F @ clear bits 3:0 (---- WCAM)
+ orr r0, r0, #0x00002000 @ set bit 13 (--V--)
+#else
+ bic r0, r0, #0x00002300 @ clear bits 13, 9:8 (--V- --RS)
+ bic r0, r0, #0x00000087 @ clear bits 7, 2:0 (B--- -CAM)
+#endif
+ orr r0, r0, #0x00000002 @ set bit 2 (A) Align
+ orr r0, r0, #0x00001000 @ set bit 12 (I) I-Cache
+ mcr p15, 0, r0, c1, c0, 0
+
+ /*
+ * before relocating, we have to setup RAM timing
+ * because memory timing is board-dependend, you will
+ * find a lowlevel_init.S in your board directory.
+ */
+ mov ip, lr
+ bl lowlevel_init
+ mov lr, ip
+ mov pc, lr
+
+
+/*
+ *************************************************************************
+ *
+ * Interrupt handling
+ *
+ *************************************************************************
+ */
+
+@
+@ IRQ stack frame.
+@
+#define S_FRAME_SIZE 72
+
+#define S_OLD_R0 68
+#define S_PSR 64
+#define S_PC 60
+#define S_LR 56
+#define S_SP 52
+
+#define S_IP 48
+#define S_FP 44
+#define S_R10 40
+#define S_R9 36
+#define S_R8 32
+#define S_R7 28
+#define S_R6 24
+#define S_R5 20
+#define S_R4 16
+#define S_R3 12
+#define S_R2 8
+#define S_R1 4
+#define S_R0 0
+
+#define MODE_SVC 0x13
+#define I_BIT 0x80
+
+/*
+ * use bad_save_user_regs for abort/prefetch/undef/swi ...
+ * use irq_save_user_regs / irq_restore_user_regs for IRQ/FIQ handling
+ */
+
+ .macro bad_save_user_regs
+ sub sp, sp, #S_FRAME_SIZE
+ stmia sp, {r0 - r12} @ Calling r0-r12
+ ldr r2, _armboot_start
+ sub r2, r2, #(CONFIG_STACKSIZE+CFG_MALLOC_LEN)
+ sub r2, r2, #(CFG_GBL_DATA_SIZE+8) @ set base 2 words into abort stack
+ ldmia r2, {r2 - r3} @ get pc, cpsr
+ add r0, sp, #S_FRAME_SIZE @ restore sp_SVC
+
+ add r5, sp, #S_SP
+ mov r1, lr
+ stmia r5, {r0 - r3} @ save sp_SVC, lr_SVC, pc, cpsr
+ mov r0, sp
+ .endm
+
+ .macro irq_save_user_regs
+ sub sp, sp, #S_FRAME_SIZE
+ stmia sp, {r0 - r12} @ Calling r0-r12
+ add r8, sp, #S_PC
+ stmdb r8, {sp, lr}^ @ Calling SP, LR
+ str lr, [r8, #0] @ Save calling PC
+ mrs r6, spsr
+ str r6, [r8, #4] @ Save CPSR
+ str r0, [r8, #8] @ Save OLD_R0
+ mov r0, sp
+ .endm
+
+ .macro irq_restore_user_regs
+ ldmia sp, {r0 - lr}^ @ Calling r0 - lr
+ mov r0, r0
+ ldr lr, [sp, #S_PC] @ Get PC
+ add sp, sp, #S_FRAME_SIZE
+ subs pc, lr, #4 @ return & move spsr_svc into cpsr
+ .endm
+
+ .macro get_bad_stack
+ ldr r13, _armboot_start @ setup our mode stack
+ sub r13, r13, #(CONFIG_STACKSIZE+CFG_MALLOC_LEN)
+ sub r13, r13, #(CFG_GBL_DATA_SIZE+8) @ reserved a couple spots in abort stack
+
+ str lr, [r13] @ save caller lr / spsr
+ mrs lr, spsr
+ str lr, [r13, #4]
+
+ mov r13, #MODE_SVC @ prepare SVC-Mode
+ @ msr spsr_c, r13
+ msr spsr, r13
+ mov lr, pc
+ movs pc, lr
+ .endm
+
+ .macro get_irq_stack @ setup IRQ stack
+ ldr sp, IRQ_STACK_START
+ .endm
+
+ .macro get_fiq_stack @ setup FIQ stack
+ ldr sp, FIQ_STACK_START
+ .endm
+
+/*
+ * exception handlers
+ */
+ .align 5
+undefined_instruction:
+ get_bad_stack
+ bad_save_user_regs
+ bl do_undefined_instruction
+
+ .align 5
+software_interrupt:
+ get_bad_stack
+ bad_save_user_regs
+ bl do_software_interrupt
+
+ .align 5
+prefetch_abort:
+ get_bad_stack
+ bad_save_user_regs
+ bl do_prefetch_abort
+
+ .align 5
+data_abort:
+ get_bad_stack
+ bad_save_user_regs
+ bl do_data_abort
+
+ .align 5
+not_used:
+ get_bad_stack
+ bad_save_user_regs
+ bl do_not_used
+
+#ifdef CONFIG_USE_IRQ
+
+ .align 5
+irq:
+ get_irq_stack
+ irq_save_user_regs
+ bl do_irq
+ irq_restore_user_regs
+
+ .align 5
+fiq:
+ get_fiq_stack
+ /* someone ought to write a more effiction fiq_save_user_regs */
+ irq_save_user_regs
+ bl do_fiq
+ irq_restore_user_regs
+
+#else
+
+ .align 5
+irq:
+ get_bad_stack
+ bad_save_user_regs
+ bl do_irq
+
+ .align 5
+fiq:
+ get_bad_stack
+ bad_save_user_regs
+ bl do_fiq
+
+#endif
diff --git a/cpu/arm920t/at91rm9200/bcm5221.c b/cpu/arm920t/at91rm9200/bcm5221.c
new file mode 100755
index 0000000..6db1435
--- /dev/null
+++ b/cpu/arm920t/at91rm9200/bcm5221.c
@@ -0,0 +1,232 @@
+/*
+ * Broadcom BCM5221 Ethernet PHY
+ *
+ * (C) Copyright 2005 REA Elektronik GmbH <www.rea.de>
+ * Anders Larsen <alarsen@rea.de>
+ *
+ * (C) Copyright 2003
+ * Author : Hamid Ikdoumi (Atmel)
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <at91rm9200_net.h>
+#include <net.h>
+#include <bcm5221.h>
+
+#ifdef CONFIG_DRIVER_ETHER
+
+#if (CONFIG_COMMANDS & CFG_CMD_NET)
+
+/*
+ * Name:
+ * bcm5221_IsPhyConnected
+ * Description:
+ * Reads the 2 PHY ID registers
+ * Arguments:
+ * p_mac - pointer to AT91S_EMAC struct
+ * Return value:
+ * TRUE - if id read successfully
+ * FALSE- if error
+ */
+unsigned int bcm5221_IsPhyConnected (AT91PS_EMAC p_mac)
+{
+ unsigned short Id1, Id2;
+
+ at91rm9200_EmacEnableMDIO (p_mac);
+ at91rm9200_EmacReadPhy (p_mac, BCM5221_PHYID1, &Id1);
+ at91rm9200_EmacReadPhy (p_mac, BCM5221_PHYID2, &Id2);
+ at91rm9200_EmacDisableMDIO (p_mac);
+
+ if ((Id1 == (BCM5221_PHYID1_OUI >> 6)) &&
+ ((Id2 >> 10) == (BCM5221_PHYID1_OUI & BCM5221_LSB_MASK)))
+ return TRUE;
+
+ return FALSE;
+}
+
+/*
+ * Name:
+ * bcm5221_GetLinkSpeed
+ * Description:
+ * Link parallel detection status of MAC is checked and set in the
+ * MAC configuration registers
+ * Arguments:
+ * p_mac - pointer to MAC
+ * Return value:
+ * TRUE - if link status set succesfully
+ * FALSE - if link status not set
+ */
+unsigned char bcm5221_GetLinkSpeed (AT91PS_EMAC p_mac)
+{
+ unsigned short stat1, stat2;
+
+ if (!at91rm9200_EmacReadPhy (p_mac, BCM5221_BMSR, &stat1))
+ return FALSE;
+
+ if (!(stat1 & BCM5221_LINK_STATUS)) /* link status up? */
+ return FALSE;
+
+ if (!at91rm9200_EmacReadPhy (p_mac, BCM5221_ACSR, &stat2))
+ return FALSE;
+
+ if ((stat1 & BCM5221_100BASE_TX_FD) && (stat2 & BCM5221_100) && (stat2 & BCM5221_FDX)) {
+ /*set Emac for 100BaseTX and Full Duplex */
+ p_mac->EMAC_CFG |= AT91C_EMAC_SPD | AT91C_EMAC_FD;
+ return TRUE;
+ }
+
+ if ((stat1 & BCM5221_10BASE_T_FD) && !(stat2 & BCM5221_100) && (stat2 & BCM5221_FDX)) {
+ /*set MII for 10BaseT and Full Duplex */
+ p_mac->EMAC_CFG = (p_mac->EMAC_CFG &
+ ~(AT91C_EMAC_SPD | AT91C_EMAC_FD))
+ | AT91C_EMAC_FD;
+ return TRUE;
+ }
+
+ if ((stat1 & BCM5221_100BASE_TX_HD) && (stat2 & BCM5221_100) && !(stat2 & BCM5221_FDX)) {
+ /*set MII for 100BaseTX and Half Duplex */
+ p_mac->EMAC_CFG = (p_mac->EMAC_CFG &
+ ~(AT91C_EMAC_SPD | AT91C_EMAC_FD))
+ | AT91C_EMAC_SPD;
+ return TRUE;
+ }
+
+ if ((stat1 & BCM5221_10BASE_T_HD) && !(stat2 & BCM5221_100) && !(stat2 & BCM5221_FDX)) {
+ /*set MII for 10BaseT and Half Duplex */
+ p_mac->EMAC_CFG &= ~(AT91C_EMAC_SPD | AT91C_EMAC_FD);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
+/*
+ * Name:
+ * bcm5221_InitPhy
+ * Description:
+ * MAC starts checking its link by using parallel detection and
+ * Autonegotiation and the same is set in the MAC configuration registers
+ * Arguments:
+ * p_mac - pointer to struct AT91S_EMAC
+ * Return value:
+ * TRUE - if link status set succesfully
+ * FALSE - if link status not set
+ */
+unsigned char bcm5221_InitPhy (AT91PS_EMAC p_mac)
+{
+ unsigned char ret = TRUE;
+ unsigned short IntValue;
+
+ at91rm9200_EmacEnableMDIO (p_mac);
+
+ if (!bcm5221_GetLinkSpeed (p_mac)) {
+ /* Try another time */
+ ret = bcm5221_GetLinkSpeed (p_mac);
+ }
+
+ /* Disable PHY Interrupts */
+ at91rm9200_EmacReadPhy (p_mac, BCM5221_INTR, &IntValue);
+ /* clear FDX LED and INTR Enable */
+ IntValue &= ~(BCM5221_FDX_LED | BCM5221_INTR_ENABLE);
+ /* set FDX, SPD, Link, INTR masks */
+ IntValue |= (BCM5221_FDX_MASK | BCM5221_SPD_MASK |
+ BCM5221_LINK_MASK | BCM5221_INTR_MASK);
+ at91rm9200_EmacWritePhy (p_mac, BCM5221_INTR, &IntValue);
+ at91rm9200_EmacDisableMDIO (p_mac);
+
+ return (ret);
+}
+
+
+/*
+ * Name:
+ * bcm5221_AutoNegotiate
+ * Description:
+ * MAC Autonegotiates with the partner status of same is set in the
+ * MAC configuration registers
+ * Arguments:
+ * dev - pointer to struct net_device
+ * Return value:
+ * TRUE - if link status set successfully
+ * FALSE - if link status not set
+ */
+unsigned char bcm5221_AutoNegotiate (AT91PS_EMAC p_mac, int *status)
+{
+ unsigned short value;
+ unsigned short PhyAnar;
+ unsigned short PhyAnalpar;
+
+ /* Set bcm5221 control register */
+ if (!at91rm9200_EmacReadPhy (p_mac, BCM5221_BMCR, &value))
+ return FALSE;
+ value &= ~BCM5221_AUTONEG; /* remove autonegotiation enable */
+ value |= BCM5221_ISOLATE; /* Electrically isolate PHY */
+ if (!at91rm9200_EmacWritePhy (p_mac, BCM5221_BMCR, &value))
+ return FALSE;
+
+ /* Set the Auto_negotiation Advertisement Register */
+ /* MII advertising for 100BaseTxFD and HD, 10BaseTFD and HD, IEEE 802.3 */
+ PhyAnar = BCM5221_TX_FDX | BCM5221_TX_HDX |
+ BCM5221_10_FDX | BCM5221_10_HDX | BCM5221_AN_IEEE_802_3;
+ if (!at91rm9200_EmacWritePhy (p_mac, BCM5221_ANAR, &PhyAnar))
+ return FALSE;
+
+ /* Read the Control Register */
+ if (!at91rm9200_EmacReadPhy (p_mac, BCM5221_BMCR, &value))
+ return FALSE;
+
+ value |= BCM5221_SPEED_SELECT | BCM5221_AUTONEG | BCM5221_DUPLEX_MODE;
+ if (!at91rm9200_EmacWritePhy (p_mac, BCM5221_BMCR, &value))
+ return FALSE;
+ /* Restart Auto_negotiation */
+ value |= BCM5221_RESTART_AUTONEG;
+ value &= ~BCM5221_ISOLATE;
+ if (!at91rm9200_EmacWritePhy (p_mac, BCM5221_BMCR, &value))
+ return FALSE;
+
+ /*check AutoNegotiate complete */
+ udelay (10000);
+ at91rm9200_EmacReadPhy (p_mac, BCM5221_BMSR, &value);
+ if (!(value & BCM5221_AUTONEG_COMP))
+ return FALSE;
+
+ /* Get the AutoNeg Link partner base page */
+ if (!at91rm9200_EmacReadPhy (p_mac, BCM5221_ANLPAR, &PhyAnalpar))
+ return FALSE;
+
+ if ((PhyAnar & BCM5221_TX_FDX) && (PhyAnalpar & BCM5221_TX_FDX)) {
+ /*set MII for 100BaseTX and Full Duplex */
+ p_mac->EMAC_CFG |= AT91C_EMAC_SPD | AT91C_EMAC_FD;
+ return TRUE;
+ }
+
+ if ((PhyAnar & BCM5221_10_FDX) && (PhyAnalpar & BCM5221_10_FDX)) {
+ /*set MII for 10BaseT and Full Duplex */
+ p_mac->EMAC_CFG = (p_mac->EMAC_CFG &
+ ~(AT91C_EMAC_SPD | AT91C_EMAC_FD))
+ | AT91C_EMAC_FD;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+#endif /* CONFIG_COMMANDS & CFG_CMD_NET */
+
+#endif /* CONFIG_DRIVER_ETHER */
diff --git a/cpu/arm920t/at91rm9200/dm9161.c b/cpu/arm920t/at91rm9200/dm9161.c
new file mode 100755
index 0000000..4b13c23
--- /dev/null
+++ b/cpu/arm920t/at91rm9200/dm9161.c
@@ -0,0 +1,225 @@
+/*
+ * (C) Copyright 2003
+ * Author : Hamid Ikdoumi (Atmel)
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <at91rm9200_net.h>
+#include <net.h>
+#include <dm9161.h>
+
+#ifdef CONFIG_DRIVER_ETHER
+
+#if (CONFIG_COMMANDS & CFG_CMD_NET)
+
+/*
+ * Name:
+ * dm9161_IsPhyConnected
+ * Description:
+ * Reads the 2 PHY ID registers
+ * Arguments:
+ * p_mac - pointer to AT91S_EMAC struct
+ * Return value:
+ * TRUE - if id read successfully
+ * FALSE- if error
+ */
+unsigned int dm9161_IsPhyConnected (AT91PS_EMAC p_mac)
+{
+ unsigned short Id1, Id2;
+
+ at91rm9200_EmacEnableMDIO (p_mac);
+ at91rm9200_EmacReadPhy (p_mac, DM9161_PHYID1, &Id1);
+ at91rm9200_EmacReadPhy (p_mac, DM9161_PHYID2, &Id2);
+ at91rm9200_EmacDisableMDIO (p_mac);
+
+ if ((Id1 == (DM9161_PHYID1_OUI >> 6)) &&
+ ((Id2 >> 10) == (DM9161_PHYID1_OUI & DM9161_LSB_MASK)))
+ return TRUE;
+
+ return FALSE;
+}
+
+/*
+ * Name:
+ * dm9161_GetLinkSpeed
+ * Description:
+ * Link parallel detection status of MAC is checked and set in the
+ * MAC configuration registers
+ * Arguments:
+ * p_mac - pointer to MAC
+ * Return value:
+ * TRUE - if link status set succesfully
+ * FALSE - if link status not set
+ */
+UCHAR dm9161_GetLinkSpeed (AT91PS_EMAC p_mac)
+{
+ unsigned short stat1, stat2;
+
+ if (!at91rm9200_EmacReadPhy (p_mac, DM9161_BMSR, &stat1))
+ return FALSE;
+
+ if (!(stat1 & DM9161_LINK_STATUS)) /* link status up? */
+ return FALSE;
+
+ if (!at91rm9200_EmacReadPhy (p_mac, DM9161_DSCSR, &stat2))
+ return FALSE;
+
+ if ((stat1 & DM9161_100BASE_TX_FD) && (stat2 & DM9161_100FDX)) {
+ /*set Emac for 100BaseTX and Full Duplex */
+ p_mac->EMAC_CFG |= AT91C_EMAC_SPD | AT91C_EMAC_FD;
+ return TRUE;
+ }
+
+ if ((stat1 & DM9161_10BASE_T_FD) && (stat2 & DM9161_10FDX)) {
+ /*set MII for 10BaseT and Full Duplex */
+ p_mac->EMAC_CFG = (p_mac->EMAC_CFG &
+ ~(AT91C_EMAC_SPD | AT91C_EMAC_FD))
+ | AT91C_EMAC_FD;
+ return TRUE;
+ }
+
+ if ((stat1 & DM9161_100BASE_T4_HD) && (stat2 & DM9161_100HDX)) {
+ /*set MII for 100BaseTX and Half Duplex */
+ p_mac->EMAC_CFG = (p_mac->EMAC_CFG &
+ ~(AT91C_EMAC_SPD | AT91C_EMAC_FD))
+ | AT91C_EMAC_SPD;
+ return TRUE;
+ }
+
+ if ((stat1 & DM9161_10BASE_T_HD) && (stat2 & DM9161_10HDX)) {
+ /*set MII for 10BaseT and Half Duplex */
+ p_mac->EMAC_CFG &= ~(AT91C_EMAC_SPD | AT91C_EMAC_FD);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
+/*
+ * Name:
+ * dm9161_InitPhy
+ * Description:
+ * MAC starts checking its link by using parallel detection and
+ * Autonegotiation and the same is set in the MAC configuration registers
+ * Arguments:
+ * p_mac - pointer to struct AT91S_EMAC
+ * Return value:
+ * TRUE - if link status set succesfully
+ * FALSE - if link status not set
+ */
+UCHAR dm9161_InitPhy (AT91PS_EMAC p_mac)
+{
+ UCHAR ret = TRUE;
+ unsigned short IntValue;
+
+ at91rm9200_EmacEnableMDIO (p_mac);
+
+ if (!dm9161_GetLinkSpeed (p_mac)) {
+ /* Try another time */
+ ret = dm9161_GetLinkSpeed (p_mac);
+ }
+
+ /* Disable PHY Interrupts */
+ at91rm9200_EmacReadPhy (p_mac, DM9161_MDINTR, &IntValue);
+ /* set FDX, SPD, Link, INTR masks */
+ IntValue |= (DM9161_FDX_MASK | DM9161_SPD_MASK |
+ DM9161_LINK_MASK | DM9161_INTR_MASK);
+ at91rm9200_EmacWritePhy (p_mac, DM9161_MDINTR, &IntValue);
+ at91rm9200_EmacDisableMDIO (p_mac);
+
+ return (ret);
+}
+
+
+/*
+ * Name:
+ * dm9161_AutoNegotiate
+ * Description:
+ * MAC Autonegotiates with the partner status of same is set in the
+ * MAC configuration registers
+ * Arguments:
+ * dev - pointer to struct net_device
+ * Return value:
+ * TRUE - if link status set successfully
+ * FALSE - if link status not set
+ */
+UCHAR dm9161_AutoNegotiate (AT91PS_EMAC p_mac, int *status)
+{
+ unsigned short value;
+ unsigned short PhyAnar;
+ unsigned short PhyAnalpar;
+
+ /* Set dm9161 control register */
+ if (!at91rm9200_EmacReadPhy (p_mac, DM9161_BMCR, &value))
+ return FALSE;
+ value &= ~DM9161_AUTONEG; /* remove autonegotiation enable */
+ value |= DM9161_ISOLATE; /* Electrically isolate PHY */
+ if (!at91rm9200_EmacWritePhy (p_mac, DM9161_BMCR, &value))
+ return FALSE;
+
+ /* Set the Auto_negotiation Advertisement Register */
+ /* MII advertising for Next page, 100BaseTxFD and HD, 10BaseTFD and HD, IEEE 802.3 */
+ PhyAnar = DM9161_NP | DM9161_TX_FDX | DM9161_TX_HDX |
+ DM9161_10_FDX | DM9161_10_HDX | DM9161_AN_IEEE_802_3;
+ if (!at91rm9200_EmacWritePhy (p_mac, DM9161_ANAR, &PhyAnar))
+ return FALSE;
+
+ /* Read the Control Register */
+ if (!at91rm9200_EmacReadPhy (p_mac, DM9161_BMCR, &value))
+ return FALSE;
+
+ value |= DM9161_SPEED_SELECT | DM9161_AUTONEG | DM9161_DUPLEX_MODE;
+ if (!at91rm9200_EmacWritePhy (p_mac, DM9161_BMCR, &value))
+ return FALSE;
+ /* Restart Auto_negotiation */
+ value |= DM9161_RESTART_AUTONEG;
+ value &= ~DM9161_ISOLATE;
+ if (!at91rm9200_EmacWritePhy (p_mac, DM9161_BMCR, &value))
+ return FALSE;
+
+ /*check AutoNegotiate complete */
+ udelay (10000);
+ at91rm9200_EmacReadPhy (p_mac, DM9161_BMSR, &value);
+ if (!(value & DM9161_AUTONEG_COMP))
+ return FALSE;
+
+ /* Get the AutoNeg Link partner base page */
+ if (!at91rm9200_EmacReadPhy (p_mac, DM9161_ANLPAR, &PhyAnalpar))
+ return FALSE;
+
+ if ((PhyAnar & DM9161_TX_FDX) && (PhyAnalpar & DM9161_TX_FDX)) {
+ /*set MII for 100BaseTX and Full Duplex */
+ p_mac->EMAC_CFG |= AT91C_EMAC_SPD | AT91C_EMAC_FD;
+ return TRUE;
+ }
+
+ if ((PhyAnar & DM9161_10_FDX) && (PhyAnalpar & DM9161_10_FDX)) {
+ /*set MII for 10BaseT and Full Duplex */
+ p_mac->EMAC_CFG = (p_mac->EMAC_CFG &
+ ~(AT91C_EMAC_SPD | AT91C_EMAC_FD))
+ | AT91C_EMAC_FD;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+#endif /* CONFIG_COMMANDS & CFG_CMD_NET */
+
+#endif /* CONFIG_DRIVER_ETHER */
diff --git a/cpu/arm920t/at91rm9200/ether.c b/cpu/arm920t/at91rm9200/ether.c
new file mode 100755
index 0000000..67008d0
--- /dev/null
+++ b/cpu/arm920t/at91rm9200/ether.c
@@ -0,0 +1,299 @@
+/*
+ * (C) Copyright 2003
+ * Author : Hamid Ikdoumi (Atmel)
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <at91rm9200_net.h>
+#include <net.h>
+#include <miiphy.h>
+
+/* ----- Ethernet Buffer definitions ----- */
+
+typedef struct {
+ unsigned long addr, size;
+} rbf_t;
+
+#define RBF_ADDR 0xfffffffc
+#define RBF_OWNER (1<<0)
+#define RBF_WRAP (1<<1)
+#define RBF_BROADCAST (1<<31)
+#define RBF_MULTICAST (1<<30)
+#define RBF_UNICAST (1<<29)
+#define RBF_EXTERNAL (1<<28)
+#define RBF_UNKOWN (1<<27)
+#define RBF_SIZE 0x07ff
+#define RBF_LOCAL4 (1<<26)
+#define RBF_LOCAL3 (1<<25)
+#define RBF_LOCAL2 (1<<24)
+#define RBF_LOCAL1 (1<<23)
+
+#define RBF_FRAMEMAX 64
+#define RBF_FRAMELEN 0x600
+
+#ifdef CONFIG_DRIVER_ETHER
+
+#if (CONFIG_COMMANDS & CFG_CMD_NET)
+
+/* alignment as per Errata #11 (64 bytes) is insufficient! */
+rbf_t rbfdt[RBF_FRAMEMAX] __attribute((aligned(512)));
+rbf_t *rbfp;
+
+unsigned char rbf_framebuf[RBF_FRAMEMAX][RBF_FRAMELEN] __attribute((aligned(4)));
+
+/* structure to interface the PHY */
+AT91S_PhyOps PhyOps;
+
+AT91PS_EMAC p_mac;
+
+/*********** EMAC Phy layer Management functions *************************/
+/*
+ * Name:
+ * at91rm9200_EmacEnableMDIO
+ * Description:
+ * Enables the MDIO bit in MAC control register
+ * Arguments:
+ * p_mac - pointer to struct AT91S_EMAC
+ * Return value:
+ * none
+ */
+void at91rm9200_EmacEnableMDIO (AT91PS_EMAC p_mac)
+{
+ /* Mac CTRL reg set for MDIO enable */
+ p_mac->EMAC_CTL |= AT91C_EMAC_MPE; /* Management port enable */
+}
+
+/*
+ * Name:
+ * at91rm9200_EmacDisableMDIO
+ * Description:
+ * Disables the MDIO bit in MAC control register
+ * Arguments:
+ * p_mac - pointer to struct AT91S_EMAC
+ * Return value:
+ * none
+ */
+void at91rm9200_EmacDisableMDIO (AT91PS_EMAC p_mac)
+{
+ /* Mac CTRL reg set for MDIO disable */
+ p_mac->EMAC_CTL &= ~AT91C_EMAC_MPE; /* Management port disable */
+}
+
+
+/*
+ * Name:
+ * at91rm9200_EmacReadPhy
+ * Description:
+ * Reads data from the PHY register
+ * Arguments:
+ * dev - pointer to struct net_device
+ * RegisterAddress - unsigned char
+ * pInput - pointer to value read from register
+ * Return value:
+ * TRUE - if data read successfully
+ */
+UCHAR at91rm9200_EmacReadPhy (AT91PS_EMAC p_mac,
+ unsigned char RegisterAddress,
+ unsigned short *pInput)
+{
+ p_mac->EMAC_MAN = (AT91C_EMAC_HIGH & ~AT91C_EMAC_LOW) |
+ (AT91C_EMAC_RW_R) |
+ (RegisterAddress << 18) |
+ (AT91C_EMAC_CODE_802_3);
+
+ udelay (10000);
+
+ *pInput = (unsigned short) p_mac->EMAC_MAN;
+
+ return TRUE;
+}
+
+
+/*
+ * Name:
+ * at91rm9200_EmacWritePhy
+ * Description:
+ * Writes data to the PHY register
+ * Arguments:
+ * dev - pointer to struct net_device
+ * RegisterAddress - unsigned char
+ * pOutput - pointer to value to be written in the register
+ * Return value:
+ * TRUE - if data read successfully
+ */
+UCHAR at91rm9200_EmacWritePhy (AT91PS_EMAC p_mac,
+ unsigned char RegisterAddress,
+ unsigned short *pOutput)
+{
+ p_mac->EMAC_MAN = (AT91C_EMAC_HIGH & ~AT91C_EMAC_LOW) |
+ AT91C_EMAC_CODE_802_3 | AT91C_EMAC_RW_W |
+ (RegisterAddress << 18) | *pOutput;
+
+ udelay (10000);
+
+ return TRUE;
+}
+
+int eth_init (bd_t * bd)
+{
+ int ret;
+ int i;
+
+ p_mac = AT91C_BASE_EMAC;
+
+ /* PIO Disable Register */
+ *AT91C_PIOA_PDR = AT91C_PA16_EMDIO | AT91C_PA15_EMDC | AT91C_PA14_ERXER |
+ AT91C_PA13_ERX1 | AT91C_PA12_ERX0 | AT91C_PA11_ECRS_ECRSDV |
+ AT91C_PA10_ETX1 | AT91C_PA9_ETX0 | AT91C_PA8_ETXEN |
+ AT91C_PA7_ETXCK_EREFCK;
+
+#ifdef CONFIG_AT91C_USE_RMII
+ *AT91C_PIOB_PDR = AT91C_PB19_ERXCK;
+ *AT91C_PIOB_BSR = AT91C_PB19_ERXCK;
+#else
+ *AT91C_PIOB_PDR = AT91C_PB19_ERXCK | AT91C_PB18_ECOL | AT91C_PB17_ERXDV |
+ AT91C_PB16_ERX3 | AT91C_PB15_ERX2 | AT91C_PB14_ETXER |
+ AT91C_PB13_ETX3 | AT91C_PB12_ETX2;
+
+ /* Select B Register */
+ *AT91C_PIOB_BSR = AT91C_PB19_ERXCK | AT91C_PB18_ECOL |
+ AT91C_PB17_ERXDV | AT91C_PB16_ERX3 | AT91C_PB15_ERX2 |
+ AT91C_PB14_ETXER | AT91C_PB13_ETX3 | AT91C_PB12_ETX2;
+#endif
+
+ *AT91C_PMC_PCER = 1 << AT91C_ID_EMAC; /* Peripheral Clock Enable Register */
+
+ p_mac->EMAC_CFG |= AT91C_EMAC_CSR; /* Clear statistics */
+
+ /* Init Ehternet buffers */
+ for (i = 0; i < RBF_FRAMEMAX; i++) {
+ rbfdt[i].addr = (unsigned long)rbf_framebuf[i];
+ rbfdt[i].size = 0;
+ }
+ rbfdt[RBF_FRAMEMAX - 1].addr |= RBF_WRAP;
+ rbfp = &rbfdt[0];
+
+ p_mac->EMAC_SA2L = (bd->bi_enetaddr[3] << 24) | (bd->bi_enetaddr[2] << 16)
+ | (bd->bi_enetaddr[1] << 8) | (bd->bi_enetaddr[0]);
+ p_mac->EMAC_SA2H = (bd->bi_enetaddr[5] << 8) | (bd->bi_enetaddr[4]);
+
+ p_mac->EMAC_RBQP = (long) (&rbfdt[0]);
+ p_mac->EMAC_RSR &= ~(AT91C_EMAC_RSR_OVR | AT91C_EMAC_REC | AT91C_EMAC_BNA);
+
+ p_mac->EMAC_CFG = (p_mac->EMAC_CFG | AT91C_EMAC_CAF | AT91C_EMAC_NBC)
+ & ~AT91C_EMAC_CLK;
+
+#ifdef CONFIG_AT91C_USE_RMII
+ p_mac->EMAC_CFG |= AT91C_EMAC_RMII;
+#endif
+
+#if (AT91C_MASTER_CLOCK > 40000000)
+ /* MDIO clock must not exceed 2.5 MHz, so enable MCK divider */
+ p_mac->EMAC_CFG |= AT91C_EMAC_CLK_HCLK_64;
+#endif
+
+ p_mac->EMAC_CTL |= AT91C_EMAC_TE | AT91C_EMAC_RE;
+
+ at91rm9200_GetPhyInterface (& PhyOps);
+
+ if (!PhyOps.IsPhyConnected (p_mac))
+ printf ("PHY not connected!!\n\r");
+
+ /* MII management start from here */
+ if (!(p_mac->EMAC_SR & AT91C_EMAC_LINK)) {
+ if (!(ret = PhyOps.Init (p_mac))) {
+ printf ("MAC: error during MII initialization\n");
+ return 0;
+ }
+ } else {
+ printf ("No link\n\r");
+ return 0;
+ }
+
+ return 0;
+}
+
+int eth_send (volatile void *packet, int length)
+{
+ while (!(p_mac->EMAC_TSR & AT91C_EMAC_BNQ));
+ p_mac->EMAC_TAR = (long) packet;
+ p_mac->EMAC_TCR = length;
+ while (p_mac->EMAC_TCR & 0x7ff);
+ p_mac->EMAC_TSR |= AT91C_EMAC_COMP;
+ return 0;
+}
+
+int eth_rx (void)
+{
+ int size;
+
+ if (!(rbfp->addr & RBF_OWNER))
+ return 0;
+
+ size = rbfp->size & RBF_SIZE;
+ NetReceive ((volatile uchar *) (rbfp->addr & RBF_ADDR), size);
+
+ rbfp->addr &= ~RBF_OWNER;
+ if (rbfp->addr & RBF_WRAP)
+ rbfp = &rbfdt[0];
+ else
+ rbfp++;
+
+ p_mac->EMAC_RSR |= AT91C_EMAC_REC;
+
+ return size;
+}
+
+void eth_halt (void)
+{
+};
+
+#if defined(CONFIG_MII) || (CONFIG_COMMANDS & CFG_CMD_MII)
+int at91rm9200_miiphy_read(char *devname, unsigned char addr,
+ unsigned char reg, unsigned short * value)
+{
+ at91rm9200_EmacEnableMDIO (p_mac);
+ at91rm9200_EmacReadPhy (p_mac, reg, value);
+ at91rm9200_EmacDisableMDIO (p_mac);
+ return 0;
+}
+
+int at91rm9200_miiphy_write(char *devname, unsigned char addr,
+ unsigned char reg, unsigned short value)
+{
+ at91rm9200_EmacEnableMDIO (p_mac);
+ at91rm9200_EmacWritePhy (p_mac, reg, &value);
+ at91rm9200_EmacDisableMDIO (p_mac);
+ return 0;
+}
+
+#endif /* defined(CONFIG_MII) || (CONFIG_COMMANDS & CFG_CMD_MII) */
+
+int at91rm9200_miiphy_initialize(bd_t *bis)
+{
+#if defined(CONFIG_MII) || (CONFIG_COMMANDS & CFG_CMD_MII)
+ miiphy_register("at91rm9200phy", at91rm9200_miiphy_read, at91rm9200_miiphy_write);
+#endif
+ return 0;
+}
+
+#endif /* CONFIG_COMMANDS & CFG_CMD_NET */
+
+#endif /* CONFIG_DRIVER_ETHER */
diff --git a/cpu/arm920t/at91rm9200/i2c.c b/cpu/arm920t/at91rm9200/i2c.c
new file mode 100755
index 0000000..2565998
--- /dev/null
+++ b/cpu/arm920t/at91rm9200/i2c.c
@@ -0,0 +1,206 @@
+/*
+ * i2c Support for Atmel's AT91RM9200 Two-Wire Interface
+ *
+ * (c) Rick Bronson
+ *
+ * Borrowed heavily from original work by:
+ * Copyright (c) 2000 Philip Edelbrock <phil@stimpy.netroedge.com>
+ *
+ * Modified to work with u-boot by (C) 2004 Gary Jennejohn garyj@denx.de
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+*/
+#include <common.h>
+
+#ifdef CONFIG_HARD_I2C
+
+#include <i2c.h>
+#include <asm/io.h>
+#include <asm/arch/hardware.h>
+
+#include <at91rm9200_i2c.h>
+
+/* define DEBUG */
+
+/*
+ * Poll the i2c status register until the specified bit is set.
+ * Returns 0 if timed out (100 msec)
+ */
+static short at91_poll_status(AT91PS_TWI twi, unsigned long bit) {
+ int loop_cntr = 10000;
+ do {
+ udelay(10);
+ } while (!(twi->TWI_SR & bit) && (--loop_cntr > 0));
+
+ return (loop_cntr > 0);
+}
+
+/*
+ * Generic i2c master transfer entrypoint
+ *
+ * rw == 1 means that this is a read
+ */
+static int
+at91_xfer(unsigned char chip, unsigned int addr, int alen,
+ unsigned char *buffer, int len, int rw)
+{
+ AT91PS_TWI twi = (AT91PS_TWI) AT91_TWI_BASE;
+ int length;
+ unsigned char *buf;
+ /* Set the TWI Master Mode Register */
+ twi->TWI_MMR = (chip << 16) | (alen << 8)
+ | ((rw == 1) ? AT91C_TWI_MREAD : 0);
+
+ /* Set TWI Internal Address Register with first messages data field */
+ if (alen > 0)
+ twi->TWI_IADR = addr;
+
+ length = len;
+ buf = buffer;
+ if (length && buf) { /* sanity check */
+ if (rw) {
+ twi->TWI_CR = AT91C_TWI_START;
+ while (length--) {
+ if (!length)
+ twi->TWI_CR = AT91C_TWI_STOP;
+ /* Wait until transfer is finished */
+ if (!at91_poll_status(twi, AT91C_TWI_RXRDY)) {
+ debug ("at91_i2c: timeout 1\n");
+ return 1;
+ }
+ *buf++ = twi->TWI_RHR;
+ }
+ if (!at91_poll_status(twi, AT91C_TWI_TXCOMP)) {
+ debug ("at91_i2c: timeout 2\n");
+ return 1;
+ }
+ } else {
+ twi->TWI_CR = AT91C_TWI_START;
+ while (length--) {
+ twi->TWI_THR = *buf++;
+ if (!length)
+ twi->TWI_CR = AT91C_TWI_STOP;
+ if (!at91_poll_status(twi, AT91C_TWI_TXRDY)) {
+ debug ("at91_i2c: timeout 3\n");
+ return 1;
+ }
+ }
+ /* Wait until transfer is finished */
+ if (!at91_poll_status(twi, AT91C_TWI_TXCOMP)) {
+ debug ("at91_i2c: timeout 4\n");
+ return 1;
+ }
+ }
+ }
+ return 0;
+}
+
+int
+i2c_probe(unsigned char chip)
+{
+ char buffer[1];
+
+ return at91_xfer(chip, 0, 0, buffer, 1, 1);
+}
+
+int
+i2c_read (unsigned char chip, unsigned int addr, int alen,
+ unsigned char *buffer, int len)
+{
+#ifdef CFG_I2C_EEPROM_ADDR_OVERFLOW
+ /* we only allow one address byte */
+ if (alen > 1)
+ return 1;
+ /* XXX assume an ATMEL AT24C16 */
+ if (alen == 1) {
+#if 0 /* EEPROM code already sets this correctly */
+ chip |= (addr >> 8) & 0xff;
+#endif
+ addr = addr & 0xff;
+ }
+#endif
+ return at91_xfer(chip, addr, alen, buffer, len, 1);
+}
+
+int
+i2c_write(unsigned char chip, unsigned int addr, int alen,
+ unsigned char *buffer, int len)
+{
+#ifdef CFG_I2C_EEPROM_ADDR_OVERFLOW
+ int i;
+ unsigned char *buf;
+
+ /* we only allow one address byte */
+ if (alen > 1)
+ return 1;
+ /* XXX assume an ATMEL AT24C16 */
+ if (alen == 1) {
+ buf = buffer;
+ /* do single byte writes */
+ for (i = 0; i < len; i++) {
+#if 0 /* EEPROM code already sets this correctly */
+ chip |= (addr >> 8) & 0xff;
+#endif
+ addr = addr & 0xff;
+ if (at91_xfer(chip, addr, alen, buf++, 1, 0))
+ return 1;
+ addr++;
+ }
+ return 0;
+ }
+#endif
+ return at91_xfer(chip, addr, alen, buffer, len, 0);
+}
+
+/*
+ * Main initialization routine
+ */
+void
+i2c_init(int speed, int slaveaddr)
+{
+ AT91PS_TWI twi = (AT91PS_TWI) AT91_TWI_BASE;
+
+ *AT91C_PIOA_PDR = AT91C_PA25_TWD | AT91C_PA26_TWCK;
+ *AT91C_PIOA_ASR = AT91C_PA25_TWD | AT91C_PA26_TWCK;
+ *AT91C_PIOA_MDER = AT91C_PA25_TWD | AT91C_PA26_TWCK;
+ *AT91C_PMC_PCER = 1 << AT91C_ID_TWI; /* enable peripheral clock */
+
+ twi->TWI_IDR = 0x3ff; /* Disable all interrupts */
+ twi->TWI_CR = AT91C_TWI_SWRST; /* Reset peripheral */
+ twi->TWI_CR = AT91C_TWI_MSEN | AT91C_TWI_SVDIS; /* Set Master mode */
+
+ /* Here, CKDIV = 1 and CHDIV=CLDIV ==> CLDIV = CHDIV = 1/4*((Fmclk/FTWI) -6) */
+ twi->TWI_CWGR = AT91C_TWI_CKDIV1 | AT91C_TWI_CLDIV3 | (AT91C_TWI_CLDIV3 << 8);
+
+ debug ("Found AT91 i2c\n");
+ return;
+}
+
+uchar i2c_reg_read(uchar i2c_addr, uchar reg)
+{
+ char buf;
+
+ i2c_read(i2c_addr, reg, 1, &buf, 1);
+
+ return(buf);
+}
+
+void i2c_reg_write(uchar i2c_addr, uchar reg, uchar val)
+{
+ i2c_write(i2c_addr, reg, 1, &val, 1);
+}
+
+#endif /* CONFIG_HARD_I2C */
diff --git a/cpu/arm920t/at91rm9200/interrupts.c b/cpu/arm920t/at91rm9200/interrupts.c
new file mode 100755
index 0000000..1054602
--- /dev/null
+++ b/cpu/arm920t/at91rm9200/interrupts.c
@@ -0,0 +1,210 @@
+/*
+ * (C) Copyright 2002
+ * Lineo, Inc. <www.lineo.com>
+ * Bernhard Kuhn <bkuhn@lineo.com>
+ *
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Marius Groeger <mgroeger@sysgo.de>
+ *
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Alex Zuepke <azu@sysgo.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 <asm/io.h>*/
+#include <asm/arch/hardware.h>
+/*#include <asm/proc/ptrace.h>*/
+
+/* the number of clocks per CFG_HZ */
+#define TIMER_LOAD_VAL (CFG_HZ_CLOCK/CFG_HZ)
+
+/* macro to read the 16 bit timer */
+#define READ_TIMER (tmr->TC_CV & 0x0000ffff)
+AT91PS_TC tmr;
+
+static ulong timestamp;
+static ulong lastinc;
+
+int interrupt_init (void)
+{
+ tmr = AT91C_BASE_TC0;
+
+ /* enables TC1.0 clock */
+ *AT91C_PMC_PCER = 1 << AT91C_ID_TC0; /* enable clock */
+
+ *AT91C_TCB0_BCR = 0;
+ *AT91C_TCB0_BMR = AT91C_TCB_TC0XC0S_NONE | AT91C_TCB_TC1XC1S_NONE | AT91C_TCB_TC2XC2S_NONE;
+ tmr->TC_CCR = AT91C_TC_CLKDIS;
+#define AT91C_TC_CMR_CPCTRG (1 << 14)
+ /* set to MCLK/2 and restart the timer when the vlaue in TC_RC is reached */
+ tmr->TC_CMR = AT91C_TC_TIMER_DIV1_CLOCK | AT91C_TC_CMR_CPCTRG;
+
+ tmr->TC_IDR = ~0ul;
+ tmr->TC_RC = TIMER_LOAD_VAL;
+ lastinc = 0;
+ tmr->TC_CCR = AT91C_TC_SWTRG | AT91C_TC_CLKEN;
+ timestamp = 0;
+
+ return (0);
+}
+
+/*
+ * timer without interrupts
+ */
+
+void reset_timer (void)
+{
+ reset_timer_masked ();
+}
+
+ulong get_timer (ulong base)
+{
+ return get_timer_masked () - base;
+}
+
+void set_timer (ulong t)
+{
+ timestamp = t;
+}
+
+void udelay (unsigned long usec)
+{
+ udelay_masked(usec);
+}
+
+void reset_timer_masked (void)
+{
+ /* reset time */
+ lastinc = READ_TIMER;
+ timestamp = 0;
+}
+
+ulong get_timer_raw (void)
+{
+ ulong now = READ_TIMER;
+
+ if (now >= lastinc) {
+ /* normal mode */
+ timestamp += now - lastinc;
+ } else {
+ /* we have an overflow ... */
+ timestamp += now + TIMER_LOAD_VAL - lastinc;
+ }
+ lastinc = now;
+
+ return timestamp;
+}
+
+ulong get_timer_masked (void)
+{
+ return get_timer_raw()/TIMER_LOAD_VAL;
+}
+
+void udelay_masked (unsigned long usec)
+{
+ ulong tmo;
+ ulong endtime;
+ signed long diff;
+
+ tmo = CFG_HZ_CLOCK / 1000;
+ tmo *= usec;
+ tmo /= 1000;
+
+ endtime = get_timer_raw () + tmo;
+
+ do {
+ ulong now = get_timer_raw ();
+ diff = endtime - now;
+ } while (diff >= 0);
+}
+
+/*
+ * This function is derived from PowerPC code (read timebase as long long).
+ * On ARM it just returns the timer value.
+ */
+unsigned long long get_ticks(void)
+{
+ return get_timer(0);
+}
+
+/*
+ * This function is derived from PowerPC code (timebase clock frequency).
+ * On ARM it returns the number of timer ticks per second.
+ */
+ulong get_tbclk (void)
+{
+ ulong tbclk;
+
+ tbclk = CFG_HZ;
+ return tbclk;
+}
+
+/*
+ * Reset the cpu by setting up the watchdog timer and let him time out
+ * or toggle a GPIO pin on the AT91RM9200DK board
+ */
+void reset_cpu (ulong ignored)
+{
+
+#ifdef CONFIG_DBGU
+ AT91PS_USART us = (AT91PS_USART) AT91C_BASE_DBGU;
+#endif
+#ifdef CONFIG_USART0
+ AT91PS_USART us = AT91C_BASE_US0;
+#endif
+#ifdef CONFIG_USART1
+ AT91PS_USART us = AT91C_BASE_US1;
+#endif
+#ifdef CONFIG_AT91RM9200DK
+ AT91PS_PIO pio = AT91C_BASE_PIOA;
+#endif
+
+ /*shutdown the console to avoid strange chars during reset */
+ us->US_CR = (AT91C_US_RSTRX | AT91C_US_RSTTX);
+
+#ifdef CONFIG_AT91RM9200DK
+ /* Clear PA19 to trigger the hard reset */
+ pio->PIO_CODR = 0x00080000;
+ pio->PIO_OER = 0x00080000;
+ pio->PIO_PER = 0x00080000;
+#endif
+
+ /* this is the way Linux does it */
+
+ /* FIXME:
+ * These defines should be moved into
+ * include/asm-arm/arch-at91rm9200/AT91RM9200.h
+ * as soon as the whitespace fix gets applied.
+ */
+ #define AT91C_ST_RSTEN (0x1 << 16)
+ #define AT91C_ST_EXTEN (0x1 << 17)
+ #define AT91C_ST_WDRST (0x1 << 0)
+ #define ST_WDMR *((unsigned long *)0xfffffd08) /* watchdog mode register */
+ #define ST_CR *((unsigned long *)0xfffffd00) /* system clock control register */
+
+ ST_WDMR = AT91C_ST_RSTEN | AT91C_ST_EXTEN | 1 ;
+ ST_CR = AT91C_ST_WDRST;
+
+ while (1);
+ /* Never reached */
+}
diff --git a/cpu/arm920t/at91rm9200/lowlevel_init.S b/cpu/arm920t/at91rm9200/lowlevel_init.S
new file mode 100755
index 0000000..1902bd0
--- /dev/null
+++ b/cpu/arm920t/at91rm9200/lowlevel_init.S
@@ -0,0 +1,205 @@
+/*
+ * Memory Setup stuff - taken from blob memsetup.S
+ *
+ * Copyright (C) 1999 2000 2001 Erik Mouw (J.A.K.Mouw@its.tudelft.nl) and
+ * Jan-Derk Bakker (J.D.Bakker@its.tudelft.nl)
+ *
+ * Modified for the at91rm9200dk board by
+ * (C) Copyright 2004
+ * Gary Jennejohn, DENX Software Engineering, <garyj@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 <version.h>
+
+#ifndef CONFIG_SKIP_LOWLEVEL_INIT
+/*
+ * some parameters for the board
+ *
+ * This is based on rm9200dk.cfg for the BDI2000 from ABATRON which in
+ * turn is based on the boot.bin code from ATMEL
+ *
+ */
+
+/* flash */
+#define MC_PUIA 0xFFFFFF10
+#define MC_PUP 0xFFFFFF50
+#define MC_PUER 0xFFFFFF54
+#define MC_ASR 0xFFFFFF04
+#define MC_AASR 0xFFFFFF08
+#define EBI_CFGR 0xFFFFFF64
+#define SMC2_CSR 0xFFFFFF70
+
+/* clocks */
+#define PLLAR 0xFFFFFC28
+#define PLLBR 0xFFFFFC2C
+#define MCKR 0xFFFFFC30
+
+#define AT91C_BASE_CKGR 0xFFFFFC20
+#define CKGR_MOR 0
+
+/* sdram */
+#define PIOC_ASR 0xFFFFF870
+#define PIOC_BSR 0xFFFFF874
+#define PIOC_PDR 0xFFFFF804
+#define EBI_CSA 0xFFFFFF60
+#define SDRC_CR 0xFFFFFF98
+#define SDRC_MR 0xFFFFFF90
+#define SDRC_TR 0xFFFFFF94
+
+
+_MTEXT_BASE:
+#undef START_FROM_MEM
+#ifdef START_FROM_MEM
+ .word TEXT_BASE-PHYS_FLASH_1
+#else
+ .word TEXT_BASE
+#endif
+
+.globl lowlevel_init
+lowlevel_init:
+ /* Get the CKGR Base Address */
+ ldr r1, =AT91C_BASE_CKGR
+ /* Main oscillator Enable register */
+#ifdef CFG_USE_MAIN_OSCILLATOR
+ ldr r0, =0x0000FF01 /* Enable main oscillator, OSCOUNT = 0xFF */
+#else
+ ldr r0, =0x0000FF00 /* Disable main oscillator, OSCOUNT = 0xFF */
+#endif
+ str r0, [r1, #CKGR_MOR]
+ /* Add loop to compensate Main Oscillator startup time */
+ ldr r0, =0x00000010
+LoopOsc:
+ subs r0, r0, #1
+ bhi LoopOsc
+
+ /* memory control configuration */
+ /* this isn't very elegant, but what the heck */
+ ldr r0, =SMRDATA
+ ldr r1, _MTEXT_BASE
+ sub r0, r0, r1
+ add r2, r0, #80
+0:
+ /* the address */
+ ldr r1, [r0], #4
+ /* the value */
+ ldr r3, [r0], #4
+ str r3, [r1]
+ cmp r2, r0
+ bne 0b
+ /* delay - this is all done by guess */
+ ldr r0, =0x00010000
+1:
+ subs r0, r0, #1
+ bhi 1b
+ ldr r0, =SMRDATA1
+ ldr r1, _MTEXT_BASE
+ sub r0, r0, r1
+ add r2, r0, #176
+2:
+ /* the address */
+ ldr r1, [r0], #4
+ /* the value */
+ ldr r3, [r0], #4
+ str r3, [r1]
+ cmp r2, r0
+ bne 2b
+
+ /* switch from FastBus to Asynchronous clock mode */
+ mrc p15, 0, r0, c1, c0, 0
+ orr r0, r0, #0xC0000000 @ set bit 31 (iA) and 30 (nF)
+ mcr p15, 0, r0, c1, c0, 0
+
+ /* everything is fine now */
+ mov pc, lr
+
+ .ltorg
+
+SMRDATA:
+ .word MC_PUIA
+ .word MC_PUIA_VAL
+ .word MC_PUP
+ .word MC_PUP_VAL
+ .word MC_PUER
+ .word MC_PUER_VAL
+ .word MC_ASR
+ .word MC_ASR_VAL
+ .word MC_AASR
+ .word MC_AASR_VAL
+ .word EBI_CFGR
+ .word EBI_CFGR_VAL
+ .word SMC2_CSR
+ .word SMC2_CSR_VAL
+ .word PLLAR
+ .word PLLAR_VAL
+ .word PLLBR
+ .word PLLBR_VAL
+ .word MCKR
+ .word MCKR_VAL
+ /* SMRDATA is 80 bytes long */
+ /* here there's a delay of 100 */
+SMRDATA1:
+ .word PIOC_ASR
+ .word PIOC_ASR_VAL
+ .word PIOC_BSR
+ .word PIOC_BSR_VAL
+ .word PIOC_PDR
+ .word PIOC_PDR_VAL
+ .word EBI_CSA
+ .word EBI_CSA_VAL
+ .word SDRC_CR
+ .word SDRC_CR_VAL
+ .word SDRC_MR
+ .word SDRC_MR_VAL
+ .word SDRAM
+ .word SDRAM_VAL
+ .word SDRC_MR
+ .word SDRC_MR_VAL1
+ .word SDRAM
+ .word SDRAM_VAL
+ .word SDRAM
+ .word SDRAM_VAL
+ .word SDRAM
+ .word SDRAM_VAL
+ .word SDRAM
+ .word SDRAM_VAL
+ .word SDRAM
+ .word SDRAM_VAL
+ .word SDRAM
+ .word SDRAM_VAL
+ .word SDRAM
+ .word SDRAM_VAL
+ .word SDRAM
+ .word SDRAM_VAL
+ .word SDRC_MR
+ .word SDRC_MR_VAL2
+ .word SDRAM1
+ .word SDRAM_VAL
+ .word SDRC_TR
+ .word SDRC_TR_VAL
+ .word SDRAM
+ .word SDRAM_VAL
+ .word SDRC_MR
+ .word SDRC_MR_VAL3
+ .word SDRAM
+ .word SDRAM_VAL
+ /* SMRDATA1 is 176 bytes long */
+#endif /* CONFIG_SKIP_LOWLEVEL_INIT */
diff --git a/cpu/arm920t/at91rm9200/lxt972.c b/cpu/arm920t/at91rm9200/lxt972.c
new file mode 100755
index 0000000..f12c59c
--- /dev/null
+++ b/cpu/arm920t/at91rm9200/lxt972.c
@@ -0,0 +1,191 @@
+/*
+ *
+ * (C) Copyright 2003
+ * Author : Hamid Ikdoumi (Atmel)
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/*
+ * Adapted for KwikByte KB920x board: 22APR2005
+ */
+
+#include <common.h>
+#include <at91rm9200_net.h>
+#include <net.h>
+#include <lxt971a.h>
+
+#ifdef CONFIG_DRIVER_ETHER
+
+#if (CONFIG_COMMANDS & CFG_CMD_NET)
+
+/*
+ * Name:
+ * lxt972_IsPhyConnected
+ * Description:
+ * Reads the 2 PHY ID registers
+ * Arguments:
+ * p_mac - pointer to AT91S_EMAC struct
+ * Return value:
+ * TRUE - if id read successfully
+ * FALSE- if error
+ */
+unsigned int lxt972_IsPhyConnected (AT91PS_EMAC p_mac)
+{
+ unsigned short Id1, Id2;
+
+ at91rm9200_EmacEnableMDIO (p_mac);
+ at91rm9200_EmacReadPhy (p_mac, PHY_COMMON_ID1, &Id1);
+ at91rm9200_EmacReadPhy (p_mac, PHY_COMMON_ID2, &Id2);
+ at91rm9200_EmacDisableMDIO (p_mac);
+
+ if ((Id1 == (0x0013)) && ((Id2 & 0xFFF0) == 0x78E0))
+ return TRUE;
+
+ return FALSE;
+}
+
+/*
+ * Name:
+ * lxt972_GetLinkSpeed
+ * Description:
+ * Link parallel detection status of MAC is checked and set in the
+ * MAC configuration registers
+ * Arguments:
+ * p_mac - pointer to MAC
+ * Return value:
+ * TRUE - if link status set succesfully
+ * FALSE - if link status not set
+ */
+UCHAR lxt972_GetLinkSpeed (AT91PS_EMAC p_mac)
+{
+ unsigned short stat1;
+
+ if (!at91rm9200_EmacReadPhy (p_mac, PHY_LXT971_STAT2, &stat1))
+ return FALSE;
+
+ if (!(stat1 & PHY_LXT971_STAT2_LINK)) /* link status up? */
+ return FALSE;
+
+ if (stat1 & PHY_LXT971_STAT2_100BTX) {
+
+ if (stat1 & PHY_LXT971_STAT2_DUPLEX_MODE) {
+
+ /*set Emac for 100BaseTX and Full Duplex */
+ p_mac->EMAC_CFG |= AT91C_EMAC_SPD | AT91C_EMAC_FD;
+ } else {
+
+ /*set Emac for 100BaseTX and Half Duplex */
+ p_mac->EMAC_CFG = (p_mac->EMAC_CFG &
+ ~(AT91C_EMAC_SPD | AT91C_EMAC_FD))
+ | AT91C_EMAC_SPD;
+ }
+
+ return TRUE;
+
+ } else {
+
+ if (stat1 & PHY_LXT971_STAT2_DUPLEX_MODE) {
+
+ /*set MII for 10BaseT and Full Duplex */
+ p_mac->EMAC_CFG = (p_mac->EMAC_CFG &
+ ~(AT91C_EMAC_SPD | AT91C_EMAC_FD))
+ | AT91C_EMAC_FD;
+ } else {
+
+ /*set MII for 10BaseT and Half Duplex */
+ p_mac->EMAC_CFG &= ~(AT91C_EMAC_SPD | AT91C_EMAC_FD);
+ }
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+
+/*
+ * Name:
+ * lxt972_InitPhy
+ * Description:
+ * MAC starts checking its link by using parallel detection and
+ * Autonegotiation and the same is set in the MAC configuration registers
+ * Arguments:
+ * p_mac - pointer to struct AT91S_EMAC
+ * Return value:
+ * TRUE - if link status set succesfully
+ * FALSE - if link status not set
+ */
+UCHAR lxt972_InitPhy (AT91PS_EMAC p_mac)
+{
+ UCHAR ret = TRUE;
+
+ at91rm9200_EmacEnableMDIO (p_mac);
+
+ if (!lxt972_GetLinkSpeed (p_mac)) {
+ /* Try another time */
+ ret = lxt972_GetLinkSpeed (p_mac);
+ }
+
+ /* Disable PHY Interrupts */
+ at91rm9200_EmacWritePhy (p_mac, PHY_LXT971_INT_ENABLE, 0);
+
+ at91rm9200_EmacDisableMDIO (p_mac);
+
+ return (ret);
+}
+
+
+/*
+ * Name:
+ * lxt972_AutoNegotiate
+ * Description:
+ * MAC Autonegotiates with the partner status of same is set in the
+ * MAC configuration registers
+ * Arguments:
+ * dev - pointer to struct net_device
+ * Return value:
+ * TRUE - if link status set successfully
+ * FALSE - if link status not set
+ */
+UCHAR lxt972_AutoNegotiate (AT91PS_EMAC p_mac, int *status)
+{
+ unsigned short value;
+
+ /* Set lxt972 control register */
+ if (!at91rm9200_EmacReadPhy (p_mac, PHY_COMMON_CTRL, &value))
+ return FALSE;
+
+ /* Restart Auto_negotiation */
+ value |= PHY_COMMON_CTRL_RES_AUTO;
+ if (!at91rm9200_EmacWritePhy (p_mac, PHY_COMMON_CTRL, &value))
+ return FALSE;
+
+ /*check AutoNegotiate complete */
+ udelay (10000);
+ at91rm9200_EmacReadPhy (p_mac, PHY_COMMON_STAT, &value);
+ if (!(value & PHY_COMMON_STAT_AN_COMP))
+ return FALSE;
+
+ return (lxt972_GetLinkSpeed (p_mac));
+}
+
+#endif /* CONFIG_COMMANDS & CFG_CMD_NET */
+
+#endif /* CONFIG_DRIVER_ETHER */
diff --git a/cpu/arm920t/at91rm9200/serial.c b/cpu/arm920t/at91rm9200/serial.c
new file mode 100755
index 0000000..a281932
--- /dev/null
+++ b/cpu/arm920t/at91rm9200/serial.c
@@ -0,0 +1,112 @@
+/*
+ * (C) Copyright 2002
+ * Lineo, Inc <www.lineo.com>
+ * Bernhard Kuhn <bkuhn@lineo.com>
+ *
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Marius Groeger <mgroeger@sysgo.de>
+ *
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Alex Zuepke <azu@sysgo.de>
+ *
+ * Copyright (C) 1999 2000 2001 Erik Mouw (J.A.K.Mouw@its.tudelft.nl)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/hardware.h>
+
+#if !defined(CONFIG_DBGU) && !defined(CONFIG_USART0) && !defined(CONFIG_USART1)
+#error must define one of CONFIG_DBGU or CONFIG_USART0 or CONFIG_USART1
+#endif
+
+/* ggi thunder */
+#ifdef CONFIG_DBGU
+AT91PS_USART us = (AT91PS_USART) AT91C_BASE_DBGU;
+#endif
+#ifdef CONFIG_USART0
+AT91PS_USART us = (AT91PS_USART) AT91C_BASE_US0;
+#endif
+#ifdef CONFIG_USART1
+AT91PS_USART us = (AT91PS_USART) AT91C_BASE_US1;
+#endif
+
+void serial_setbrg (void)
+{
+ DECLARE_GLOBAL_DATA_PTR;
+ int baudrate;
+
+ if ((baudrate = gd->baudrate) <= 0)
+ baudrate = CONFIG_BAUDRATE;
+ /* MASTER_CLOCK/(16 * baudrate) */
+ us->US_BRGR = (AT91C_MASTER_CLOCK >> 4) / (unsigned)baudrate;
+}
+
+int serial_init (void)
+{
+ /* make any port initializations specific to this port */
+#ifdef CONFIG_DBGU
+ *AT91C_PIOA_PDR = AT91C_PA31_DTXD | AT91C_PA30_DRXD; /* PA 31 & 30 */
+ *AT91C_PMC_PCER = 1 << AT91C_ID_SYS; /* enable clock */
+#endif
+#ifdef CONFIG_USART0
+ *AT91C_PIOA_PDR = AT91C_PA17_TXD0 | AT91C_PA18_RXD0;
+ *AT91C_PMC_PCER |= 1 << AT91C_ID_USART0; /* enable clock */
+#endif
+#ifdef CONFIG_USART1
+ *AT91C_PIOB_PDR = AT91C_PB21_TXD1 | AT91C_PB20_RXD1;
+ *AT91C_PMC_PCER |= 1 << AT91C_ID_USART1; /* enable clock */
+#endif
+ serial_setbrg ();
+
+ us->US_CR = AT91C_US_RSTRX | AT91C_US_RSTTX;
+ us->US_CR = AT91C_US_RXEN | AT91C_US_TXEN;
+ us->US_MR =
+ (AT91C_US_CLKS_CLOCK | AT91C_US_CHRL_8_BITS |
+ AT91C_US_PAR_NONE | AT91C_US_NBSTOP_1_BIT);
+ us->US_IMR = ~0ul;
+ return (0);
+}
+
+void serial_putc (const char c)
+{
+ if (c == '\n')
+ serial_putc ('\r');
+ while ((us->US_CSR & AT91C_US_TXRDY) == 0);
+ us->US_THR = c;
+}
+
+void serial_puts (const char *s)
+{
+ while (*s) {
+ serial_putc (*s++);
+ }
+}
+
+int serial_getc (void)
+{
+ while ((us->US_CSR & AT91C_US_RXRDY) == 0);
+ return us->US_RHR;
+}
+
+int serial_tstc (void)
+{
+ return ((us->US_CSR & AT91C_US_RXRDY) == AT91C_US_RXRDY);
+}
diff --git a/cpu/arm920t/at91rm9200/usb_ohci.c b/cpu/arm920t/at91rm9200/usb_ohci.c
new file mode 100755
index 0000000..5b2c56c
--- /dev/null
+++ b/cpu/arm920t/at91rm9200/usb_ohci.c
@@ -0,0 +1,1635 @@
+/*
+ * URB OHCI HCD (Host Controller Driver) for USB on the AT91RM9200.
+ *
+ * (C) Copyright 2003
+ * Gary Jennejohn, DENX Software Engineering <gj@denx.de>
+ *
+ * Note: Much of this code has been derived from Linux 2.4
+ * (C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at>
+ * (C) Copyright 2000-2002 David Brownell
+ *
+ * Modified for the MP2USB by (C) Copyright 2005 Eric Benard
+ * ebenard@eukrea.com - based on s3c24x0's driver
+ *
+ * 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
+ *
+ */
+/*
+ * IMPORTANT NOTES
+ * 1 - you MUST define LITTLEENDIAN in the configuration file for the
+ * board or this driver will NOT work!
+ * 2 - this driver is intended for use with USB Mass Storage Devices
+ * (BBB) ONLY. There is NO support for Interrupt or Isochronous pipes!
+ * 3 - when running on a PQFP208 AT91RM9200, define CONFIG_AT91C_PQFP_UHPBUG
+ * to activate workaround for bug #41 or this driver will NOT work!
+ */
+
+#include <common.h>
+/* #include <pci.h> no PCI on the S3C24X0 */
+
+#ifdef CONFIG_USB_OHCI
+
+#include <asm/arch/hardware.h>
+
+#include <malloc.h>
+#include <usb.h>
+#include "usb_ohci.h"
+
+#define OHCI_USE_NPS /* force NoPowerSwitching mode */
+#undef OHCI_VERBOSE_DEBUG /* not always helpful */
+
+/* For initializing controller (mask in an HCFS mode too) */
+#define OHCI_CONTROL_INIT \
+ (OHCI_CTRL_CBSR & 0x3) | OHCI_CTRL_IE | OHCI_CTRL_PLE
+
+#define readl(a) (*((vu_long *)(a)))
+#define writel(a, b) (*((vu_long *)(b)) = ((vu_long)a))
+
+#define min_t(type,x,y) ({ type __x = (x); type __y = (y); __x < __y ? __x: __y; })
+
+#undef DEBUG
+#ifdef DEBUG
+#define dbg(format, arg...) printf("DEBUG: " format "\n", ## arg)
+#else
+#define dbg(format, arg...) do {} while(0)
+#endif /* DEBUG */
+#define err(format, arg...) printf("ERROR: " format "\n", ## arg)
+#undef SHOW_INFO
+#ifdef SHOW_INFO
+#define info(format, arg...) printf("INFO: " format "\n", ## arg)
+#else
+#define info(format, arg...) do {} while(0)
+#endif
+
+#define m16_swap(x) swap_16(x)
+#define m32_swap(x) swap_32(x)
+
+/* global ohci_t */
+static ohci_t gohci;
+/* this must be aligned to a 256 byte boundary */
+struct ohci_hcca ghcca[1];
+/* a pointer to the aligned storage */
+struct ohci_hcca *phcca;
+/* this allocates EDs for all possible endpoints */
+struct ohci_device ohci_dev;
+/* urb_priv */
+urb_priv_t urb_priv;
+/* RHSC flag */
+int got_rhsc;
+/* device which was disconnected */
+struct usb_device *devgone;
+
+/*-------------------------------------------------------------------------*/
+
+/* AMD-756 (D2 rev) reports corrupt register contents in some cases.
+ * The erratum (#4) description is incorrect. AMD's workaround waits
+ * till some bits (mostly reserved) are clear; ok for all revs.
+ */
+#define OHCI_QUIRK_AMD756 0xabcd
+#define read_roothub(hc, register, mask) ({ \
+ u32 temp = readl (&hc->regs->roothub.register); \
+ if (hc->flags & OHCI_QUIRK_AMD756) \
+ while (temp & mask) \
+ temp = readl (&hc->regs->roothub.register); \
+ temp; })
+
+static u32 roothub_a (struct ohci *hc)
+ { return read_roothub (hc, a, 0xfc0fe000); }
+static inline u32 roothub_b (struct ohci *hc)
+ { return readl (&hc->regs->roothub.b); }
+static inline u32 roothub_status (struct ohci *hc)
+ { return readl (&hc->regs->roothub.status); }
+static u32 roothub_portstatus (struct ohci *hc, int i)
+ { return read_roothub (hc, portstatus [i], 0xffe0fce0); }
+
+
+/* forward declaration */
+static int hc_interrupt (void);
+static void
+td_submit_job (struct usb_device * dev, unsigned long pipe, void * buffer,
+ int transfer_len, struct devrequest * setup, urb_priv_t * urb, int interval);
+
+/*-------------------------------------------------------------------------*
+ * URB support functions
+ *-------------------------------------------------------------------------*/
+
+/* free HCD-private data associated with this URB */
+
+static void urb_free_priv (urb_priv_t * urb)
+{
+ int i;
+ int last;
+ struct td * td;
+
+ last = urb->length - 1;
+ if (last >= 0) {
+ for (i = 0; i <= last; i++) {
+ td = urb->td[i];
+ if (td) {
+ td->usb_dev = NULL;
+ urb->td[i] = NULL;
+ }
+ }
+ }
+}
+
+/*-------------------------------------------------------------------------*/
+
+#ifdef DEBUG
+static int sohci_get_current_frame_number (struct usb_device * dev);
+
+/* debug| print the main components of an URB
+ * small: 0) header + data packets 1) just header */
+
+static void pkt_print (struct usb_device * dev, unsigned long pipe, void * buffer,
+ int transfer_len, struct devrequest * setup, char * str, int small)
+{
+ urb_priv_t * purb = &urb_priv;
+
+ dbg("%s URB:[%4x] dev:%2d,ep:%2d-%c,type:%s,len:%d/%d stat:%#lx",
+ str,
+ sohci_get_current_frame_number (dev),
+ usb_pipedevice (pipe),
+ usb_pipeendpoint (pipe),
+ usb_pipeout (pipe)? 'O': 'I',
+ usb_pipetype (pipe) < 2? (usb_pipeint (pipe)? "INTR": "ISOC"):
+ (usb_pipecontrol (pipe)? "CTRL": "BULK"),
+ purb->actual_length,
+ transfer_len, dev->status);
+#ifdef OHCI_VERBOSE_DEBUG
+ if (!small) {
+ int i, len;
+
+ if (usb_pipecontrol (pipe)) {
+ printf (__FILE__ ": cmd(8):");
+ for (i = 0; i < 8 ; i++)
+ printf (" %02x", ((__u8 *) setup) [i]);
+ printf ("\n");
+ }
+ if (transfer_len > 0 && buffer) {
+ printf (__FILE__ ": data(%d/%d):",
+ purb->actual_length,
+ transfer_len);
+ len = usb_pipeout (pipe)?
+ transfer_len: purb->actual_length;
+ for (i = 0; i < 16 && i < len; i++)
+ printf (" %02x", ((__u8 *) buffer) [i]);
+ printf ("%s\n", i < len? "...": "");
+ }
+ }
+#endif
+}
+
+/* just for debugging; prints non-empty branches of the int ed tree inclusive iso eds*/
+void ep_print_int_eds (ohci_t *ohci, char * str) {
+ int i, j;
+ __u32 * ed_p;
+ for (i= 0; i < 32; i++) {
+ j = 5;
+ ed_p = &(ohci->hcca->int_table [i]);
+ if (*ed_p == 0)
+ continue;
+ printf (__FILE__ ": %s branch int %2d(%2x):", str, i, i);
+ while (*ed_p != 0 && j--) {
+ ed_t *ed = (ed_t *)m32_swap(ed_p);
+ printf (" ed: %4x;", ed->hwINFO);
+ ed_p = &ed->hwNextED;
+ }
+ printf ("\n");
+ }
+}
+
+static void ohci_dump_intr_mask (char *label, __u32 mask)
+{
+ dbg ("%s: 0x%08x%s%s%s%s%s%s%s%s%s",
+ label,
+ mask,
+ (mask & OHCI_INTR_MIE) ? " MIE" : "",
+ (mask & OHCI_INTR_OC) ? " OC" : "",
+ (mask & OHCI_INTR_RHSC) ? " RHSC" : "",
+ (mask & OHCI_INTR_FNO) ? " FNO" : "",
+ (mask & OHCI_INTR_UE) ? " UE" : "",
+ (mask & OHCI_INTR_RD) ? " RD" : "",
+ (mask & OHCI_INTR_SF) ? " SF" : "",
+ (mask & OHCI_INTR_WDH) ? " WDH" : "",
+ (mask & OHCI_INTR_SO) ? " SO" : ""
+ );
+}
+
+static void maybe_print_eds (char *label, __u32 value)
+{
+ ed_t *edp = (ed_t *)value;
+
+ if (value) {
+ dbg ("%s %08x", label, value);
+ dbg ("%08x", edp->hwINFO);
+ dbg ("%08x", edp->hwTailP);
+ dbg ("%08x", edp->hwHeadP);
+ dbg ("%08x", edp->hwNextED);
+ }
+}
+
+static char * hcfs2string (int state)
+{
+ switch (state) {
+ case OHCI_USB_RESET: return "reset";
+ case OHCI_USB_RESUME: return "resume";
+ case OHCI_USB_OPER: return "operational";
+ case OHCI_USB_SUSPEND: return "suspend";
+ }
+ return "?";
+}
+
+/* dump control and status registers */
+static void ohci_dump_status (ohci_t *controller)
+{
+ struct ohci_regs *regs = controller->regs;
+ __u32 temp;
+
+ temp = readl (&regs->revision) & 0xff;
+ if (temp != 0x10)
+ dbg ("spec %d.%d", (temp >> 4), (temp & 0x0f));
+
+ temp = readl (&regs->control);
+ dbg ("control: 0x%08x%s%s%s HCFS=%s%s%s%s%s CBSR=%d", temp,
+ (temp & OHCI_CTRL_RWE) ? " RWE" : "",
+ (temp & OHCI_CTRL_RWC) ? " RWC" : "",
+ (temp & OHCI_CTRL_IR) ? " IR" : "",
+ hcfs2string (temp & OHCI_CTRL_HCFS),
+ (temp & OHCI_CTRL_BLE) ? " BLE" : "",
+ (temp & OHCI_CTRL_CLE) ? " CLE" : "",
+ (temp & OHCI_CTRL_IE) ? " IE" : "",
+ (temp & OHCI_CTRL_PLE) ? " PLE" : "",
+ temp & OHCI_CTRL_CBSR
+ );
+
+ temp = readl (&regs->cmdstatus);
+ dbg ("cmdstatus: 0x%08x SOC=%d%s%s%s%s", temp,
+ (temp & OHCI_SOC) >> 16,
+ (temp & OHCI_OCR) ? " OCR" : "",
+ (temp & OHCI_BLF) ? " BLF" : "",
+ (temp & OHCI_CLF) ? " CLF" : "",
+ (temp & OHCI_HCR) ? " HCR" : ""
+ );
+
+ ohci_dump_intr_mask ("intrstatus", readl (&regs->intrstatus));
+ ohci_dump_intr_mask ("intrenable", readl (&regs->intrenable));
+
+ maybe_print_eds ("ed_periodcurrent", readl (&regs->ed_periodcurrent));
+
+ maybe_print_eds ("ed_controlhead", readl (&regs->ed_controlhead));
+ maybe_print_eds ("ed_controlcurrent", readl (&regs->ed_controlcurrent));
+
+ maybe_print_eds ("ed_bulkhead", readl (&regs->ed_bulkhead));
+ maybe_print_eds ("ed_bulkcurrent", readl (&regs->ed_bulkcurrent));
+
+ maybe_print_eds ("donehead", readl (&regs->donehead));
+}
+
+static void ohci_dump_roothub (ohci_t *controller, int verbose)
+{
+ __u32 temp, ndp, i;
+
+ temp = roothub_a (controller);
+ ndp = (temp & RH_A_NDP);
+#ifdef CONFIG_AT91C_PQFP_UHPBUG
+ ndp = (ndp == 2) ? 1:0;
+#endif
+ if (verbose) {
+ dbg ("roothub.a: %08x POTPGT=%d%s%s%s%s%s NDP=%d", temp,
+ ((temp & RH_A_POTPGT) >> 24) & 0xff,
+ (temp & RH_A_NOCP) ? " NOCP" : "",
+ (temp & RH_A_OCPM) ? " OCPM" : "",
+ (temp & RH_A_DT) ? " DT" : "",
+ (temp & RH_A_NPS) ? " NPS" : "",
+ (temp & RH_A_PSM) ? " PSM" : "",
+ ndp
+ );
+ temp = roothub_b (controller);
+ dbg ("roothub.b: %08x PPCM=%04x DR=%04x",
+ temp,
+ (temp & RH_B_PPCM) >> 16,
+ (temp & RH_B_DR)
+ );
+ temp = roothub_status (controller);
+ dbg ("roothub.status: %08x%s%s%s%s%s%s",
+ temp,
+ (temp & RH_HS_CRWE) ? " CRWE" : "",
+ (temp & RH_HS_OCIC) ? " OCIC" : "",
+ (temp & RH_HS_LPSC) ? " LPSC" : "",
+ (temp & RH_HS_DRWE) ? " DRWE" : "",
+ (temp & RH_HS_OCI) ? " OCI" : "",
+ (temp & RH_HS_LPS) ? " LPS" : ""
+ );
+ }
+
+ for (i = 0; i < ndp; i++) {
+ temp = roothub_portstatus (controller, i);
+ dbg ("roothub.portstatus [%d] = 0x%08x%s%s%s%s%s%s%s%s%s%s%s%s",
+ i,
+ temp,
+ (temp & RH_PS_PRSC) ? " PRSC" : "",
+ (temp & RH_PS_OCIC) ? " OCIC" : "",
+ (temp & RH_PS_PSSC) ? " PSSC" : "",
+ (temp & RH_PS_PESC) ? " PESC" : "",
+ (temp & RH_PS_CSC) ? " CSC" : "",
+
+ (temp & RH_PS_LSDA) ? " LSDA" : "",
+ (temp & RH_PS_PPS) ? " PPS" : "",
+ (temp & RH_PS_PRS) ? " PRS" : "",
+ (temp & RH_PS_POCI) ? " POCI" : "",
+ (temp & RH_PS_PSS) ? " PSS" : "",
+
+ (temp & RH_PS_PES) ? " PES" : "",
+ (temp & RH_PS_CCS) ? " CCS" : ""
+ );
+ }
+}
+
+static void ohci_dump (ohci_t *controller, int verbose)
+{
+ dbg ("OHCI controller usb-%s state", controller->slot_name);
+
+ /* dumps some of the state we know about */
+ ohci_dump_status (controller);
+ if (verbose)
+ ep_print_int_eds (controller, "hcca");
+ dbg ("hcca frame #%04x", controller->hcca->frame_no);
+ ohci_dump_roothub (controller, 1);
+}
+
+
+#endif /* DEBUG */
+
+/*-------------------------------------------------------------------------*
+ * Interface functions (URB)
+ *-------------------------------------------------------------------------*/
+
+/* get a transfer request */
+
+int sohci_submit_job(struct usb_device *dev, unsigned long pipe, void *buffer,
+ int transfer_len, struct devrequest *setup, int interval)
+{
+ ohci_t *ohci;
+ ed_t * ed;
+ urb_priv_t *purb_priv;
+ int i, size = 0;
+
+ ohci = &gohci;
+
+ /* when controller's hung, permit only roothub cleanup attempts
+ * such as powering down ports */
+ if (ohci->disabled) {
+ err("sohci_submit_job: EPIPE");
+ return -1;
+ }
+
+ /* every endpoint has a ed, locate and fill it */
+ if (!(ed = ep_add_ed (dev, pipe))) {
+ err("sohci_submit_job: ENOMEM");
+ return -1;
+ }
+
+ /* for the private part of the URB we need the number of TDs (size) */
+ switch (usb_pipetype (pipe)) {
+ case PIPE_BULK: /* one TD for every 4096 Byte */
+ size = (transfer_len - 1) / 4096 + 1;
+ break;
+ case PIPE_CONTROL: /* 1 TD for setup, 1 for ACK and 1 for every 4096 B */
+ size = (transfer_len == 0)? 2:
+ (transfer_len - 1) / 4096 + 3;
+ break;
+ }
+
+ if (size >= (N_URB_TD - 1)) {
+ err("need %d TDs, only have %d", size, N_URB_TD);
+ return -1;
+ }
+ purb_priv = &urb_priv;
+ purb_priv->pipe = pipe;
+
+ /* fill the private part of the URB */
+ purb_priv->length = size;
+ purb_priv->ed = ed;
+ purb_priv->actual_length = 0;
+
+ /* allocate the TDs */
+ /* note that td[0] was allocated in ep_add_ed */
+ for (i = 0; i < size; i++) {
+ purb_priv->td[i] = td_alloc (dev);
+ if (!purb_priv->td[i]) {
+ purb_priv->length = i;
+ urb_free_priv (purb_priv);
+ err("sohci_submit_job: ENOMEM");
+ return -1;
+ }
+ }
+
+ if (ed->state == ED_NEW || (ed->state & ED_DEL)) {
+ urb_free_priv (purb_priv);
+ err("sohci_submit_job: EINVAL");
+ return -1;
+ }
+
+ /* link the ed into a chain if is not already */
+ if (ed->state != ED_OPER)
+ ep_link (ohci, ed);
+
+ /* fill the TDs and link it to the ed */
+ td_submit_job(dev, pipe, buffer, transfer_len, setup, purb_priv, interval);
+
+ return 0;
+}
+
+/*-------------------------------------------------------------------------*/
+
+#ifdef DEBUG
+/* tell us the current USB frame number */
+
+static int sohci_get_current_frame_number (struct usb_device *usb_dev)
+{
+ ohci_t *ohci = &gohci;
+
+ return m16_swap (ohci->hcca->frame_no);
+}
+#endif
+
+/*-------------------------------------------------------------------------*
+ * ED handling functions
+ *-------------------------------------------------------------------------*/
+
+/* link an ed into one of the HC chains */
+
+static int ep_link (ohci_t *ohci, ed_t *edi)
+{
+ volatile ed_t *ed = edi;
+
+ ed->state = ED_OPER;
+
+ switch (ed->type) {
+ case PIPE_CONTROL:
+ ed->hwNextED = 0;
+ if (ohci->ed_controltail == NULL) {
+ writel (ed, &ohci->regs->ed_controlhead);
+ } else {
+ ohci->ed_controltail->hwNextED = m32_swap (ed);
+ }
+ ed->ed_prev = ohci->ed_controltail;
+ if (!ohci->ed_controltail && !ohci->ed_rm_list[0] &&
+ !ohci->ed_rm_list[1] && !ohci->sleeping) {
+ ohci->hc_control |= OHCI_CTRL_CLE;
+ writel (ohci->hc_control, &ohci->regs->control);
+ }
+ ohci->ed_controltail = edi;
+ break;
+
+ case PIPE_BULK:
+ ed->hwNextED = 0;
+ if (ohci->ed_bulktail == NULL) {
+ writel (ed, &ohci->regs->ed_bulkhead);
+ } else {
+ ohci->ed_bulktail->hwNextED = m32_swap (ed);
+ }
+ ed->ed_prev = ohci->ed_bulktail;
+ if (!ohci->ed_bulktail && !ohci->ed_rm_list[0] &&
+ !ohci->ed_rm_list[1] && !ohci->sleeping) {
+ ohci->hc_control |= OHCI_CTRL_BLE;
+ writel (ohci->hc_control, &ohci->regs->control);
+ }
+ ohci->ed_bulktail = edi;
+ break;
+ }
+ return 0;
+}
+
+/*-------------------------------------------------------------------------*/
+
+/* unlink an ed from one of the HC chains.
+ * just the link to the ed is unlinked.
+ * the link from the ed still points to another operational ed or 0
+ * so the HC can eventually finish the processing of the unlinked ed */
+
+static int ep_unlink (ohci_t *ohci, ed_t *ed)
+{
+ ed->hwINFO |= m32_swap (OHCI_ED_SKIP);
+
+ switch (ed->type) {
+ case PIPE_CONTROL:
+ if (ed->ed_prev == NULL) {
+ if (!ed->hwNextED) {
+ ohci->hc_control &= ~OHCI_CTRL_CLE;
+ writel (ohci->hc_control, &ohci->regs->control);
+ }
+ writel (m32_swap (*((__u32 *)&ed->hwNextED)), &ohci->regs->ed_controlhead);
+ } else {
+ ed->ed_prev->hwNextED = ed->hwNextED;
+ }
+ if (ohci->ed_controltail == ed) {
+ ohci->ed_controltail = ed->ed_prev;
+ } else {
+ ((ed_t *)m32_swap (*((__u32 *)&ed->hwNextED)))->ed_prev = ed->ed_prev;
+ }
+ break;
+
+ case PIPE_BULK:
+ if (ed->ed_prev == NULL) {
+ if (!ed->hwNextED) {
+ ohci->hc_control &= ~OHCI_CTRL_BLE;
+ writel (ohci->hc_control, &ohci->regs->control);
+ }
+ writel (m32_swap (*((__u32 *)&ed->hwNextED)), &ohci->regs->ed_bulkhead);
+ } else {
+ ed->ed_prev->hwNextED = ed->hwNextED;
+ }
+ if (ohci->ed_bulktail == ed) {
+ ohci->ed_bulktail = ed->ed_prev;
+ } else {
+ ((ed_t *)m32_swap (*((__u32 *)&ed->hwNextED)))->ed_prev = ed->ed_prev;
+ }
+ break;
+ }
+ ed->state = ED_UNLINK;
+ return 0;
+}
+
+
+/*-------------------------------------------------------------------------*/
+
+/* add/reinit an endpoint; this should be done once at the usb_set_configuration command,
+ * but the USB stack is a little bit stateless so we do it at every transaction
+ * if the state of the ed is ED_NEW then a dummy td is added and the state is changed to ED_UNLINK
+ * in all other cases the state is left unchanged
+ * the ed info fields are setted anyway even though most of them should not change */
+
+static ed_t * ep_add_ed (struct usb_device *usb_dev, unsigned long pipe)
+{
+ td_t *td;
+ ed_t *ed_ret;
+ volatile ed_t *ed;
+
+ ed = ed_ret = &ohci_dev.ed[(usb_pipeendpoint (pipe) << 1) |
+ (usb_pipecontrol (pipe)? 0: usb_pipeout (pipe))];
+
+ if ((ed->state & ED_DEL) || (ed->state & ED_URB_DEL)) {
+ err("ep_add_ed: pending delete");
+ /* pending delete request */
+ return NULL;
+ }
+
+ if (ed->state == ED_NEW) {
+ ed->hwINFO = m32_swap (OHCI_ED_SKIP); /* skip ed */
+ /* dummy td; end of td list for ed */
+ td = td_alloc (usb_dev);
+ ed->hwTailP = m32_swap (td);
+ ed->hwHeadP = ed->hwTailP;
+ ed->state = ED_UNLINK;
+ ed->type = usb_pipetype (pipe);
+ ohci_dev.ed_cnt++;
+ }
+
+ ed->hwINFO = m32_swap (usb_pipedevice (pipe)
+ | usb_pipeendpoint (pipe) << 7
+ | (usb_pipeisoc (pipe)? 0x8000: 0)
+ | (usb_pipecontrol (pipe)? 0: (usb_pipeout (pipe)? 0x800: 0x1000))
+ | usb_pipeslow (pipe) << 13
+ | usb_maxpacket (usb_dev, pipe) << 16);
+
+ return ed_ret;
+}
+
+/*-------------------------------------------------------------------------*
+ * TD handling functions
+ *-------------------------------------------------------------------------*/
+
+/* enqueue next TD for this URB (OHCI spec 5.2.8.2) */
+
+static void td_fill (ohci_t *ohci, unsigned int info,
+ void *data, int len,
+ struct usb_device *dev, int index, urb_priv_t *urb_priv)
+{
+ volatile td_t *td, *td_pt;
+#ifdef OHCI_FILL_TRACE
+ int i;
+#endif
+
+ if (index > urb_priv->length) {
+ err("index > length");
+ return;
+ }
+ /* use this td as the next dummy */
+ td_pt = urb_priv->td [index];
+ td_pt->hwNextTD = 0;
+
+ /* fill the old dummy TD */
+ td = urb_priv->td [index] = (td_t *)(m32_swap (urb_priv->ed->hwTailP) & ~0xf);
+
+ td->ed = urb_priv->ed;
+ td->next_dl_td = NULL;
+ td->index = index;
+ td->data = (__u32)data;
+#ifdef OHCI_FILL_TRACE
+ if ((usb_pipetype(urb_priv->pipe) == PIPE_BULK) && usb_pipeout(urb_priv->pipe)) {
+ for (i = 0; i < len; i++)
+ printf("td->data[%d] %#2x ",i, ((unsigned char *)td->data)[i]);
+ printf("\n");
+ }
+#endif
+ if (!len)
+ data = 0;
+
+ td->hwINFO = m32_swap (info);
+ td->hwCBP = m32_swap (data);
+ if (data)
+ td->hwBE = m32_swap (data + len - 1);
+ else
+ td->hwBE = 0;
+ td->hwNextTD = m32_swap (td_pt);
+ td->hwPSW [0] = m16_swap (((__u32)data & 0x0FFF) | 0xE000);
+
+ /* append to queue */
+ td->ed->hwTailP = td->hwNextTD;
+}
+
+/*-------------------------------------------------------------------------*/
+
+/* prepare all TDs of a transfer */
+
+static void td_submit_job (struct usb_device *dev, unsigned long pipe, void *buffer,
+ int transfer_len, struct devrequest *setup, urb_priv_t *urb, int interval)
+{
+ ohci_t *ohci = &gohci;
+ int data_len = transfer_len;
+ void *data;
+ int cnt = 0;
+ __u32 info = 0;
+ unsigned int toggle = 0;
+
+ /* OHCI handles the DATA-toggles itself, we just use the USB-toggle bits for reseting */
+ if(usb_gettoggle(dev, usb_pipeendpoint(pipe), usb_pipeout(pipe))) {
+ toggle = TD_T_TOGGLE;
+ } else {
+ toggle = TD_T_DATA0;
+ usb_settoggle(dev, usb_pipeendpoint(pipe), usb_pipeout(pipe), 1);
+ }
+ urb->td_cnt = 0;
+ if (data_len)
+ data = buffer;
+ else
+ data = 0;
+
+ switch (usb_pipetype (pipe)) {
+ case PIPE_BULK:
+ info = usb_pipeout (pipe)?
+ TD_CC | TD_DP_OUT : TD_CC | TD_DP_IN ;
+ while(data_len > 4096) {
+ td_fill (ohci, info | (cnt? TD_T_TOGGLE:toggle), data, 4096, dev, cnt, urb);
+ data += 4096; data_len -= 4096; cnt++;
+ }
+ info = usb_pipeout (pipe)?
+ TD_CC | TD_DP_OUT : TD_CC | TD_R | TD_DP_IN ;
+ td_fill (ohci, info | (cnt? TD_T_TOGGLE:toggle), data, data_len, dev, cnt, urb);
+ cnt++;
+
+ if (!ohci->sleeping)
+ writel (OHCI_BLF, &ohci->regs->cmdstatus); /* start bulk list */
+ break;
+
+ case PIPE_CONTROL:
+ info = TD_CC | TD_DP_SETUP | TD_T_DATA0;
+ td_fill (ohci, info, setup, 8, dev, cnt++, urb);
+ if (data_len > 0) {
+ info = usb_pipeout (pipe)?
+ TD_CC | TD_R | TD_DP_OUT | TD_T_DATA1 : TD_CC | TD_R | TD_DP_IN | TD_T_DATA1;
+ /* NOTE: mishandles transfers >8K, some >4K */
+ td_fill (ohci, info, data, data_len, dev, cnt++, urb);
+ }
+ info = usb_pipeout (pipe)?
+ TD_CC | TD_DP_IN | TD_T_DATA1: TD_CC | TD_DP_OUT | TD_T_DATA1;
+ td_fill (ohci, info, data, 0, dev, cnt++, urb);
+ if (!ohci->sleeping)
+ writel (OHCI_CLF, &ohci->regs->cmdstatus); /* start Control list */
+ break;
+ }
+ if (urb->length != cnt)
+ dbg("TD LENGTH %d != CNT %d", urb->length, cnt);
+}
+
+/*-------------------------------------------------------------------------*
+ * Done List handling functions
+ *-------------------------------------------------------------------------*/
+
+
+/* calculate the transfer length and update the urb */
+
+static void dl_transfer_length(td_t * td)
+{
+ __u32 tdINFO, tdBE, tdCBP;
+ urb_priv_t *lurb_priv = &urb_priv;
+
+ tdINFO = m32_swap (td->hwINFO);
+ tdBE = m32_swap (td->hwBE);
+ tdCBP = m32_swap (td->hwCBP);
+
+
+ if (!(usb_pipetype (lurb_priv->pipe) == PIPE_CONTROL &&
+ ((td->index == 0) || (td->index == lurb_priv->length - 1)))) {
+ if (tdBE != 0) {
+ if (td->hwCBP == 0)
+ lurb_priv->actual_length += tdBE - td->data + 1;
+ else
+ lurb_priv->actual_length += tdCBP - td->data;
+ }
+ }
+}
+
+/*-------------------------------------------------------------------------*/
+
+/* replies to the request have to be on a FIFO basis so
+ * we reverse the reversed done-list */
+
+static td_t * dl_reverse_done_list (ohci_t *ohci)
+{
+ __u32 td_list_hc;
+ td_t *td_rev = NULL;
+ td_t *td_list = NULL;
+ urb_priv_t *lurb_priv = NULL;
+
+ td_list_hc = m32_swap (ohci->hcca->done_head) & 0xfffffff0;
+ ohci->hcca->done_head = 0;
+
+ while (td_list_hc) {
+ td_list = (td_t *)td_list_hc;
+
+ if (TD_CC_GET (m32_swap (td_list->hwINFO))) {
+ lurb_priv = &urb_priv;
+ dbg(" USB-error/status: %x : %p",
+ TD_CC_GET (m32_swap (td_list->hwINFO)), td_list);
+ if (td_list->ed->hwHeadP & m32_swap (0x1)) {
+ if (lurb_priv && ((td_list->index + 1) < lurb_priv->length)) {
+ td_list->ed->hwHeadP =
+ (lurb_priv->td[lurb_priv->length - 1]->hwNextTD & m32_swap (0xfffffff0)) |
+ (td_list->ed->hwHeadP & m32_swap (0x2));
+ lurb_priv->td_cnt += lurb_priv->length - td_list->index - 1;
+ } else
+ td_list->ed->hwHeadP &= m32_swap (0xfffffff2);
+ }
+ }
+
+ td_list->next_dl_td = td_rev;
+ td_rev = td_list;
+ td_list_hc = m32_swap (td_list->hwNextTD) & 0xfffffff0;
+ }
+ return td_list;
+}
+
+/*-------------------------------------------------------------------------*/
+
+/* td done list */
+static int dl_done_list (ohci_t *ohci, td_t *td_list)
+{
+ td_t *td_list_next = NULL;
+ ed_t *ed;
+ int cc = 0;
+ int stat = 0;
+ /* urb_t *urb; */
+ urb_priv_t *lurb_priv;
+ __u32 tdINFO, edHeadP, edTailP;
+
+ while (td_list) {
+ td_list_next = td_list->next_dl_td;
+
+ lurb_priv = &urb_priv;
+ tdINFO = m32_swap (td_list->hwINFO);
+
+ ed = td_list->ed;
+
+ dl_transfer_length(td_list);
+
+ /* error code of transfer */
+ cc = TD_CC_GET (tdINFO);
+ if (cc != 0) {
+ dbg("ConditionCode %#x", cc);
+ stat = cc_to_error[cc];
+ }
+
+ if (ed->state != ED_NEW) {
+ edHeadP = m32_swap (ed->hwHeadP) & 0xfffffff0;
+ edTailP = m32_swap (ed->hwTailP);
+
+ /* unlink eds if they are not busy */
+ if ((edHeadP == edTailP) && (ed->state == ED_OPER))
+ ep_unlink (ohci, ed);
+ }
+
+ td_list = td_list_next;
+ }
+ return stat;
+}
+
+/*-------------------------------------------------------------------------*
+ * Virtual Root Hub
+ *-------------------------------------------------------------------------*/
+
+/* Device descriptor */
+static __u8 root_hub_dev_des[] =
+{
+ 0x12, /* __u8 bLength; */
+ 0x01, /* __u8 bDescriptorType; Device */
+ 0x10, /* __u16 bcdUSB; v1.1 */
+ 0x01,
+ 0x09, /* __u8 bDeviceClass; HUB_CLASSCODE */
+ 0x00, /* __u8 bDeviceSubClass; */
+ 0x00, /* __u8 bDeviceProtocol; */
+ 0x08, /* __u8 bMaxPacketSize0; 8 Bytes */
+ 0x00, /* __u16 idVendor; */
+ 0x00,
+ 0x00, /* __u16 idProduct; */
+ 0x00,
+ 0x00, /* __u16 bcdDevice; */
+ 0x00,
+ 0x00, /* __u8 iManufacturer; */
+ 0x01, /* __u8 iProduct; */
+ 0x00, /* __u8 iSerialNumber; */
+ 0x01 /* __u8 bNumConfigurations; */
+};
+
+
+/* Configuration descriptor */
+static __u8 root_hub_config_des[] =
+{
+ 0x09, /* __u8 bLength; */
+ 0x02, /* __u8 bDescriptorType; Configuration */
+ 0x19, /* __u16 wTotalLength; */
+ 0x00,
+ 0x01, /* __u8 bNumInterfaces; */
+ 0x01, /* __u8 bConfigurationValue; */
+ 0x00, /* __u8 iConfiguration; */
+ 0x40, /* __u8 bmAttributes;
+ Bit 7: Bus-powered, 6: Self-powered, 5 Remote-wakwup, 4..0: resvd */
+ 0x00, /* __u8 MaxPower; */
+
+ /* interface */
+ 0x09, /* __u8 if_bLength; */
+ 0x04, /* __u8 if_bDescriptorType; Interface */
+ 0x00, /* __u8 if_bInterfaceNumber; */
+ 0x00, /* __u8 if_bAlternateSetting; */
+ 0x01, /* __u8 if_bNumEndpoints; */
+ 0x09, /* __u8 if_bInterfaceClass; HUB_CLASSCODE */
+ 0x00, /* __u8 if_bInterfaceSubClass; */
+ 0x00, /* __u8 if_bInterfaceProtocol; */
+ 0x00, /* __u8 if_iInterface; */
+
+ /* endpoint */
+ 0x07, /* __u8 ep_bLength; */
+ 0x05, /* __u8 ep_bDescriptorType; Endpoint */
+ 0x81, /* __u8 ep_bEndpointAddress; IN Endpoint 1 */
+ 0x03, /* __u8 ep_bmAttributes; Interrupt */
+ 0x02, /* __u16 ep_wMaxPacketSize; ((MAX_ROOT_PORTS + 1) / 8 */
+ 0x00,
+ 0xff /* __u8 ep_bInterval; 255 ms */
+};
+
+static unsigned char root_hub_str_index0[] =
+{
+ 0x04, /* __u8 bLength; */
+ 0x03, /* __u8 bDescriptorType; String-descriptor */
+ 0x09, /* __u8 lang ID */
+ 0x04, /* __u8 lang ID */
+};
+
+static unsigned char root_hub_str_index1[] =
+{
+ 28, /* __u8 bLength; */
+ 0x03, /* __u8 bDescriptorType; String-descriptor */
+ 'O', /* __u8 Unicode */
+ 0, /* __u8 Unicode */
+ 'H', /* __u8 Unicode */
+ 0, /* __u8 Unicode */
+ 'C', /* __u8 Unicode */
+ 0, /* __u8 Unicode */
+ 'I', /* __u8 Unicode */
+ 0, /* __u8 Unicode */
+ ' ', /* __u8 Unicode */
+ 0, /* __u8 Unicode */
+ 'R', /* __u8 Unicode */
+ 0, /* __u8 Unicode */
+ 'o', /* __u8 Unicode */
+ 0, /* __u8 Unicode */
+ 'o', /* __u8 Unicode */
+ 0, /* __u8 Unicode */
+ 't', /* __u8 Unicode */
+ 0, /* __u8 Unicode */
+ ' ', /* __u8 Unicode */
+ 0, /* __u8 Unicode */
+ 'H', /* __u8 Unicode */
+ 0, /* __u8 Unicode */
+ 'u', /* __u8 Unicode */
+ 0, /* __u8 Unicode */
+ 'b', /* __u8 Unicode */
+ 0, /* __u8 Unicode */
+};
+
+/* Hub class-specific descriptor is constructed dynamically */
+
+
+/*-------------------------------------------------------------------------*/
+
+#define OK(x) len = (x); break
+#ifdef DEBUG
+#define WR_RH_STAT(x) {info("WR:status %#8x", (x));writel((x), &gohci.regs->roothub.status);}
+#define WR_RH_PORTSTAT(x) {info("WR:portstatus[%d] %#8x", wIndex-1, (x));writel((x), &gohci.regs->roothub.portstatus[wIndex-1]);}
+#else
+#define WR_RH_STAT(x) writel((x), &gohci.regs->roothub.status)
+#define WR_RH_PORTSTAT(x) writel((x), &gohci.regs->roothub.portstatus[wIndex-1])
+#endif
+#define RD_RH_STAT roothub_status(&gohci)
+#define RD_RH_PORTSTAT roothub_portstatus(&gohci,wIndex-1)
+
+/* request to virtual root hub */
+
+int rh_check_port_status(ohci_t *controller)
+{
+ __u32 temp, ndp, i;
+ int res;
+
+ res = -1;
+ temp = roothub_a (controller);
+ ndp = (temp & RH_A_NDP);
+#ifdef CONFIG_AT91C_PQFP_UHPBUG
+ ndp = (ndp == 2) ? 1:0;
+#endif
+
+ for (i = 0; i < ndp; i++) {
+ temp = roothub_portstatus (controller, i);
+ /* check for a device disconnect */
+ if (((temp & (RH_PS_PESC | RH_PS_CSC)) ==
+ (RH_PS_PESC | RH_PS_CSC)) &&
+ ((temp & RH_PS_CCS) == 0)) {
+ res = i;
+ break;
+ }
+ }
+ return res;
+}
+
+static int ohci_submit_rh_msg(struct usb_device *dev, unsigned long pipe,
+ void *buffer, int transfer_len, struct devrequest *cmd)
+{
+ void * data = buffer;
+ int leni = transfer_len;
+ int len = 0;
+ int stat = 0;
+ __u32 datab[4];
+ __u8 *data_buf = (__u8 *)datab;
+ __u16 bmRType_bReq;
+ __u16 wValue;
+ __u16 wIndex;
+ __u16 wLength;
+
+#ifdef DEBUG
+urb_priv.actual_length = 0;
+pkt_print(dev, pipe, buffer, transfer_len, cmd, "SUB(rh)", usb_pipein(pipe));
+#else
+ wait_ms(1);
+#endif
+ if ((pipe & PIPE_INTERRUPT) == PIPE_INTERRUPT) {
+ info("Root-Hub submit IRQ: NOT implemented");
+ return 0;
+ }
+
+ bmRType_bReq = cmd->requesttype | (cmd->request << 8);
+ wValue = m16_swap (cmd->value);
+ wIndex = m16_swap (cmd->index);
+ wLength = m16_swap (cmd->length);
+
+ info("Root-Hub: adr: %2x cmd(%1x): %08x %04x %04x %04x",
+ dev->devnum, 8, bmRType_bReq, wValue, wIndex, wLength);
+
+ switch (bmRType_bReq) {
+ /* Request Destination:
+ without flags: Device,
+ RH_INTERFACE: interface,
+ RH_ENDPOINT: endpoint,
+ RH_CLASS means HUB here,
+ RH_OTHER | RH_CLASS almost ever means HUB_PORT here
+ */
+
+ case RH_GET_STATUS:
+ *(__u16 *) data_buf = m16_swap (1); OK (2);
+ case RH_GET_STATUS | RH_INTERFACE:
+ *(__u16 *) data_buf = m16_swap (0); OK (2);
+ case RH_GET_STATUS | RH_ENDPOINT:
+ *(__u16 *) data_buf = m16_swap (0); OK (2);
+ case RH_GET_STATUS | RH_CLASS:
+ *(__u32 *) data_buf = m32_swap (
+ RD_RH_STAT & ~(RH_HS_CRWE | RH_HS_DRWE));
+ OK (4);
+ case RH_GET_STATUS | RH_OTHER | RH_CLASS:
+ *(__u32 *) data_buf = m32_swap (RD_RH_PORTSTAT); OK (4);
+
+ case RH_CLEAR_FEATURE | RH_ENDPOINT:
+ switch (wValue) {
+ case (RH_ENDPOINT_STALL): OK (0);
+ }
+ break;
+
+ case RH_CLEAR_FEATURE | RH_CLASS:
+ switch (wValue) {
+ case RH_C_HUB_LOCAL_POWER:
+ OK(0);
+ case (RH_C_HUB_OVER_CURRENT):
+ WR_RH_STAT(RH_HS_OCIC); OK (0);
+ }
+ break;
+
+ case RH_CLEAR_FEATURE | RH_OTHER | RH_CLASS:
+ switch (wValue) {
+ case (RH_PORT_ENABLE):
+ WR_RH_PORTSTAT (RH_PS_CCS ); OK (0);
+ case (RH_PORT_SUSPEND):
+ WR_RH_PORTSTAT (RH_PS_POCI); OK (0);
+ case (RH_PORT_POWER):
+ WR_RH_PORTSTAT (RH_PS_LSDA); OK (0);
+ case (RH_C_PORT_CONNECTION):
+ WR_RH_PORTSTAT (RH_PS_CSC ); OK (0);
+ case (RH_C_PORT_ENABLE):
+ WR_RH_PORTSTAT (RH_PS_PESC); OK (0);
+ case (RH_C_PORT_SUSPEND):
+ WR_RH_PORTSTAT (RH_PS_PSSC); OK (0);
+ case (RH_C_PORT_OVER_CURRENT):
+ WR_RH_PORTSTAT (RH_PS_OCIC); OK (0);
+ case (RH_C_PORT_RESET):
+ WR_RH_PORTSTAT (RH_PS_PRSC); OK (0);
+ }
+ break;
+
+ case RH_SET_FEATURE | RH_OTHER | RH_CLASS:
+ switch (wValue) {
+ case (RH_PORT_SUSPEND):
+ WR_RH_PORTSTAT (RH_PS_PSS ); OK (0);
+ case (RH_PORT_RESET): /* BUG IN HUP CODE *********/
+ if (RD_RH_PORTSTAT & RH_PS_CCS)
+ WR_RH_PORTSTAT (RH_PS_PRS);
+ OK (0);
+ case (RH_PORT_POWER):
+ WR_RH_PORTSTAT (RH_PS_PPS ); OK (0);
+ case (RH_PORT_ENABLE): /* BUG IN HUP CODE *********/
+ if (RD_RH_PORTSTAT & RH_PS_CCS)
+ WR_RH_PORTSTAT (RH_PS_PES );
+ OK (0);
+ }
+ break;
+
+ case RH_SET_ADDRESS: gohci.rh.devnum = wValue; OK(0);
+
+ case RH_GET_DESCRIPTOR:
+ switch ((wValue & 0xff00) >> 8) {
+ case (0x01): /* device descriptor */
+ len = min_t(unsigned int,
+ leni,
+ min_t(unsigned int,
+ sizeof (root_hub_dev_des),
+ wLength));
+ data_buf = root_hub_dev_des; OK(len);
+ case (0x02): /* configuration descriptor */
+ len = min_t(unsigned int,
+ leni,
+ min_t(unsigned int,
+ sizeof (root_hub_config_des),
+ wLength));
+ data_buf = root_hub_config_des; OK(len);
+ case (0x03): /* string descriptors */
+ if(wValue==0x0300) {
+ len = min_t(unsigned int,
+ leni,
+ min_t(unsigned int,
+ sizeof (root_hub_str_index0),
+ wLength));
+ data_buf = root_hub_str_index0;
+ OK(len);
+ }
+ if(wValue==0x0301) {
+ len = min_t(unsigned int,
+ leni,
+ min_t(unsigned int,
+ sizeof (root_hub_str_index1),
+ wLength));
+ data_buf = root_hub_str_index1;
+ OK(len);
+ }
+ default:
+ stat = USB_ST_STALLED;
+ }
+ break;
+
+ case RH_GET_DESCRIPTOR | RH_CLASS:
+ {
+ __u32 temp = roothub_a (&gohci);
+
+ data_buf [0] = 9; /* min length; */
+ data_buf [1] = 0x29;
+ data_buf [2] = temp & RH_A_NDP;
+#ifdef CONFIG_AT91C_PQFP_UHPBUG
+ data_buf [2] = (data_buf [2] == 2) ? 1:0;
+#endif
+ data_buf [3] = 0;
+ if (temp & RH_A_PSM) /* per-port power switching? */
+ data_buf [3] |= 0x1;
+ if (temp & RH_A_NOCP) /* no overcurrent reporting? */
+ data_buf [3] |= 0x10;
+ else if (temp & RH_A_OCPM) /* per-port overcurrent reporting? */
+ data_buf [3] |= 0x8;
+
+ /* corresponds to data_buf[4-7] */
+ datab [1] = 0;
+ data_buf [5] = (temp & RH_A_POTPGT) >> 24;
+ temp = roothub_b (&gohci);
+ data_buf [7] = temp & RH_B_DR;
+ if (data_buf [2] < 7) {
+ data_buf [8] = 0xff;
+ } else {
+ data_buf [0] += 2;
+ data_buf [8] = (temp & RH_B_DR) >> 8;
+ data_buf [10] = data_buf [9] = 0xff;
+ }
+
+ len = min_t(unsigned int, leni,
+ min_t(unsigned int, data_buf [0], wLength));
+ OK (len);
+ }
+
+ case RH_GET_CONFIGURATION: *(__u8 *) data_buf = 0x01; OK (1);
+
+ case RH_SET_CONFIGURATION: WR_RH_STAT (0x10000); OK (0);
+
+ default:
+ dbg ("unsupported root hub command");
+ stat = USB_ST_STALLED;
+ }
+
+#ifdef DEBUG
+ ohci_dump_roothub (&gohci, 1);
+#else
+ wait_ms(1);
+#endif
+
+ len = min_t(int, len, leni);
+ if (data != data_buf)
+ memcpy (data, data_buf, len);
+ dev->act_len = len;
+ dev->status = stat;
+
+#ifdef DEBUG
+ if (transfer_len)
+ urb_priv.actual_length = transfer_len;
+ pkt_print(dev, pipe, buffer, transfer_len, cmd, "RET(rh)", 0/*usb_pipein(pipe)*/);
+#else
+ wait_ms(1);
+#endif
+
+ return stat;
+}
+
+/*-------------------------------------------------------------------------*/
+
+/* common code for handling submit messages - used for all but root hub */
+/* accesses. */
+int submit_common_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
+ int transfer_len, struct devrequest *setup, int interval)
+{
+ int stat = 0;
+ int maxsize = usb_maxpacket(dev, pipe);
+ int timeout;
+
+ /* device pulled? Shortcut the action. */
+ if (devgone == dev) {
+ dev->status = USB_ST_CRC_ERR;
+ return 0;
+ }
+
+#ifdef DEBUG
+ urb_priv.actual_length = 0;
+ pkt_print(dev, pipe, buffer, transfer_len, setup, "SUB", usb_pipein(pipe));
+#else
+ wait_ms(1);
+#endif
+ if (!maxsize) {
+ err("submit_common_message: pipesize for pipe %lx is zero",
+ pipe);
+ return -1;
+ }
+
+ if (sohci_submit_job(dev, pipe, buffer, transfer_len, setup, interval) < 0) {
+ err("sohci_submit_job failed");
+ return -1;
+ }
+
+ wait_ms(10);
+ /* ohci_dump_status(&gohci); */
+
+ /* allow more time for a BULK device to react - some are slow */
+#define BULK_TO 5000 /* timeout in milliseconds */
+ if (usb_pipetype (pipe) == PIPE_BULK)
+ timeout = BULK_TO;
+ else
+ timeout = 100;
+
+ /* wait for it to complete */
+ for (;;) {
+ /* check whether the controller is done */
+ stat = hc_interrupt();
+ if (stat < 0) {
+ stat = USB_ST_CRC_ERR;
+ break;
+ }
+ if (stat >= 0 && stat != 0xff) {
+ /* 0xff is returned for an SF-interrupt */
+ break;
+ }
+ if (--timeout) {
+ wait_ms(1);
+ } else {
+ err("CTL:TIMEOUT ");
+ stat = USB_ST_CRC_ERR;
+ break;
+ }
+ }
+ /* we got an Root Hub Status Change interrupt */
+ if (got_rhsc) {
+#ifdef DEBUG
+ ohci_dump_roothub (&gohci, 1);
+#endif
+ got_rhsc = 0;
+ /* abuse timeout */
+ timeout = rh_check_port_status(&gohci);
+ if (timeout >= 0) {
+#if 0 /* this does nothing useful, but leave it here in case that changes */
+ /* the called routine adds 1 to the passed value */
+ usb_hub_port_connect_change(gohci.rh.dev, timeout - 1);
+#endif
+ /*
+ * XXX
+ * This is potentially dangerous because it assumes
+ * that only one device is ever plugged in!
+ */
+ devgone = dev;
+ }
+ }
+
+ dev->status = stat;
+ dev->act_len = transfer_len;
+
+#ifdef DEBUG
+ pkt_print(dev, pipe, buffer, transfer_len, setup, "RET(ctlr)", usb_pipein(pipe));
+#else
+ wait_ms(1);
+#endif
+
+ /* free TDs in urb_priv */
+ urb_free_priv (&urb_priv);
+ return 0;
+}
+
+/* submit routines called from usb.c */
+int submit_bulk_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
+ int transfer_len)
+{
+ info("submit_bulk_msg");
+ return submit_common_msg(dev, pipe, buffer, transfer_len, NULL, 0);
+}
+
+int submit_control_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
+ int transfer_len, struct devrequest *setup)
+{
+ int maxsize = usb_maxpacket(dev, pipe);
+
+ info("submit_control_msg");
+#ifdef DEBUG
+ urb_priv.actual_length = 0;
+ pkt_print(dev, pipe, buffer, transfer_len, setup, "SUB", usb_pipein(pipe));
+#else
+ wait_ms(1);
+#endif
+ if (!maxsize) {
+ err("submit_control_message: pipesize for pipe %lx is zero",
+ pipe);
+ return -1;
+ }
+ if (((pipe >> 8) & 0x7f) == gohci.rh.devnum) {
+ gohci.rh.dev = dev;
+ /* root hub - redirect */
+ return ohci_submit_rh_msg(dev, pipe, buffer, transfer_len,
+ setup);
+ }
+
+ return submit_common_msg(dev, pipe, buffer, transfer_len, setup, 0);
+}
+
+int submit_int_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
+ int transfer_len, int interval)
+{
+ info("submit_int_msg");
+ return -1;
+}
+
+/*-------------------------------------------------------------------------*
+ * HC functions
+ *-------------------------------------------------------------------------*/
+
+/* reset the HC and BUS */
+
+static int hc_reset (ohci_t *ohci)
+{
+ int timeout = 30;
+ int smm_timeout = 50; /* 0,5 sec */
+
+ dbg("%s\n", __FUNCTION__);
+
+ if (readl (&ohci->regs->control) & OHCI_CTRL_IR) { /* SMM owns the HC */
+ writel (OHCI_OCR, &ohci->regs->cmdstatus); /* request ownership */
+ info("USB HC TakeOver from SMM");
+ while (readl (&ohci->regs->control) & OHCI_CTRL_IR) {
+ wait_ms (10);
+ if (--smm_timeout == 0) {
+ err("USB HC TakeOver failed!");
+ return -1;
+ }
+ }
+ }
+
+ /* Disable HC interrupts */
+ writel (OHCI_INTR_MIE, &ohci->regs->intrdisable);
+
+ dbg("USB HC reset_hc usb-%s: ctrl = 0x%X ;\n",
+ ohci->slot_name,
+ readl(&ohci->regs->control));
+
+ /* Reset USB (needed by some controllers) */
+ writel (0, &ohci->regs->control);
+
+ /* HC Reset requires max 10 us delay */
+ writel (OHCI_HCR, &ohci->regs->cmdstatus);
+ while ((readl (&ohci->regs->cmdstatus) & OHCI_HCR) != 0) {
+ if (--timeout == 0) {
+ err("USB HC reset timed out!");
+ return -1;
+ }
+ udelay (1);
+ }
+ return 0;
+}
+
+/*-------------------------------------------------------------------------*/
+
+/* Start an OHCI controller, set the BUS operational
+ * enable interrupts
+ * connect the virtual root hub */
+
+static int hc_start (ohci_t * ohci)
+{
+ __u32 mask;
+ unsigned int fminterval;
+
+ ohci->disabled = 1;
+
+ /* Tell the controller where the control and bulk lists are
+ * The lists are empty now. */
+
+ writel (0, &ohci->regs->ed_controlhead);
+ writel (0, &ohci->regs->ed_bulkhead);
+
+ writel ((__u32)ohci->hcca, &ohci->regs->hcca); /* a reset clears this */
+
+ fminterval = 0x2edf;
+ writel ((fminterval * 9) / 10, &ohci->regs->periodicstart);
+ fminterval |= ((((fminterval - 210) * 6) / 7) << 16);
+ writel (fminterval, &ohci->regs->fminterval);
+ writel (0x628, &ohci->regs->lsthresh);
+
+ /* start controller operations */
+ ohci->hc_control = OHCI_CONTROL_INIT | OHCI_USB_OPER;
+ ohci->disabled = 0;
+ writel (ohci->hc_control, &ohci->regs->control);
+
+ /* disable all interrupts */
+ mask = (OHCI_INTR_SO | OHCI_INTR_WDH | OHCI_INTR_SF | OHCI_INTR_RD |
+ OHCI_INTR_UE | OHCI_INTR_FNO | OHCI_INTR_RHSC |
+ OHCI_INTR_OC | OHCI_INTR_MIE);
+ writel (mask, &ohci->regs->intrdisable);
+ /* clear all interrupts */
+ mask &= ~OHCI_INTR_MIE;
+ writel (mask, &ohci->regs->intrstatus);
+ /* Choose the interrupts we care about now - but w/o MIE */
+ mask = OHCI_INTR_RHSC | OHCI_INTR_UE | OHCI_INTR_WDH | OHCI_INTR_SO;
+ writel (mask, &ohci->regs->intrenable);
+
+#ifdef OHCI_USE_NPS
+ /* required for AMD-756 and some Mac platforms */
+ writel ((roothub_a (ohci) | RH_A_NPS) & ~RH_A_PSM,
+ &ohci->regs->roothub.a);
+ writel (RH_HS_LPSC, &ohci->regs->roothub.status);
+#endif /* OHCI_USE_NPS */
+
+#define mdelay(n) ({unsigned long msec=(n); while (msec--) udelay(1000);})
+ /* POTPGT delay is bits 24-31, in 2 ms units. */
+ mdelay ((roothub_a (ohci) >> 23) & 0x1fe);
+
+ /* connect the virtual root hub */
+ ohci->rh.devnum = 0;
+
+ return 0;
+}
+
+/*-------------------------------------------------------------------------*/
+
+/* an interrupt happens */
+
+static int
+hc_interrupt (void)
+{
+ ohci_t *ohci = &gohci;
+ struct ohci_regs *regs = ohci->regs;
+ int ints;
+ int stat = -1;
+
+ if ((ohci->hcca->done_head != 0) && !(m32_swap (ohci->hcca->done_head) & 0x01)) {
+ ints = OHCI_INTR_WDH;
+ } else {
+ ints = readl (&regs->intrstatus);
+ }
+
+ /* dbg("Interrupt: %x frame: %x", ints, le16_to_cpu (ohci->hcca->frame_no)); */
+
+ if (ints & OHCI_INTR_RHSC) {
+ got_rhsc = 1;
+ }
+
+ if (ints & OHCI_INTR_UE) {
+ ohci->disabled++;
+ err ("OHCI Unrecoverable Error, controller usb-%s disabled",
+ ohci->slot_name);
+ /* e.g. due to PCI Master/Target Abort */
+
+#ifdef DEBUG
+ ohci_dump (ohci, 1);
+#else
+ wait_ms(1);
+#endif
+ /* FIXME: be optimistic, hope that bug won't repeat often. */
+ /* Make some non-interrupt context restart the controller. */
+ /* Count and limit the retries though; either hardware or */
+ /* software errors can go forever... */
+ hc_reset (ohci);
+ return -1;
+ }
+
+ if (ints & OHCI_INTR_WDH) {
+ wait_ms(1);
+ writel (OHCI_INTR_WDH, &regs->intrdisable);
+ stat = dl_done_list (&gohci, dl_reverse_done_list (&gohci));
+ writel (OHCI_INTR_WDH, &regs->intrenable);
+ }
+
+ if (ints & OHCI_INTR_SO) {
+ dbg("USB Schedule overrun\n");
+ writel (OHCI_INTR_SO, &regs->intrenable);
+ stat = -1;
+ }
+
+ /* FIXME: this assumes SOF (1/ms) interrupts don't get lost... */
+ if (ints & OHCI_INTR_SF) {
+ unsigned int frame = m16_swap (ohci->hcca->frame_no) & 1;
+ wait_ms(1);
+ writel (OHCI_INTR_SF, &regs->intrdisable);
+ if (ohci->ed_rm_list[frame] != NULL)
+ writel (OHCI_INTR_SF, &regs->intrenable);
+ stat = 0xff;
+ }
+
+ writel (ints, &regs->intrstatus);
+ return stat;
+}
+
+/*-------------------------------------------------------------------------*/
+
+/*-------------------------------------------------------------------------*/
+
+/* De-allocate all resources.. */
+
+static void hc_release_ohci (ohci_t *ohci)
+{
+ dbg ("USB HC release ohci usb-%s", ohci->slot_name);
+
+ if (!ohci->disabled)
+ hc_reset (ohci);
+}
+
+/*-------------------------------------------------------------------------*/
+
+/*
+ * low level initalisation routine, called from usb.c
+ */
+static char ohci_inited = 0;
+
+int usb_lowlevel_init(void)
+{
+ /*
+ * Enable USB host clock.
+ */
+ *AT91C_PMC_SCER = AT91C_PMC_UHP; /* 48MHz clock enabled for UHP */
+ *AT91C_PMC_PCER = 1 << AT91C_ID_UHP; /* Peripheral Clock Enable Register */
+
+ memset (&gohci, 0, sizeof (ohci_t));
+ memset (&urb_priv, 0, sizeof (urb_priv_t));
+
+ /* align the storage */
+ if ((__u32)&ghcca[0] & 0xff) {
+ err("HCCA not aligned!!");
+ return -1;
+ }
+ phcca = &ghcca[0];
+ info("aligned ghcca %p", phcca);
+ memset(&ohci_dev, 0, sizeof(struct ohci_device));
+ if ((__u32)&ohci_dev.ed[0] & 0x7) {
+ err("EDs not aligned!!");
+ return -1;
+ }
+ memset(gtd, 0, sizeof(td_t) * (NUM_TD + 1));
+ if ((__u32)gtd & 0x7) {
+ err("TDs not aligned!!");
+ return -1;
+ }
+ ptd = gtd;
+ gohci.hcca = phcca;
+ memset (phcca, 0, sizeof (struct ohci_hcca));
+
+ gohci.disabled = 1;
+ gohci.sleeping = 0;
+ gohci.irq = -1;
+ gohci.regs = (struct ohci_regs *)AT91_USB_HOST_BASE;
+
+ gohci.flags = 0;
+ gohci.slot_name = "at91rm9200";
+
+ if (hc_reset (&gohci) < 0) {
+ hc_release_ohci (&gohci);
+ /* Initialization failed */
+ *AT91C_PMC_PCER = AT91C_ID_UHP;
+ *AT91C_PMC_SCDR = 1 << AT91C_PMC_UHP; /* 48MHz clock disabled for UHP */
+ return -1;
+ }
+
+ /* FIXME this is a second HC reset; why?? */
+/* writel (gohci.hc_control = OHCI_USB_RESET, &gohci.regs->control);
+ wait_ms (10);*/
+
+ if (hc_start (&gohci) < 0) {
+ err ("can't start usb-%s", gohci.slot_name);
+ hc_release_ohci (&gohci);
+ /* Initialization failed */
+ *AT91C_PMC_PCER = AT91C_ID_UHP;
+ *AT91C_PMC_SCDR = 1 << AT91C_PMC_UHP; /* 48MHz clock disabled for UHP */
+ return -1;
+ }
+
+#ifdef DEBUG
+ ohci_dump (&gohci, 1);
+#else
+ wait_ms(1);
+#endif
+ ohci_inited = 1;
+ return 0;
+}
+
+int usb_lowlevel_stop(void)
+{
+ /* this gets called really early - before the controller has */
+ /* even been initialized! */
+ if (!ohci_inited)
+ return 0;
+ /* TODO release any interrupts, etc. */
+ /* call hc_release_ohci() here ? */
+ hc_reset (&gohci);
+ /* may not want to do this */
+ *AT91C_PMC_PCER = 1 << AT91C_ID_UHP;
+ *AT91C_PMC_SCDR = 1 << AT91C_PMC_UHP; /* 48MHz clock disabled for UHP */
+ return 0;
+}
+
+#endif /* CONFIG_USB_OHCI */
diff --git a/cpu/arm920t/at91rm9200/usb_ohci.h b/cpu/arm920t/at91rm9200/usb_ohci.h
new file mode 100755
index 0000000..ecb4e93
--- /dev/null
+++ b/cpu/arm920t/at91rm9200/usb_ohci.h
@@ -0,0 +1,419 @@
+/*
+ * URB OHCI HCD (Host Controller Driver) for USB.
+ *
+ * (C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at>
+ * (C) Copyright 2000-2001 David Brownell <dbrownell@users.sourceforge.net>
+ *
+ * usb-ohci.h
+ */
+
+
+static int cc_to_error[16] = {
+
+/* mapping of the OHCI CC status to error codes */
+ /* No Error */ 0,
+ /* CRC Error */ USB_ST_CRC_ERR,
+ /* Bit Stuff */ USB_ST_BIT_ERR,
+ /* Data Togg */ USB_ST_CRC_ERR,
+ /* Stall */ USB_ST_STALLED,
+ /* DevNotResp */ -1,
+ /* PIDCheck */ USB_ST_BIT_ERR,
+ /* UnExpPID */ USB_ST_BIT_ERR,
+ /* DataOver */ USB_ST_BUF_ERR,
+ /* DataUnder */ USB_ST_BUF_ERR,
+ /* reservd */ -1,
+ /* reservd */ -1,
+ /* BufferOver */ USB_ST_BUF_ERR,
+ /* BuffUnder */ USB_ST_BUF_ERR,
+ /* Not Access */ -1,
+ /* Not Access */ -1
+};
+
+/* ED States */
+
+#define ED_NEW 0x00
+#define ED_UNLINK 0x01
+#define ED_OPER 0x02
+#define ED_DEL 0x04
+#define ED_URB_DEL 0x08
+
+/* usb_ohci_ed */
+struct ed {
+ __u32 hwINFO;
+ __u32 hwTailP;
+ __u32 hwHeadP;
+ __u32 hwNextED;
+
+ struct ed *ed_prev;
+ __u8 int_period;
+ __u8 int_branch;
+ __u8 int_load;
+ __u8 int_interval;
+ __u8 state;
+ __u8 type;
+ __u16 last_iso;
+ struct ed *ed_rm_list;
+
+ struct usb_device *usb_dev;
+ __u32 unused[3];
+} __attribute((aligned(16)));
+typedef struct ed ed_t;
+
+
+/* TD info field */
+#define TD_CC 0xf0000000
+#define TD_CC_GET(td_p) ((td_p >>28) & 0x0f)
+#define TD_CC_SET(td_p, cc) (td_p) = ((td_p) & 0x0fffffff) | (((cc) & 0x0f) << 28)
+#define TD_EC 0x0C000000
+#define TD_T 0x03000000
+#define TD_T_DATA0 0x02000000
+#define TD_T_DATA1 0x03000000
+#define TD_T_TOGGLE 0x00000000
+#define TD_R 0x00040000
+#define TD_DI 0x00E00000
+#define TD_DI_SET(X) (((X) & 0x07)<< 21)
+#define TD_DP 0x00180000
+#define TD_DP_SETUP 0x00000000
+#define TD_DP_IN 0x00100000
+#define TD_DP_OUT 0x00080000
+
+#define TD_ISO 0x00010000
+#define TD_DEL 0x00020000
+
+/* CC Codes */
+#define TD_CC_NOERROR 0x00
+#define TD_CC_CRC 0x01
+#define TD_CC_BITSTUFFING 0x02
+#define TD_CC_DATATOGGLEM 0x03
+#define TD_CC_STALL 0x04
+#define TD_DEVNOTRESP 0x05
+#define TD_PIDCHECKFAIL 0x06
+#define TD_UNEXPECTEDPID 0x07
+#define TD_DATAOVERRUN 0x08
+#define TD_DATAUNDERRUN 0x09
+#define TD_BUFFEROVERRUN 0x0C
+#define TD_BUFFERUNDERRUN 0x0D
+#define TD_NOTACCESSED 0x0F
+
+
+#define MAXPSW 1
+
+struct td {
+ __u32 hwINFO;
+ __u32 hwCBP; /* Current Buffer Pointer */
+ __u32 hwNextTD; /* Next TD Pointer */
+ __u32 hwBE; /* Memory Buffer End Pointer */
+
+ __u16 hwPSW[MAXPSW];
+ __u8 unused;
+ __u8 index;
+ struct ed *ed;
+ struct td *next_dl_td;
+ struct usb_device *usb_dev;
+ int transfer_len;
+ __u32 data;
+
+ __u32 unused2[2];
+} __attribute((aligned(32)));
+typedef struct td td_t;
+
+#define OHCI_ED_SKIP (1 << 14)
+
+/*
+ * The HCCA (Host Controller Communications Area) is a 256 byte
+ * structure defined in the OHCI spec. that the host controller is
+ * told the base address of. It must be 256-byte aligned.
+ */
+
+#define NUM_INTS 32 /* part of the OHCI standard */
+struct ohci_hcca {
+ __u32 int_table[NUM_INTS]; /* Interrupt ED table */
+ __u16 frame_no; /* current frame number */
+ __u16 pad1; /* set to 0 on each frame_no change */
+ __u32 done_head; /* info returned for an interrupt */
+ u8 reserved_for_hc[116];
+} __attribute((aligned(256)));
+
+
+/*
+ * Maximum number of root hub ports.
+ */
+#define MAX_ROOT_PORTS 15 /* maximum OHCI root hub ports */
+
+/*
+ * This is the structure of the OHCI controller's memory mapped I/O
+ * region. This is Memory Mapped I/O. You must use the readl() and
+ * writel() macros defined in asm/io.h to access these!!
+ */
+struct ohci_regs {
+ /* control and status registers */
+ __u32 revision;
+ __u32 control;
+ __u32 cmdstatus;
+ __u32 intrstatus;
+ __u32 intrenable;
+ __u32 intrdisable;
+ /* memory pointers */
+ __u32 hcca;
+ __u32 ed_periodcurrent;
+ __u32 ed_controlhead;
+ __u32 ed_controlcurrent;
+ __u32 ed_bulkhead;
+ __u32 ed_bulkcurrent;
+ __u32 donehead;
+ /* frame counters */
+ __u32 fminterval;
+ __u32 fmremaining;
+ __u32 fmnumber;
+ __u32 periodicstart;
+ __u32 lsthresh;
+ /* Root hub ports */
+ struct ohci_roothub_regs {
+ __u32 a;
+ __u32 b;
+ __u32 status;
+ __u32 portstatus[MAX_ROOT_PORTS];
+ } roothub;
+} __attribute((aligned(32)));
+
+
+/* OHCI CONTROL AND STATUS REGISTER MASKS */
+
+/*
+ * HcControl (control) register masks
+ */
+#define OHCI_CTRL_CBSR (3 << 0) /* control/bulk service ratio */
+#define OHCI_CTRL_PLE (1 << 2) /* periodic list enable */
+#define OHCI_CTRL_IE (1 << 3) /* isochronous enable */
+#define OHCI_CTRL_CLE (1 << 4) /* control list enable */
+#define OHCI_CTRL_BLE (1 << 5) /* bulk list enable */
+#define OHCI_CTRL_HCFS (3 << 6) /* host controller functional state */
+#define OHCI_CTRL_IR (1 << 8) /* interrupt routing */
+#define OHCI_CTRL_RWC (1 << 9) /* remote wakeup connected */
+#define OHCI_CTRL_RWE (1 << 10) /* remote wakeup enable */
+
+/* pre-shifted values for HCFS */
+# define OHCI_USB_RESET (0 << 6)
+# define OHCI_USB_RESUME (1 << 6)
+# define OHCI_USB_OPER (2 << 6)
+# define OHCI_USB_SUSPEND (3 << 6)
+
+/*
+ * HcCommandStatus (cmdstatus) register masks
+ */
+#define OHCI_HCR (1 << 0) /* host controller reset */
+#define OHCI_CLF (1 << 1) /* control list filled */
+#define OHCI_BLF (1 << 2) /* bulk list filled */
+#define OHCI_OCR (1 << 3) /* ownership change request */
+#define OHCI_SOC (3 << 16) /* scheduling overrun count */
+
+/*
+ * masks used with interrupt registers:
+ * HcInterruptStatus (intrstatus)
+ * HcInterruptEnable (intrenable)
+ * HcInterruptDisable (intrdisable)
+ */
+#define OHCI_INTR_SO (1 << 0) /* scheduling overrun */
+#define OHCI_INTR_WDH (1 << 1) /* writeback of done_head */
+#define OHCI_INTR_SF (1 << 2) /* start frame */
+#define OHCI_INTR_RD (1 << 3) /* resume detect */
+#define OHCI_INTR_UE (1 << 4) /* unrecoverable error */
+#define OHCI_INTR_FNO (1 << 5) /* frame number overflow */
+#define OHCI_INTR_RHSC (1 << 6) /* root hub status change */
+#define OHCI_INTR_OC (1 << 30) /* ownership change */
+#define OHCI_INTR_MIE (1 << 31) /* master interrupt enable */
+
+
+/* Virtual Root HUB */
+struct virt_root_hub {
+ int devnum; /* Address of Root Hub endpoint */
+ void *dev; /* was urb */
+ void *int_addr;
+ int send;
+ int interval;
+};
+
+/* USB HUB CONSTANTS (not OHCI-specific; see hub.h) */
+
+/* destination of request */
+#define RH_INTERFACE 0x01
+#define RH_ENDPOINT 0x02
+#define RH_OTHER 0x03
+
+#define RH_CLASS 0x20
+#define RH_VENDOR 0x40
+
+/* Requests: bRequest << 8 | bmRequestType */
+#define RH_GET_STATUS 0x0080
+#define RH_CLEAR_FEATURE 0x0100
+#define RH_SET_FEATURE 0x0300
+#define RH_SET_ADDRESS 0x0500
+#define RH_GET_DESCRIPTOR 0x0680
+#define RH_SET_DESCRIPTOR 0x0700
+#define RH_GET_CONFIGURATION 0x0880
+#define RH_SET_CONFIGURATION 0x0900
+#define RH_GET_STATE 0x0280
+#define RH_GET_INTERFACE 0x0A80
+#define RH_SET_INTERFACE 0x0B00
+#define RH_SYNC_FRAME 0x0C80
+/* Our Vendor Specific Request */
+#define RH_SET_EP 0x2000
+
+
+/* Hub port features */
+#define RH_PORT_CONNECTION 0x00
+#define RH_PORT_ENABLE 0x01
+#define RH_PORT_SUSPEND 0x02
+#define RH_PORT_OVER_CURRENT 0x03
+#define RH_PORT_RESET 0x04
+#define RH_PORT_POWER 0x08
+#define RH_PORT_LOW_SPEED 0x09
+
+#define RH_C_PORT_CONNECTION 0x10
+#define RH_C_PORT_ENABLE 0x11
+#define RH_C_PORT_SUSPEND 0x12
+#define RH_C_PORT_OVER_CURRENT 0x13
+#define RH_C_PORT_RESET 0x14
+
+/* Hub features */
+#define RH_C_HUB_LOCAL_POWER 0x00
+#define RH_C_HUB_OVER_CURRENT 0x01
+
+#define RH_DEVICE_REMOTE_WAKEUP 0x00
+#define RH_ENDPOINT_STALL 0x01
+
+#define RH_ACK 0x01
+#define RH_REQ_ERR -1
+#define RH_NACK 0x00
+
+
+/* OHCI ROOT HUB REGISTER MASKS */
+
+/* roothub.portstatus [i] bits */
+#define RH_PS_CCS 0x00000001 /* current connect status */
+#define RH_PS_PES 0x00000002 /* port enable status*/
+#define RH_PS_PSS 0x00000004 /* port suspend status */
+#define RH_PS_POCI 0x00000008 /* port over current indicator */
+#define RH_PS_PRS 0x00000010 /* port reset status */
+#define RH_PS_PPS 0x00000100 /* port power status */
+#define RH_PS_LSDA 0x00000200 /* low speed device attached */
+#define RH_PS_CSC 0x00010000 /* connect status change */
+#define RH_PS_PESC 0x00020000 /* port enable status change */
+#define RH_PS_PSSC 0x00040000 /* port suspend status change */
+#define RH_PS_OCIC 0x00080000 /* over current indicator change */
+#define RH_PS_PRSC 0x00100000 /* port reset status change */
+
+/* roothub.status bits */
+#define RH_HS_LPS 0x00000001 /* local power status */
+#define RH_HS_OCI 0x00000002 /* over current indicator */
+#define RH_HS_DRWE 0x00008000 /* device remote wakeup enable */
+#define RH_HS_LPSC 0x00010000 /* local power status change */
+#define RH_HS_OCIC 0x00020000 /* over current indicator change */
+#define RH_HS_CRWE 0x80000000 /* clear remote wakeup enable */
+
+/* roothub.b masks */
+#define RH_B_DR 0x0000ffff /* device removable flags */
+#define RH_B_PPCM 0xffff0000 /* port power control mask */
+
+/* roothub.a masks */
+#define RH_A_NDP (0xff << 0) /* number of downstream ports */
+#define RH_A_PSM (1 << 8) /* power switching mode */
+#define RH_A_NPS (1 << 9) /* no power switching */
+#define RH_A_DT (1 << 10) /* device type (mbz) */
+#define RH_A_OCPM (1 << 11) /* over current protection mode */
+#define RH_A_NOCP (1 << 12) /* no over current protection */
+#define RH_A_POTPGT (0xff << 24) /* power on to power good time */
+
+/* urb */
+#define N_URB_TD 48
+typedef struct
+{
+ ed_t *ed;
+ __u16 length; /* number of tds associated with this request */
+ __u16 td_cnt; /* number of tds already serviced */
+ int state;
+ unsigned long pipe;
+ int actual_length;
+ td_t *td[N_URB_TD]; /* list pointer to all corresponding TDs associated with this request */
+} urb_priv_t;
+#define URB_DEL 1
+
+/*
+ * This is the full ohci controller description
+ *
+ * Note how the "proper" USB information is just
+ * a subset of what the full implementation needs. (Linus)
+ */
+
+
+typedef struct ohci {
+ struct ohci_hcca *hcca; /* hcca */
+ /*dma_addr_t hcca_dma;*/
+
+ int irq;
+ int disabled; /* e.g. got a UE, we're hung */
+ int sleeping;
+ unsigned long flags; /* for HC bugs */
+
+ struct ohci_regs *regs; /* OHCI controller's memory */
+
+ ed_t *ed_rm_list[2]; /* lists of all endpoints to be removed */
+ ed_t *ed_bulktail; /* last endpoint of bulk list */
+ ed_t *ed_controltail; /* last endpoint of control list */
+ int intrstatus;
+ __u32 hc_control; /* copy of the hc control reg */
+ struct usb_device *dev[32];
+ struct virt_root_hub rh;
+
+ const char *slot_name;
+} ohci_t;
+
+#define NUM_EDS 8 /* num of preallocated endpoint descriptors */
+
+struct ohci_device {
+ ed_t ed[NUM_EDS];
+ int ed_cnt;
+};
+
+/* hcd */
+/* endpoint */
+static int ep_link(ohci_t * ohci, ed_t * ed);
+static int ep_unlink(ohci_t * ohci, ed_t * ed);
+static ed_t * ep_add_ed(struct usb_device * usb_dev, unsigned long pipe);
+
+/*-------------------------------------------------------------------------*/
+
+/* we need more TDs than EDs */
+#define NUM_TD 64
+
+/* +1 so we can align the storage */
+td_t gtd[NUM_TD+1];
+/* pointers to aligned storage */
+td_t *ptd;
+
+/* TDs ... */
+static inline struct td *
+td_alloc (struct usb_device *usb_dev)
+{
+ int i;
+ struct td *td;
+
+ td = NULL;
+ for (i = 0; i < NUM_TD; i++)
+ {
+ if (ptd[i].usb_dev == NULL)
+ {
+ td = &ptd[i];
+ td->usb_dev = usb_dev;
+ break;
+ }
+ }
+
+ return td;
+}
+
+static inline void
+ed_free (struct ed *ed)
+{
+ ed->usb_dev = NULL;
+}
diff --git a/cpu/arm920t/config.mk b/cpu/arm920t/config.mk
new file mode 100755
index 0000000..14e0cd7
--- /dev/null
+++ b/cpu/arm920t/config.mk
@@ -0,0 +1,34 @@
+#
+# (C) Copyright 2002
+# Gary Jennejohn, DENX Software Engineering, <gj@denx.de>
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# Some descriptions of such software. Copyright (c) 2008 WonderMedia Technologies, Inc.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+#
+# WonderMedia Technologies, Inc.
+# 10F, 529, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C.
+#
+
+PLATFORM_RELFLAGS += -fno-strict-aliasing -fno-common -ffixed-r8 \
+ -msoft-float
+
+PLATFORM_CPPFLAGS += -march=armv7-a
+# =========================================================================
+#
+# Supply options according to compiler version
+#
+# =========================================================================
+PLATFORM_CPPFLAGS +=$(call cc-option,-mapcs-32)
+PLATFORM_RELFLAGS +=$(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,))
diff --git a/cpu/arm920t/cpu.c b/cpu/arm920t/cpu.c
new file mode 100755
index 0000000..cbfbb3f
--- /dev/null
+++ b/cpu/arm920t/cpu.c
@@ -0,0 +1,204 @@
+/*++
+Copyright (c) 2010 WonderMedia Technologies, Inc.
+
+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, see http://www.gnu.org/licenses/>.
+
+WonderMedia Technologies, Inc.
+10F, 529, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C.
+--*/
+
+/*
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Marius Groeger <mgroeger@sysgo.de>
+ *
+ * (C) Copyright 2002
+ * Gary Jennejohn, DENX Software Engineering, <gj@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
+ */
+
+#include <common.h>
+#include <command.h>
+#include <arm920t.h>
+
+#ifdef CONFIG_USE_IRQ
+DECLARE_GLOBAL_DATA_PTR;
+#endif
+
+/* read co-processor 15, register #1 (control register) */
+static unsigned long read_p15_c1 (void)
+{
+ unsigned long value;
+
+ __asm__ __volatile__(
+ "mrc p15, 0, %0, c1, c0, 0 @ read control reg\n"
+ : "=r" (value)
+ :
+ : "memory");
+
+#ifdef MMU_DEBUG
+ printf ("p15/c1 is = %08lx\n", value);
+#endif
+ return value;
+}
+
+/* write to co-processor 15, register #1 (control register) */
+static void write_p15_c1 (unsigned long value)
+{
+#ifdef MMU_DEBUG
+ printf ("write %08lx to p15/c1\n", value);
+#endif
+ __asm__ __volatile__(
+ "mcr p15, 0, %0, c1, c0, 0 @ write it back\n"
+ :
+ : "r" (value)
+ : "memory");
+
+ read_p15_c1 ();
+}
+
+static void cp_delay (void)
+{
+ volatile int i;
+
+ /* copro seems to need some delay between reading and writing */
+ for (i = 0; i < 100; i++);
+}
+
+/* See also ARM920T Technical reference Manual */
+#define C1_MMU (1<<0) /* mmu off/on */
+#define C1_ALIGN (1<<1) /* alignment faults off/on */
+#define C1_DC (1<<2) /* dcache off/on */
+
+#define C1_BIG_ENDIAN (1<<7) /* big endian off/on */
+#define C1_SYS_PROT (1<<8) /* system protection */
+#define C1_ROM_PROT (1<<9) /* ROM protection */
+#define C1_IC (1<<12) /* icache off/on */
+#define C1_HIGH_VECTORS (1<<13) /* location of vectors: low/high addresses */
+
+
+int cpu_init (void)
+{
+ /*
+ * setup up stacks if necessary
+ */
+#ifdef CONFIG_USE_IRQ
+ IRQ_STACK_START = _armboot_start - CFG_MALLOC_LEN - CFG_GBL_DATA_SIZE - 4;
+ FIQ_STACK_START = IRQ_STACK_START - CONFIG_STACKSIZE_IRQ;
+#endif
+ return 0;
+}
+
+int cleanup_before_linux (void)
+{
+ /*
+ * this function is called just before we call linux
+ * it prepares the processor for linux
+ *
+ * we turn off caches etc ...
+ */
+
+ unsigned long i;
+
+ disable_interrupts ();
+
+ /* turn off I/D-cache */
+ asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i));
+ i &= ~(C1_DC | C1_IC);
+ asm ("mcr p15, 0, %0, c1, c0, 0": :"r" (i));
+
+ i = 0;
+ asm ("mcr p15, 0, %0, c7, c5, 0": :"r" (i)); /* invalidate icache */
+ asm ("mcr p15, 0, %0, c7, c5, 6": :"r" (i)); /* invalidate BP array */
+ asm ("mcr p15, 0, %0, c7, c10, 4": :"r" (i)); /* DSB */
+ asm ("mcr p15, 0, %0, c7, c5, 4": :"r" (i)); /* ISB */
+
+ return (0);
+}
+
+int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+ disable_interrupts ();
+ reset_cpu (0);
+ /*NOTREACHED*/
+ return (0);
+}
+
+void icache_enable (void)
+{
+ ulong reg;
+
+ reg = read_p15_c1 (); /* get control reg. */
+ cp_delay ();
+ write_p15_c1 (reg | C1_IC);
+}
+
+void icache_disable (void)
+{
+ ulong reg;
+
+ reg = read_p15_c1 ();
+ cp_delay ();
+ write_p15_c1 (reg & ~C1_IC);
+}
+
+int icache_status (void)
+{
+ return (read_p15_c1 () & C1_IC) != 0;
+}
+
+#ifdef USE_920T_MMU
+/* It makes no sense to use the dcache if the MMU is not enabled */
+void dcache_enable (void)
+{
+ ulong reg;
+
+ reg = read_p15_c1 ();
+ cp_delay ();
+ write_p15_c1 (reg | C1_DC);
+}
+
+void dcache_disable (void)
+{
+ ulong reg;
+
+ reg = read_p15_c1 ();
+ cp_delay ();
+ reg &= ~C1_DC;
+ write_p15_c1 (reg);
+}
+
+int dcache_status (void)
+{
+ return (read_p15_c1 () & C1_DC) != 0;
+}
+#endif
diff --git a/cpu/arm920t/imx/Makefile b/cpu/arm920t/imx/Makefile
new file mode 100755
index 0000000..8865f82
--- /dev/null
+++ b/cpu/arm920t/imx/Makefile
@@ -0,0 +1,42 @@
+#
+# (C) Copyright 2000, 2001, 2002
+# 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$(SOC).a
+
+OBJS = generic.o interrupts.o serial.o speed.o
+
+all: .depend $(LIB)
+
+$(LIB): $(OBJS)
+ $(AR) crv $@ $(OBJS)
+
+#########################################################################
+
+.depend: Makefile $(OBJS:.o=.c)
+ $(CC) -M $(CFLAGS) $(OBJS:.o=.c) > $@
+
+sinclude .depend
+
+#########################################################################
diff --git a/cpu/arm920t/imx/generic.c b/cpu/arm920t/imx/generic.c
new file mode 100755
index 0000000..aa7c8c1
--- /dev/null
+++ b/cpu/arm920t/imx/generic.c
@@ -0,0 +1,90 @@
+/*
+ * arch/arm/mach-imx/generic.c
+ *
+ * author: Sascha Hauer
+ * Created: april 20th, 2004
+ * Copyright: Synertronixx GmbH
+ *
+ * Common code for i.MX machines
+ *
+ * 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_IMX
+
+#include <asm/arch/imx-regs.h>
+
+void imx_gpio_mode(int gpio_mode)
+{
+ unsigned int pin = gpio_mode & GPIO_PIN_MASK;
+ unsigned int port = (gpio_mode & GPIO_PORT_MASK) >> 5;
+ unsigned int ocr = (gpio_mode & GPIO_OCR_MASK) >> 10;
+ unsigned int tmp;
+
+ /* Pullup enable */
+ if(gpio_mode & GPIO_PUEN)
+ PUEN(port) |= (1<<pin);
+ else
+ PUEN(port) &= ~(1<<pin);
+
+ /* Data direction */
+ if(gpio_mode & GPIO_OUT)
+ DDIR(port) |= 1<<pin;
+ else
+ DDIR(port) &= ~(1<<pin);
+
+ /* Primary / alternate function */
+ if(gpio_mode & GPIO_AF)
+ GPR(port) |= (1<<pin);
+ else
+ GPR(port) &= ~(1<<pin);
+
+ /* use as gpio? */
+ if( ocr == 3 )
+ GIUS(port) |= (1<<pin);
+ else
+ GIUS(port) &= ~(1<<pin);
+
+ /* Output / input configuration */
+ /* FIXME: I'm not very sure about OCR and ICONF, someone
+ * should have a look over it
+ */
+ if(pin<16) {
+ tmp = OCR1(port);
+ tmp &= ~( 3<<(pin*2));
+ tmp |= (ocr << (pin*2));
+ OCR1(port) = tmp;
+
+ if( gpio_mode & GPIO_AOUT )
+ ICONFA1(port) &= ~( 3<<(pin*2));
+ if( gpio_mode & GPIO_BOUT )
+ ICONFB1(port) &= ~( 3<<(pin*2));
+ } else {
+ tmp = OCR2(port);
+ tmp &= ~( 3<<((pin-16)*2));
+ tmp |= (ocr << ((pin-16)*2));
+ OCR2(port) = tmp;
+
+ if( gpio_mode & GPIO_AOUT )
+ ICONFA2(port) &= ~( 3<<((pin-16)*2));
+ if( gpio_mode & GPIO_BOUT )
+ ICONFB2(port) &= ~( 3<<((pin-16)*2));
+ }
+}
+
+#endif /* CONFIG_IMX */
diff --git a/cpu/arm920t/imx/interrupts.c b/cpu/arm920t/imx/interrupts.c
new file mode 100755
index 0000000..03ce06d
--- /dev/null
+++ b/cpu/arm920t/imx/interrupts.c
@@ -0,0 +1,139 @@
+/*
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Marius Groeger <mgroeger@sysgo.de>
+ *
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Alex Zuepke <azu@sysgo.de>
+ *
+ * (C) Copyright 2002
+ * Gary Jennejohn, DENX Software Engineering, <gj@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>
+#if defined (CONFIG_IMX)
+
+#include <arm920t.h>
+#include <asm/arch/imx-regs.h>
+
+int interrupt_init (void)
+{
+ int i;
+ /* setup GP Timer 1 */
+ TCTL1 = TCTL_SWR;
+ for ( i=0; i<100; i++) TCTL1 = 0; /* We have no udelay by now */
+ TPRER1 = get_PERCLK1() / 1000000; /* 1 MHz */
+ TCTL1 |= TCTL_FRR | (1<<1); /* Freerun Mode, PERCLK1 input */
+
+ reset_timer_masked();
+
+ return (0);
+}
+
+/*
+ * timer without interrupts
+ */
+
+void reset_timer (void)
+{
+ reset_timer_masked ();
+}
+
+ulong get_timer (ulong base)
+{
+ return get_timer_masked ();
+}
+
+void set_timer (ulong t)
+{
+ /* nop */
+}
+
+void reset_timer_masked (void)
+{
+ TCTL1 &= ~TCTL_TEN;
+ TCTL1 |= TCTL_TEN; /* Enable timer */
+}
+
+ulong get_timer_masked (void)
+{
+ return TCN1;
+}
+
+void udelay_masked (unsigned long usec)
+{
+ ulong endtime = get_timer_masked() + usec;
+ signed long diff;
+
+ do {
+ ulong now = get_timer_masked ();
+ diff = endtime - now;
+ } while (diff >= 0);
+}
+
+void udelay (unsigned long usec)
+{
+ udelay_masked(usec);
+}
+
+/*
+ * This function is derived from PowerPC code (read timebase as long long).
+ * On ARM it just returns the timer value.
+ */
+unsigned long long get_ticks(void)
+{
+ return get_timer(0);
+}
+
+/*
+ * This function is derived from PowerPC code (timebase clock frequency).
+ * On ARM it returns the number of timer ticks per second.
+ */
+ulong get_tbclk (void)
+{
+ ulong tbclk;
+
+ tbclk = CFG_HZ;
+
+ return tbclk;
+}
+
+/*
+ * Reset the cpu by setting up the watchdog timer and let him time out
+ */
+void reset_cpu (ulong ignored)
+{
+ /* Disable watchdog and set Time-Out field to 0 */
+ WCR = 0x00000000;
+
+ /* Write Service Sequence */
+ WSR = 0x00005555;
+ WSR = 0x0000AAAA;
+
+ /* Enable watchdog */
+ WCR = 0x00000001;
+
+ while (1);
+ /*NOTREACHED*/
+}
+
+#endif /* defined (CONFIG_IMX) */
diff --git a/cpu/arm920t/imx/serial.c b/cpu/arm920t/imx/serial.c
new file mode 100755
index 0000000..9dbaa56
--- /dev/null
+++ b/cpu/arm920t/imx/serial.c
@@ -0,0 +1,201 @@
+/*
+ * (c) 2004 Sascha Hauer <sascha@saschahauer.de>
+ *
+ * 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>
+#if defined (CONFIG_IMX)
+
+#include <asm/arch/imx-regs.h>
+
+#ifndef CONFIG_IMX_SERIAL_NONE
+
+#if defined CONFIG_IMX_SERIAL1
+#define UART_BASE IMX_UART1_BASE
+#elif defined CONFIG_IMX_SERIAL2
+#define UART_BASE IMX_UART2_BASE
+#else
+#error "define CONFIG_IMX_SERIAL1, CONFIG_IMX_SERIAL2 or CONFIG_IMX_SERIAL_NONE"
+#endif
+
+struct imx_serial {
+ volatile uint32_t urxd[16];
+ volatile uint32_t utxd[16];
+ volatile uint32_t ucr1;
+ volatile uint32_t ucr2;
+ volatile uint32_t ucr3;
+ volatile uint32_t ucr4;
+ volatile uint32_t ufcr;
+ volatile uint32_t usr1;
+ volatile uint32_t usr2;
+ volatile uint32_t uesc;
+ volatile uint32_t utim;
+ volatile uint32_t ubir;
+ volatile uint32_t ubmr;
+ volatile uint32_t ubrc;
+ volatile uint32_t bipr[4];
+ volatile uint32_t bmpr[4];
+ volatile uint32_t uts;
+};
+
+void serial_setbrg (void)
+{
+ serial_init();
+}
+
+extern void imx_gpio_mode(int gpio_mode);
+
+/*
+ * Initialise the serial port with the given baudrate. The settings
+ * are always 8 data bits, no parity, 1 stop bit, no start bits.
+ *
+ */
+int serial_init (void)
+{
+ volatile struct imx_serial* base = (struct imx_serial *)UART_BASE;
+#ifdef CONFIG_IMX_SERIAL1
+ imx_gpio_mode(PC11_PF_UART1_TXD);
+ imx_gpio_mode(PC12_PF_UART1_RXD);
+#else
+ imx_gpio_mode(PB30_PF_UART2_TXD);
+ imx_gpio_mode(PB31_PF_UART2_RXD);
+#endif
+
+ /* Disable UART */
+ base->ucr1 &= ~UCR1_UARTEN;
+
+ /* Set to default POR state */
+
+ base->ucr1 = 0x00000004;
+ base->ucr2 = 0x00000000;
+ base->ucr3 = 0x00000000;
+ base->ucr4 = 0x00008040;
+ base->uesc = 0x0000002B;
+ base->utim = 0x00000000;
+ base->ubir = 0x00000000;
+ base->ubmr = 0x00000000;
+ base->uts = 0x00000000;
+ /* Set clocks */
+ base->ucr4 |= UCR4_REF16;
+
+ /* Configure FIFOs */
+ base->ufcr = 0xa81;
+
+ /* Set the numerator value minus one of the BRM ratio */
+ base->ubir = (CONFIG_BAUDRATE / 100) - 1;
+
+ /* Set the denominator value minus one of the BRM ratio */
+ base->ubmr = 10000 - 1;
+
+ /* Set to 8N1 */
+ base->ucr2 &= ~UCR2_PREN;
+ base->ucr2 |= UCR2_WS;
+ base->ucr2 &= ~UCR2_STPB;
+
+ /* Ignore RTS */
+ base->ucr2 |= UCR2_IRTS;
+
+ /* Enable UART */
+ base->ucr1 |= UCR1_UARTEN | UCR1_UARTCLKEN;
+
+ /* Enable FIFOs */
+ base->ucr2 |= UCR2_SRST | UCR2_RXEN | UCR2_TXEN;
+
+ /* Clear status flags */
+ base->usr2 |= USR2_ADET |
+ USR2_DTRF |
+ USR2_IDLE |
+ USR2_IRINT |
+ USR2_WAKE |
+ USR2_RTSF |
+ USR2_BRCD |
+ USR2_ORE |
+ USR2_RDR;
+
+ /* Clear status flags */
+ base->usr1 |= USR1_PARITYERR |
+ USR1_RTSD |
+ USR1_ESCF |
+ USR1_FRAMERR |
+ USR1_AIRINT |
+ USR1_AWAKE;
+ return (0);
+}
+
+/*
+ * Read a single byte from the serial port. Returns 1 on success, 0
+ * otherwise. When the function is successful, the character read is
+ * written into its argument c.
+ */
+int serial_getc (void)
+{
+ volatile struct imx_serial* base = (struct imx_serial *)UART_BASE;
+ unsigned char ch;
+
+ while(base->uts & UTS_RXEMPTY);
+
+ ch = (char)base->urxd[0];
+
+ return ch;
+}
+
+#ifdef CONFIG_HWFLOW
+static int hwflow = 0; /* turned off by default */
+int hwflow_onoff(int on)
+{
+}
+#endif
+
+/*
+ * Output a single byte to the serial port.
+ */
+void serial_putc (const char c)
+{
+ volatile struct imx_serial* base = (struct imx_serial *)UART_BASE;
+
+ /* Wait for Tx FIFO not full */
+ while (base->uts & UTS_TXFULL);
+
+ base->utxd[0] = c;
+
+ /* If \n, also do \r */
+ if (c == '\n')
+ serial_putc ('\r');
+}
+
+/*
+ * Test whether a character is in the RX buffer
+ */
+int serial_tstc (void)
+{
+ volatile struct imx_serial* base = (struct imx_serial *)UART_BASE;
+
+ /* If receive fifo is empty, return false */
+ if (base->uts & UTS_RXEMPTY)
+ return 0;
+ return 1;
+}
+
+void
+serial_puts (const char *s)
+{
+ while (*s) {
+ serial_putc (*s++);
+ }
+}
+#endif /* CONFIG_IMX_SERIAL_NONE */
+#endif /* defined CONFIG_IMX */
diff --git a/cpu/arm920t/imx/speed.c b/cpu/arm920t/imx/speed.c
new file mode 100755
index 0000000..1e29698
--- /dev/null
+++ b/cpu/arm920t/imx/speed.c
@@ -0,0 +1,102 @@
+/*
+ *
+ * (c) 2004 Sascha Hauer <sascha@saschahauer.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>
+#if defined (CONFIG_IMX)
+
+#include <asm/arch/imx-regs.h>
+
+/* ------------------------------------------------------------------------- */
+/* NOTE: This describes the proper use of this file.
+ *
+ * CONFIG_SYS_CLK_FREQ should be defined as the input frequency of the PLL.
+ * SH FIXME: 16780000 in our case
+ * get_FCLK(), get_HCLK(), get_PCLK() and get_UCLK() return the clock of
+ * the specified bus in HZ.
+ */
+/* ------------------------------------------------------------------------- */
+
+ulong get_systemPLLCLK(void)
+{
+ /* FIXME: We assume System_SEL = 0 here */
+ u32 spctl0 = SPCTL0;
+ u32 mfi = (spctl0 >> 10) & 0xf;
+ u32 mfn = spctl0 & 0x3f;
+ u32 mfd = (spctl0 >> 16) & 0x3f;
+ u32 pd = (spctl0 >> 26) & 0xf;
+
+ mfi = mfi<=5 ? 5 : mfi;
+
+ return (2*(CONFIG_SYSPLL_CLK_FREQ>>10)*( (mfi<<10) + (mfn<<10)/(mfd+1)))/(pd+1);
+}
+
+ulong get_mcuPLLCLK(void)
+{
+ /* FIXME: We assume System_SEL = 0 here */
+ u32 mpctl0 = MPCTL0;
+ u32 mfi = (mpctl0 >> 10) & 0xf;
+ u32 mfn = mpctl0 & 0x3f;
+ u32 mfd = (mpctl0 >> 16) & 0x3f;
+ u32 pd = (mpctl0 >> 26) & 0xf;
+
+ mfi = mfi<=5 ? 5 : mfi;
+
+ return (2*(CONFIG_SYS_CLK_FREQ>>10)*( (mfi<<10) + (mfn<<10)/(mfd+1)))/(pd+1);
+}
+
+ulong get_FCLK(void)
+{
+ return (( CSCR>>15)&1) ? get_mcuPLLCLK()>>1 : get_mcuPLLCLK();
+}
+
+/* return HCLK frequency */
+ulong get_HCLK(void)
+{
+ u32 bclkdiv = (( CSCR >> 10 ) & 0xf) + 1;
+ printf("bclkdiv: %d\n", bclkdiv);
+ return get_systemPLLCLK() / bclkdiv;
+}
+
+/* return BCLK frequency */
+ulong get_BCLK(void)
+{
+ return get_HCLK();
+}
+
+ulong get_PERCLK1(void)
+{
+ return get_systemPLLCLK() / (((PCDR) & 0xf)+1);
+}
+
+ulong get_PERCLK2(void)
+{
+ return get_systemPLLCLK() / (((PCDR>>4) & 0xf)+1);
+}
+
+ulong get_PERCLK3(void)
+{
+ return get_systemPLLCLK() / (((PCDR>>16) & 0x7f)+1);
+}
+
+#endif /* defined (CONFIG_IMX) */
diff --git a/cpu/arm920t/interrupts.c b/cpu/arm920t/interrupts.c
new file mode 100755
index 0000000..a43a3ed
--- /dev/null
+++ b/cpu/arm920t/interrupts.c
@@ -0,0 +1,174 @@
+/*
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Marius Groeger <mgroeger@sysgo.de>
+ *
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Alex Zuepke <azu@sysgo.de>
+ *
+ * (C) Copyright 2002
+ * Gary Jennejohn, DENX Software Engineering, <gj@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 <arm920t.h>
+#include <asm/proc-armv/ptrace.h>
+
+#ifdef CONFIG_USE_IRQ
+/* enable IRQ interrupts */
+void enable_interrupts (void)
+{
+ unsigned long temp;
+ __asm__ __volatile__("mrs %0, cpsr\n"
+ "bic %0, %0, #0x80\n"
+ "msr cpsr_c, %0"
+ : "=r" (temp)
+ :
+ : "memory");
+}
+
+
+/*
+ * disable IRQ/FIQ interrupts
+ * returns true if interrupts had been enabled before we disabled them
+ */
+int disable_interrupts (void)
+{
+ unsigned long old,temp;
+ __asm__ __volatile__("mrs %0, cpsr\n"
+ "orr %1, %0, #0xc0\n"
+ "msr cpsr_c, %1"
+ : "=r" (old), "=r" (temp)
+ :
+ : "memory");
+ return (old & 0x80) == 0;
+}
+#else
+void enable_interrupts (void)
+{
+ return;
+}
+int disable_interrupts (void)
+{
+ return 0;
+}
+#endif
+
+
+void bad_mode (void)
+{
+ panic ("Resetting CPU ...\n");
+ reset_cpu (0);
+}
+
+void show_regs (struct pt_regs *regs)
+{
+ unsigned long flags;
+ const char *processor_modes[] = {
+ "USER_26", "FIQ_26", "IRQ_26", "SVC_26",
+ "UK4_26", "UK5_26", "UK6_26", "UK7_26",
+ "UK8_26", "UK9_26", "UK10_26", "UK11_26",
+ "UK12_26", "UK13_26", "UK14_26", "UK15_26",
+ "USER_32", "FIQ_32", "IRQ_32", "SVC_32",
+ "UK4_32", "UK5_32", "UK6_32", "ABT_32",
+ "UK8_32", "UK9_32", "UK10_32", "UND_32",
+ "UK12_32", "UK13_32", "UK14_32", "SYS_32",
+ };
+
+ flags = condition_codes (regs);
+
+ printf ("pc : [<%08lx>] lr : [<%08lx>]\n"
+ "sp : %08lx ip : %08lx fp : %08lx\n",
+ instruction_pointer (regs),
+ regs->ARM_lr, regs->ARM_sp, regs->ARM_ip, regs->ARM_fp);
+ printf ("r10: %08lx r9 : %08lx r8 : %08lx\n",
+ regs->ARM_r10, regs->ARM_r9, regs->ARM_r8);
+ printf ("r7 : %08lx r6 : %08lx r5 : %08lx r4 : %08lx\n",
+ regs->ARM_r7, regs->ARM_r6, regs->ARM_r5, regs->ARM_r4);
+ printf ("r3 : %08lx r2 : %08lx r1 : %08lx r0 : %08lx\n",
+ regs->ARM_r3, regs->ARM_r2, regs->ARM_r1, regs->ARM_r0);
+ printf ("Flags: %c%c%c%c",
+ flags & CC_N_BIT ? 'N' : 'n',
+ flags & CC_Z_BIT ? 'Z' : 'z',
+ flags & CC_C_BIT ? 'C' : 'c', flags & CC_V_BIT ? 'V' : 'v');
+ printf (" IRQs %s FIQs %s Mode %s%s\n",
+ interrupts_enabled (regs) ? "on" : "off",
+ fast_interrupts_enabled (regs) ? "on" : "off",
+ processor_modes[processor_mode (regs)],
+ thumb_mode (regs) ? " (T)" : "");
+}
+
+void do_undefined_instruction (struct pt_regs *pt_regs)
+{
+ printf ("undefined instruction\n");
+ show_regs (pt_regs);
+ bad_mode ();
+}
+
+void do_software_interrupt (struct pt_regs *pt_regs)
+{
+ printf ("software interrupt\n");
+ show_regs (pt_regs);
+ bad_mode ();
+}
+
+void do_prefetch_abort (struct pt_regs *pt_regs)
+{
+ printf ("prefetch abort\n");
+ show_regs (pt_regs);
+ bad_mode ();
+}
+
+void do_data_abort (struct pt_regs *pt_regs)
+{
+ printf ("data abort\n");
+ show_regs (pt_regs);
+ bad_mode ();
+}
+
+void do_not_used (struct pt_regs *pt_regs)
+{
+ printf ("not used\n");
+ show_regs (pt_regs);
+ bad_mode ();
+}
+
+void do_fiq (struct pt_regs *pt_regs)
+{
+ printf ("fast interrupt request\n");
+ show_regs (pt_regs);
+ bad_mode ();
+}
+
+void do_irq (struct pt_regs *pt_regs)
+{
+#if defined (CONFIG_USE_IRQ) && defined (CONFIG_ARCH_INTEGRATOR)
+ /* ASSUMED to be a timer interrupt */
+ /* Just clear it - count handled in */
+ /* integratorap.c */
+ *(volatile ulong *)(CFG_TIMERBASE + 0x0C) = 0;
+#else
+ printf ("interrupt request\n");
+ show_regs (pt_regs);
+ bad_mode ();
+#endif
+}
diff --git a/cpu/arm920t/ks8695/Makefile b/cpu/arm920t/ks8695/Makefile
new file mode 100755
index 0000000..ac49060
--- /dev/null
+++ b/cpu/arm920t/ks8695/Makefile
@@ -0,0 +1,43 @@
+#
+# (C) Copyright 2000-2005
+# 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$(SOC).a
+
+OBJS = interrupts.o serial.o
+SOBJS = lowlevel_init.o
+
+all: .depend $(LIB)
+
+$(LIB): $(OBJS) $(SOBJS)
+ $(AR) crv $@ $(OBJS) $(SOBJS)
+
+#########################################################################
+
+.depend: Makefile $(SOBJS:.o=.S) $(OBJS:.o=.c)
+ $(CC) -M $(CFLAGS) $(SOBJS:.o=.S) $(OBJS:.o=.c) > $@
+
+sinclude .depend
+
+#########################################################################
diff --git a/cpu/arm920t/ks8695/interrupts.c b/cpu/arm920t/ks8695/interrupts.c
new file mode 100755
index 0000000..883d689
--- /dev/null
+++ b/cpu/arm920t/ks8695/interrupts.c
@@ -0,0 +1,112 @@
+/*
+ * (C) Copyright 2004-2005, Greg Ungerer <greg.ungerer@opengear.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 <asm/arch/platform.h>
+
+/*
+ * Handy KS8695 register access functions.
+ */
+#define ks8695_read(a) *((volatile ulong *) (KS8695_IO_BASE + (a)))
+#define ks8695_write(a,v) *((volatile ulong *) (KS8695_IO_BASE + (a))) = (v)
+
+int timer_inited;
+ulong timer_ticks;
+
+int interrupt_init (void)
+{
+ /* nothing happens here - we don't setup any IRQs */
+ return (0);
+}
+
+/*
+ * Initial timer set constants. Nothing complicated, just set for a 1ms
+ * tick.
+ */
+#define TIMER_INTERVAL (TICKS_PER_uSEC * mSEC_1)
+#define TIMER_COUNT (TIMER_INTERVAL / 2)
+#define TIMER_PULSE TIMER_COUNT
+
+void reset_timer_masked(void)
+{
+ /* Set the hadware timer for 1ms */
+ ks8695_write(KS8695_TIMER1, TIMER_COUNT);
+ ks8695_write(KS8695_TIMER1_PCOUNT, TIMER_PULSE);
+ ks8695_write(KS8695_TIMER_CTRL, 0x2);
+ timer_ticks = 0;
+ timer_inited++;
+}
+
+void reset_timer(void)
+{
+ reset_timer_masked();
+}
+
+ulong get_timer_masked(void)
+{
+ /* Check for timer wrap */
+ if (ks8695_read(KS8695_INT_STATUS) & KS8695_INTMASK_TIMERINT1) {
+ /* Clear interrupt condition */
+ ks8695_write(KS8695_INT_STATUS, KS8695_INTMASK_TIMERINT1);
+ timer_ticks++;
+ }
+ return timer_ticks;
+}
+
+ulong get_timer(ulong base)
+{
+ return (get_timer_masked() - base);
+}
+
+void set_timer(ulong t)
+{
+ timer_ticks = t;
+}
+
+void udelay(ulong usec)
+{
+ ulong start = get_timer_masked();
+ ulong end;
+
+ if (!timer_inited)
+ reset_timer();
+
+ /* Only 1ms resolution :-( */
+ end = usec / 1000;
+ while (get_timer(start) < end)
+ ;
+}
+
+void reset_cpu (ulong ignored)
+{
+ ulong tc;
+
+ /* Set timer0 to watchdog, and let it timeout */
+ tc = ks8695_read(KS8695_TIMER_CTRL) & 0x2;
+ ks8695_write(KS8695_TIMER_CTRL, tc);
+ ks8695_write(KS8695_TIMER0, ((10 << 8) | 0xff));
+ ks8695_write(KS8695_TIMER_CTRL, (tc | 0x1));
+
+ /* Should only wait here till watchdog resets */
+ for (;;)
+ ;
+}
diff --git a/cpu/arm920t/ks8695/lowlevel_init.S b/cpu/arm920t/ks8695/lowlevel_init.S
new file mode 100755
index 0000000..e9f1227
--- /dev/null
+++ b/cpu/arm920t/ks8695/lowlevel_init.S
@@ -0,0 +1,205 @@
+/*
+ * lowlevel_init.S - basic hardware initialization for the KS8695 CPU
+ *
+ * Copyright (c) 2004-2005, Greg Ungerer <greg.ungerer@opengear.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 <config.h>
+#include <version.h>
+#include <asm/arch/platform.h>
+
+#ifndef CONFIG_SKIP_LOWLEVEL_INIT
+
+/*
+ *************************************************************************
+ *
+ * Handy dandy macros
+ *
+ *************************************************************************
+ */
+
+/* Delay a bit */
+.macro DELAY_FOR cycles, reg0
+ ldr \reg0, =\cycles
+ subs \reg0, \reg0, #1
+ subne pc, pc, #0xc
+.endm
+
+/*
+ *************************************************************************
+ *
+ * Some local storage.
+ *
+ *************************************************************************
+ */
+
+/* Should we boot with an interactive console or not */
+.globl serial_console
+
+/*
+ *************************************************************************
+ *
+ * Raw hardware initialization code. The important thing is to get
+ * SDRAM setup and running. We do some other basic things here too,
+ * like getting the PLL set for high speed, and init the LEDs.
+ *
+ *************************************************************************
+ */
+
+.globl lowlevel_init
+lowlevel_init:
+
+#if DEBUG
+ /*
+ * enable UART for early debug trace
+ */
+ ldr r1, =(KS8695_IO_BASE+KS8695_UART_DIVISOR)
+ mov r2, #0xd9
+ str r2, [r1] /* 115200 baud */
+ ldr r1, =(KS8695_IO_BASE+KS8695_UART_LINE_CTRL)
+ mov r2, #0x03
+ str r2, [r1] /* 8 data bits, no parity, 1 stop */
+ ldr r1, =(KS8695_IO_BASE+KS8695_UART_TX_HOLDING)
+ mov r2, #0x41
+ str r2, [r1] /* write 'A' */
+#endif
+#if DEBUG
+ ldr r1, =(KS8695_IO_BASE+KS8695_UART_TX_HOLDING)
+ mov r2, #0x42
+ str r2, [r1]
+#endif
+
+ /*
+ * remap the memory and flash regions. we want to end up with
+ * ram from address 0, and flash at 32MB.
+ */
+ ldr r1, =(KS8695_IO_BASE+KS8695_MEM_CTRL0)
+ ldr r2, =0xbfc00040
+ str r2, [r1] /* large flash map */
+ ldr pc, =(highflash+0x02000000-0x00f00000) /* jump to high flash address */
+highflash:
+ ldr r2, =0x8fe00040
+ str r2, [r1] /* remap flash range */
+
+ /*
+ * remap the second select region to the 4MB immediately after
+ * the first region. This way if you have a larger flash (say 8Mb)
+ * then you can have it all mapped nicely. Has no effect if you
+ * only have a 4Mb or smaller flash.
+ */
+ ldr r1, =(KS8695_IO_BASE+KS8695_MEM_CTRL1)
+ ldr r2, =0x9fe40040
+ str r2, [r1] /* remap flash2 region, contiguous */
+ ldr r1, =(KS8695_IO_BASE+KS8695_MEM_GENERAL)
+ ldr r2, =0x30000005
+ str r2, [r1] /* enable both flash selects */
+
+#ifdef CONFIG_CM41xx
+ /*
+ * map the second flash chip, using the external IO lines.
+ */
+ ldr r1, =(KS8695_IO_BASE+KS8695_IO_CTRL0)
+ ldr r2, =0xafe80b6d
+ str r2, [r1] /* remap io0 region, contiguous */
+ ldr r1, =(KS8695_IO_BASE+KS8695_IO_CTRL1)
+ ldr r2, =0xbfec0b6d
+ str r2, [r1] /* remap io1 region, contiguous */
+ ldr r1, =(KS8695_IO_BASE+KS8695_MEM_GENERAL)
+ ldr r2, =0x30050005
+ str r2, [r1] /* enable second flash */
+#endif
+
+ /*
+ * before relocating, we have to setup RAM timing
+ */
+ ldr r1, =(KS8695_IO_BASE+KS8695_SDRAM_CTRL0)
+#if (PHYS_SDRAM_1_SIZE == 0x02000000)
+ ldr r2, =0x7fc0000e /* 32MB */
+#else
+ ldr r2, =0x3fc0000e /* 16MB */
+#endif
+ str r2, [r1] /* configure sdram bank0 setup */
+ ldr r1, =(KS8695_IO_BASE+KS8695_SDRAM_CTRL1)
+ mov r2, #0
+ str r2, [r1] /* configure sdram bank1 setup */
+
+ ldr r1, =(KS8695_IO_BASE+KS8695_SDRAM_GENERAL)
+ ldr r2, =0x0000000a
+ str r2, [r1] /* set RAS/CAS timing */
+
+ ldr r1, =(KS8695_IO_BASE+KS8695_SDRAM_BUFFER)
+ ldr r2, =0x00030000
+ str r2, [r1] /* send NOP command */
+ DELAY_FOR 0x100, r0
+ ldr r2, =0x00010000
+ str r2, [r1] /* send PRECHARGE-ALL */
+ DELAY_FOR 0x100, r0
+
+ ldr r1, =(KS8695_IO_BASE+KS8695_SDRAM_REFRESH)
+ ldr r2, =0x00000020
+ str r2, [r1] /* set for fast refresh */
+ DELAY_FOR 0x100, r0
+ ldr r2, =0x00000190
+ str r2, [r1] /* set normal refresh timing */
+
+ ldr r1, =(KS8695_IO_BASE+KS8695_SDRAM_BUFFER)
+ ldr r2, =0x00020033
+ str r2, [r1] /* send mode command */
+ DELAY_FOR 0x100, r0
+ ldr r2, =0x01f00000
+ str r2, [r1] /* enable sdram fifos */
+
+ /*
+ * set pll to top speed
+ */
+ ldr r1, =(KS8695_IO_BASE+KS8695_SYSTEN_BUS_CLOCK)
+ mov r2, #0
+ str r2, [r1] /* set pll clock to 166MHz */
+
+ ldr r1, =(KS8695_IO_BASE+KS8695_SWITCH_CTRL0)
+ ldr r2, [r1] /* Get switch ctrl0 register */
+ and r2, r2, #0x0fc00000 /* Mask out LED control bits */
+ orr r2, r2, #0x01800000 /* Set Link/activity/speed actions */
+ str r2, [r1]
+
+#ifdef CONFIG_CM4008
+ ldr r1, =(KS8695_IO_BASE+KS8695_GPIO_MODE)
+ ldr r2, =0x0000fe30
+ str r2, [r1] /* enable LED's as outputs */
+ ldr r1, =(KS8695_IO_BASE+KS8695_GPIO_DATA)
+ ldr r2, =0x0000fe20
+ str r2, [r1] /* turn on power LED */
+#endif
+#if defined(CONFIG_CM4008) || defined(CONFIG_CM41xx)
+ ldr r2, [r1] /* get current GPIO input data */
+ tst r2, #0x8 /* check if "erase" depressed */
+ beq nobutton
+ mov r2, #0 /* be quiet on boot, no console */
+ ldr r1, =serial_console
+ str r2, [r1]
+nobutton:
+#endif
+
+ add lr, lr, #0x02000000 /* flash is now mapped high */
+ add ip, ip, #0x02000000 /* this is a hack */
+ mov pc, lr /* all done, return */
+
+#endif /* CONFIG_SKIP_LOWLEVEL_INIT */
diff --git a/cpu/arm920t/ks8695/serial.c b/cpu/arm920t/ks8695/serial.c
new file mode 100755
index 0000000..0dd91e7
--- /dev/null
+++ b/cpu/arm920t/ks8695/serial.c
@@ -0,0 +1,116 @@
+/*
+ * serial.c -- KS8695 serial driver
+ *
+ * (C) Copyright 2004, Greg Ungerer <greg.ungerer@opengear.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <asm/arch/platform.h>
+
+#ifndef CONFIG_SERIAL1
+#error "Bad: you didn't configure serial ..."
+#endif
+
+/*
+ * Define the UART hardware register access structure.
+ */
+struct ks8695uart {
+ unsigned int RX; /* 0x00 - Receive data (r) */
+ unsigned int TX; /* 0x04 - Transmit data (w) */
+ unsigned int FCR; /* 0x08 - Fifo Control (r/w) */
+ unsigned int LCR; /* 0x0c - Line Control (r/w) */
+ unsigned int MCR; /* 0x10 - Modem Control (r/w) */
+ unsigned int LSR; /* 0x14 - Line Status (r/w) */
+ unsigned int MSR; /* 0x18 - Modem Status (r/w) */
+ unsigned int BD; /* 0x1c - Baud Rate (r/w) */
+ unsigned int SR; /* 0x20 - Status (r/w) */
+};
+
+#define KS8695_UART_ADDR ((void *) (KS8695_IO_BASE + KS8695_UART_RX_BUFFER))
+#define KS8695_UART_CLK 25000000
+
+
+/*
+ * Under some circumstances we want to be "quiet" and not issue any
+ * serial output - though we want u-boot to otherwise work and behave
+ * the same. By default be noisy.
+ */
+int serial_console = 1;
+
+
+void serial_setbrg(void)
+{
+ DECLARE_GLOBAL_DATA_PTR;
+ volatile struct ks8695uart *uartp = KS8695_UART_ADDR;
+
+ /* Set to global baud rate and 8 data bits, no parity, 1 stop bit*/
+ uartp->BD = KS8695_UART_CLK / gd->baudrate;
+ uartp->LCR = KS8695_UART_LINEC_WLEN8;
+}
+
+int serial_init(void)
+{
+ serial_console = 1;
+ serial_setbrg();
+ return 0;
+}
+
+void serial_raw_putc(const char c)
+{
+ volatile struct ks8695uart *uartp = KS8695_UART_ADDR;
+ int i;
+
+ for (i = 0; (i < 0x100000); i++) {
+ if (uartp->LSR & KS8695_UART_LINES_TXFE)
+ break;
+ }
+
+ uartp->TX = c;
+}
+
+void serial_putc(const char c)
+{
+ if (serial_console) {
+ serial_raw_putc(c);
+ if (c == '\n')
+ serial_raw_putc('\r');
+ }
+}
+
+int serial_tstc(void)
+{
+ volatile struct ks8695uart *uartp = KS8695_UART_ADDR;
+ if (serial_console)
+ return ((uartp->LSR & KS8695_UART_LINES_RXFE) ? 1 : 0);
+ return 0;
+}
+
+void serial_puts(const char *s)
+{
+ char c;
+ while ((c = *s++) != 0)
+ serial_putc(c);
+}
+
+int serial_getc(void)
+{
+ volatile struct ks8695uart *uartp = KS8695_UART_ADDR;
+
+ while ((uartp->LSR & KS8695_UART_LINES_RXFE) == 0)
+ ;
+ return (uartp->RX);
+}
diff --git a/cpu/arm920t/s3c24x0/Makefile b/cpu/arm920t/s3c24x0/Makefile
new file mode 100755
index 0000000..af9e4ef
--- /dev/null
+++ b/cpu/arm920t/s3c24x0/Makefile
@@ -0,0 +1,43 @@
+#
+# (C) Copyright 2000, 2001, 2002
+# 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$(SOC).a
+
+OBJS = i2c.o interrupts.o serial.o speed.o \
+ usb_ohci.o
+
+all: .depend $(LIB)
+
+$(LIB): $(OBJS)
+ $(AR) crv $@ $(OBJS)
+
+#########################################################################
+
+.depend: Makefile $(OBJS:.o=.c)
+ $(CC) -M $(CFLAGS) $(OBJS:.o=.c) > $@
+
+sinclude .depend
+
+#########################################################################
diff --git a/cpu/arm920t/s3c24x0/i2c.c b/cpu/arm920t/s3c24x0/i2c.c
new file mode 100755
index 0000000..ef56cd1
--- /dev/null
+++ b/cpu/arm920t/s3c24x0/i2c.c
@@ -0,0 +1,447 @@
+/*
+ * (C) Copyright 2002
+ * David Mueller, ELSOFT AG, d.mueller@elsoft.ch
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/* This code should work for both the S3C2400 and the S3C2410
+ * as they seem to have the same I2C controller inside.
+ * The different address mapping is handled by the s3c24xx.h files below.
+ */
+
+#include <common.h>
+
+#ifdef CONFIG_DRIVER_S3C24X0_I2C
+
+#if defined(CONFIG_S3C2400)
+#include <s3c2400.h>
+#elif defined(CONFIG_S3C2410)
+#include <s3c2410.h>
+#endif
+#include <i2c.h>
+
+#ifdef CONFIG_HARD_I2C
+
+#define I2C_WRITE 0
+#define I2C_READ 1
+
+#define I2C_OK 0
+#define I2C_NOK 1
+#define I2C_NACK 2
+#define I2C_NOK_LA 3 /* Lost arbitration */
+#define I2C_NOK_TOUT 4 /* time out */
+
+#define I2CSTAT_BSY 0x20 /* Busy bit */
+#define I2CSTAT_NACK 0x01 /* Nack bit */
+#define I2CCON_IRPND 0x10 /* Interrupt pending bit */
+#define I2C_MODE_MT 0xC0 /* Master Transmit Mode */
+#define I2C_MODE_MR 0x80 /* Master Receive Mode */
+#define I2C_START_STOP 0x20 /* START / STOP */
+#define I2C_TXRX_ENA 0x10 /* I2C Tx/Rx enable */
+
+#define I2C_TIMEOUT 1 /* 1 second */
+
+
+static int GetI2CSDA(void)
+{
+ S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
+
+#ifdef CONFIG_S3C2410
+ return (gpio->GPEDAT & 0x8000) >> 15;
+#endif
+#ifdef CONFIG_S3C2400
+ return (gpio->PGDAT & 0x0020) >> 5;
+#endif
+}
+
+#if 0
+static void SetI2CSDA(int x)
+{
+ rGPEDAT = (rGPEDAT & ~0x8000) | (x&1) << 15;
+}
+#endif
+
+static void SetI2CSCL(int x)
+{
+ S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
+
+#ifdef CONFIG_S3C2410
+ gpio->GPEDAT = (gpio->GPEDAT & ~0x4000) | (x&1) << 14;
+#endif
+#ifdef CONFIG_S3C2400
+ gpio->PGDAT = (gpio->PGDAT & ~0x0040) | (x&1) << 6;
+#endif
+}
+
+
+static int WaitForXfer (void)
+{
+ S3C24X0_I2C *const i2c = S3C24X0_GetBase_I2C ();
+ int i, status;
+
+ i = I2C_TIMEOUT * 10000;
+ status = i2c->IICCON;
+ while ((i > 0) && !(status & I2CCON_IRPND)) {
+ udelay (100);
+ status = i2c->IICCON;
+ i--;
+ }
+
+ return (status & I2CCON_IRPND) ? I2C_OK : I2C_NOK_TOUT;
+}
+
+static int IsACK (void)
+{
+ S3C24X0_I2C *const i2c = S3C24X0_GetBase_I2C ();
+
+ return (!(i2c->IICSTAT & I2CSTAT_NACK));
+}
+
+static void ReadWriteByte (void)
+{
+ S3C24X0_I2C *const i2c = S3C24X0_GetBase_I2C ();
+
+ i2c->IICCON &= ~I2CCON_IRPND;
+}
+
+void i2c_init (int speed, int slaveadd)
+{
+ S3C24X0_I2C *const i2c = S3C24X0_GetBase_I2C ();
+ S3C24X0_GPIO *const gpio = S3C24X0_GetBase_GPIO ();
+ ulong freq, pres = 16, div;
+ int i, status;
+
+ /* wait for some time to give previous transfer a chance to finish */
+
+ i = I2C_TIMEOUT * 1000;
+ status = i2c->IICSTAT;
+ while ((i > 0) && (status & I2CSTAT_BSY)) {
+ udelay (1000);
+ status = i2c->IICSTAT;
+ i--;
+ }
+
+ if ((status & I2CSTAT_BSY) || GetI2CSDA () == 0) {
+#ifdef CONFIG_S3C2410
+ ulong old_gpecon = gpio->GPECON;
+#endif
+#ifdef CONFIG_S3C2400
+ ulong old_gpecon = gpio->PGCON;
+#endif
+ /* bus still busy probably by (most) previously interrupted transfer */
+
+#ifdef CONFIG_S3C2410
+ /* set I2CSDA and I2CSCL (GPE15, GPE14) to GPIO */
+ gpio->GPECON = (gpio->GPECON & ~0xF0000000) | 0x10000000;
+#endif
+#ifdef CONFIG_S3C2400
+ /* set I2CSDA and I2CSCL (PG5, PG6) to GPIO */
+ gpio->PGCON = (gpio->PGCON & ~0x00003c00) | 0x00000c00;
+#endif
+
+ /* toggle I2CSCL until bus idle */
+ SetI2CSCL (0);
+ udelay (1000);
+ i = 10;
+ while ((i > 0) && (GetI2CSDA () != 1)) {
+ SetI2CSCL (1);
+ udelay (1000);
+ SetI2CSCL (0);
+ udelay (1000);
+ i--;
+ }
+ SetI2CSCL (1);
+ udelay (1000);
+
+ /* restore pin functions */
+#ifdef CONFIG_S3C2410
+ gpio->GPECON = old_gpecon;
+#endif
+#ifdef CONFIG_S3C2400
+ gpio->PGCON = old_gpecon;
+#endif
+ }
+
+ /* calculate prescaler and divisor values */
+ freq = get_PCLK ();
+ if ((freq / pres / (16 + 1)) > speed)
+ /* set prescaler to 512 */
+ pres = 512;
+
+ div = 0;
+ while ((freq / pres / (div + 1)) > speed)
+ div++;
+
+ /* set prescaler, divisor according to freq, also set
+ * ACKGEN, IRQ */
+ i2c->IICCON = (div & 0x0F) | 0xA0 | ((pres == 512) ? 0x40 : 0);
+
+ /* init to SLAVE REVEIVE and set slaveaddr */
+ i2c->IICSTAT = 0;
+ i2c->IICADD = slaveadd;
+ /* program Master Transmit (and implicit STOP) */
+ i2c->IICSTAT = I2C_MODE_MT | I2C_TXRX_ENA;
+
+}
+
+/*
+ * cmd_type is 0 for write, 1 for read.
+ *
+ * addr_len can take any value from 0-255, it is only limited
+ * by the char, we could make it larger if needed. If it is
+ * 0 we skip the address write cycle.
+ */
+static
+int i2c_transfer (unsigned char cmd_type,
+ unsigned char chip,
+ unsigned char addr[],
+ unsigned char addr_len,
+ unsigned char data[], unsigned short data_len)
+{
+ S3C24X0_I2C *const i2c = S3C24X0_GetBase_I2C ();
+ int i, status, result;
+
+ if (data == 0 || data_len == 0) {
+ /*Don't support data transfer of no length or to address 0 */
+ printf ("i2c_transfer: bad call\n");
+ return I2C_NOK;
+ }
+
+ /* Check I2C bus idle */
+ i = I2C_TIMEOUT * 1000;
+ status = i2c->IICSTAT;
+ while ((i > 0) && (status & I2CSTAT_BSY)) {
+ udelay (1000);
+ status = i2c->IICSTAT;
+ i--;
+ }
+
+ if (status & I2CSTAT_BSY)
+ return I2C_NOK_TOUT;
+
+ i2c->IICCON |= 0x80;
+ result = I2C_OK;
+
+ switch (cmd_type) {
+ case I2C_WRITE:
+ if (addr && addr_len) {
+ i2c->IICDS = chip;
+ /* send START */
+ i2c->IICSTAT = I2C_MODE_MT | I2C_TXRX_ENA | I2C_START_STOP;
+ i = 0;
+ while ((i < addr_len) && (result == I2C_OK)) {
+ result = WaitForXfer ();
+ i2c->IICDS = addr[i];
+ ReadWriteByte ();
+ i++;
+ }
+ i = 0;
+ while ((i < data_len) && (result == I2C_OK)) {
+ result = WaitForXfer ();
+ i2c->IICDS = data[i];
+ ReadWriteByte ();
+ i++;
+ }
+ } else {
+ i2c->IICDS = chip;
+ /* send START */
+ i2c->IICSTAT = I2C_MODE_MT | I2C_TXRX_ENA | I2C_START_STOP;
+ i = 0;
+ while ((i < data_len) && (result = I2C_OK)) {
+ result = WaitForXfer ();
+ i2c->IICDS = data[i];
+ ReadWriteByte ();
+ i++;
+ }
+ }
+
+ if (result == I2C_OK)
+ result = WaitForXfer ();
+
+ /* send STOP */
+ i2c->IICSTAT = I2C_MODE_MR | I2C_TXRX_ENA;
+ ReadWriteByte ();
+ break;
+
+ case I2C_READ:
+ if (addr && addr_len) {
+ i2c->IICSTAT = I2C_MODE_MT | I2C_TXRX_ENA;
+ i2c->IICDS = chip;
+ /* send START */
+ i2c->IICSTAT |= I2C_START_STOP;
+ result = WaitForXfer ();
+ if (IsACK ()) {
+ i = 0;
+ while ((i < addr_len) && (result == I2C_OK)) {
+ i2c->IICDS = addr[i];
+ ReadWriteByte ();
+ result = WaitForXfer ();
+ i++;
+ }
+
+ i2c->IICDS = chip;
+ /* resend START */
+ i2c->IICSTAT = I2C_MODE_MR | I2C_TXRX_ENA |
+ I2C_START_STOP;
+ ReadWriteByte ();
+ result = WaitForXfer ();
+ i = 0;
+ while ((i < data_len) && (result == I2C_OK)) {
+ /* disable ACK for final READ */
+ if (i == data_len - 1)
+ i2c->IICCON &= ~0x80;
+ ReadWriteByte ();
+ result = WaitForXfer ();
+ data[i] = i2c->IICDS;
+ i++;
+ }
+ } else {
+ result = I2C_NACK;
+ }
+
+ } else {
+ i2c->IICSTAT = I2C_MODE_MR | I2C_TXRX_ENA;
+ i2c->IICDS = chip;
+ /* send START */
+ i2c->IICSTAT |= I2C_START_STOP;
+ result = WaitForXfer ();
+
+ if (IsACK ()) {
+ i = 0;
+ while ((i < data_len) && (result == I2C_OK)) {
+ /* disable ACK for final READ */
+ if (i == data_len - 1)
+ i2c->IICCON &= ~0x80;
+ ReadWriteByte ();
+ result = WaitForXfer ();
+ data[i] = i2c->IICDS;
+ i++;
+ }
+ } else {
+ result = I2C_NACK;
+ }
+ }
+
+ /* send STOP */
+ i2c->IICSTAT = I2C_MODE_MR | I2C_TXRX_ENA;
+ ReadWriteByte ();
+ break;
+
+ default:
+ printf ("i2c_transfer: bad call\n");
+ result = I2C_NOK;
+ break;
+ }
+
+ return (result);
+}
+
+int i2c_probe (uchar chip)
+{
+ uchar buf[1];
+
+ buf[0] = 0;
+
+ /*
+ * What is needed is to send the chip address and verify that the
+ * address was <ACK>ed (i.e. there was a chip at that address which
+ * drove the data line low).
+ */
+ return (i2c_transfer (I2C_READ, chip << 1, 0, 0, buf, 1) != I2C_OK);
+}
+
+int i2c_read (uchar chip, uint addr, int alen, uchar * buffer, int len)
+{
+ uchar xaddr[4];
+ int ret;
+
+ if (alen > 4) {
+ printf ("I2C read: addr len %d not supported\n", alen);
+ return 1;
+ }
+
+ if (alen > 0) {
+ xaddr[0] = (addr >> 24) & 0xFF;
+ xaddr[1] = (addr >> 16) & 0xFF;
+ xaddr[2] = (addr >> 8) & 0xFF;
+ xaddr[3] = addr & 0xFF;
+ }
+
+#ifdef CFG_I2C_EEPROM_ADDR_OVERFLOW
+ /*
+ * EEPROM chips that implement "address overflow" are ones
+ * like Catalyst 24WC04/08/16 which has 9/10/11 bits of
+ * address and the extra bits end up in the "chip address"
+ * bit slots. This makes a 24WC08 (1Kbyte) chip look like
+ * four 256 byte chips.
+ *
+ * Note that we consider the length of the address field to
+ * still be one byte because the extra address bits are
+ * hidden in the chip address.
+ */
+ if (alen > 0)
+ chip |= ((addr >> (alen * 8)) & CFG_I2C_EEPROM_ADDR_OVERFLOW);
+#endif
+ if ((ret =
+ i2c_transfer (I2C_READ, chip << 1, &xaddr[4 - alen], alen,
+ buffer, len)) != 0) {
+ printf ("I2c read: failed %d\n", ret);
+ return 1;
+ }
+ return 0;
+}
+
+int i2c_write (uchar chip, uint addr, int alen, uchar * buffer, int len)
+{
+ uchar xaddr[4];
+
+ if (alen > 4) {
+ printf ("I2C write: addr len %d not supported\n", alen);
+ return 1;
+ }
+
+ if (alen > 0) {
+ xaddr[0] = (addr >> 24) & 0xFF;
+ xaddr[1] = (addr >> 16) & 0xFF;
+ xaddr[2] = (addr >> 8) & 0xFF;
+ xaddr[3] = addr & 0xFF;
+ }
+#ifdef CFG_I2C_EEPROM_ADDR_OVERFLOW
+ /*
+ * EEPROM chips that implement "address overflow" are ones
+ * like Catalyst 24WC04/08/16 which has 9/10/11 bits of
+ * address and the extra bits end up in the "chip address"
+ * bit slots. This makes a 24WC08 (1Kbyte) chip look like
+ * four 256 byte chips.
+ *
+ * Note that we consider the length of the address field to
+ * still be one byte because the extra address bits are
+ * hidden in the chip address.
+ */
+ if (alen > 0)
+ chip |= ((addr >> (alen * 8)) & CFG_I2C_EEPROM_ADDR_OVERFLOW);
+#endif
+ return (i2c_transfer
+ (I2C_WRITE, chip << 1, &xaddr[4 - alen], alen, buffer,
+ len) != 0);
+}
+#endif /* CONFIG_HARD_I2C */
+
+#endif /* CONFIG_DRIVER_S3C24X0_I2C */
diff --git a/cpu/arm920t/s3c24x0/interrupts.c b/cpu/arm920t/s3c24x0/interrupts.c
new file mode 100755
index 0000000..3ec9b54
--- /dev/null
+++ b/cpu/arm920t/s3c24x0/interrupts.c
@@ -0,0 +1,217 @@
+/*
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Marius Groeger <mgroeger@sysgo.de>
+ *
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Alex Zuepke <azu@sysgo.de>
+ *
+ * (C) Copyright 2002
+ * Gary Jennejohn, DENX Software Engineering, <gj@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>
+#if defined(CONFIG_S3C2400) || defined (CONFIG_S3C2410) || defined (CONFIG_TRAB)
+
+#include <arm920t.h>
+#if defined(CONFIG_S3C2400)
+#include <s3c2400.h>
+#elif defined(CONFIG_S3C2410)
+#include <s3c2410.h>
+#endif
+
+int timer_load_val = 0;
+
+/* macro to read the 16 bit timer */
+static inline ulong READ_TIMER(void)
+{
+ S3C24X0_TIMERS * const timers = S3C24X0_GetBase_TIMERS();
+
+ return (timers->TCNTO4 & 0xffff);
+}
+
+static ulong timestamp;
+static ulong lastdec;
+
+int interrupt_init (void)
+{
+ S3C24X0_TIMERS * const timers = S3C24X0_GetBase_TIMERS();
+
+ /* use PWM Timer 4 because it has no output */
+ /* prescaler for Timer 4 is 16 */
+ timers->TCFG0 = 0x0f00;
+ if (timer_load_val == 0)
+ {
+ /*
+ * for 10 ms clock period @ PCLK with 4 bit divider = 1/2
+ * (default) and prescaler = 16. Should be 10390
+ * @33.25MHz and 15625 @ 50 MHz
+ */
+ timer_load_val = get_PCLK()/(2 * 16 * 100);
+ }
+ /* load value for 10 ms timeout */
+ lastdec = timers->TCNTB4 = timer_load_val;
+ /* auto load, manual update of Timer 4 */
+ timers->TCON = (timers->TCON & ~0x0700000) | 0x600000;
+ /* auto load, start Timer 4 */
+ timers->TCON = (timers->TCON & ~0x0700000) | 0x500000;
+ timestamp = 0;
+
+ return (0);
+}
+
+/*
+ * timer without interrupts
+ */
+
+void reset_timer (void)
+{
+ reset_timer_masked ();
+}
+
+ulong get_timer (ulong base)
+{
+ return get_timer_masked () - base;
+}
+
+void set_timer (ulong t)
+{
+ timestamp = t;
+}
+
+void udelay (unsigned long usec)
+{
+ ulong tmo;
+ ulong start = get_timer(0);
+
+ tmo = usec / 1000;
+ tmo *= (timer_load_val * 100);
+ tmo /= 1000;
+
+ while ((ulong)(get_timer_masked () - start) < tmo)
+ /*NOP*/;
+}
+
+void reset_timer_masked (void)
+{
+ /* reset time */
+ lastdec = READ_TIMER();
+ timestamp = 0;
+}
+
+ulong get_timer_masked (void)
+{
+ ulong now = READ_TIMER();
+
+ if (lastdec >= now) {
+ /* normal mode */
+ timestamp += lastdec - now;
+ } else {
+ /* we have an overflow ... */
+ timestamp += lastdec + timer_load_val - now;
+ }
+ lastdec = now;
+
+ return timestamp;
+}
+
+void udelay_masked (unsigned long usec)
+{
+ ulong tmo;
+ ulong endtime;
+ signed long diff;
+
+ if (usec >= 1000) {
+ tmo = usec / 1000;
+ tmo *= (timer_load_val * 100);
+ tmo /= 1000;
+ } else {
+ tmo = usec * (timer_load_val * 100);
+ tmo /= (1000*1000);
+ }
+
+ endtime = get_timer_masked () + tmo;
+
+ do {
+ ulong now = get_timer_masked ();
+ diff = endtime - now;
+ } while (diff >= 0);
+}
+
+/*
+ * This function is derived from PowerPC code (read timebase as long long).
+ * On ARM it just returns the timer value.
+ */
+unsigned long long get_ticks(void)
+{
+ return get_timer(0);
+}
+
+/*
+ * This function is derived from PowerPC code (timebase clock frequency).
+ * On ARM it returns the number of timer ticks per second.
+ */
+ulong get_tbclk (void)
+{
+ ulong tbclk;
+
+#if defined(CONFIG_SMDK2400) || defined(CONFIG_TRAB)
+ tbclk = timer_load_val * 100;
+#elif defined(CONFIG_SMDK2410) || defined(CONFIG_VCMA9)
+ tbclk = CFG_HZ;
+#else
+# error "tbclk not configured"
+#endif
+
+ return tbclk;
+}
+
+/*
+ * reset the cpu by setting up the watchdog timer and let him time out
+ */
+void reset_cpu (ulong ignored)
+{
+ volatile S3C24X0_WATCHDOG * watchdog;
+
+#ifdef CONFIG_TRAB
+ extern void disable_vfd (void);
+
+ disable_vfd();
+#endif
+
+ watchdog = S3C24X0_GetBase_WATCHDOG();
+
+ /* Disable watchdog */
+ watchdog->WTCON = 0x0000;
+
+ /* Initialize watchdog timer count register */
+ watchdog->WTCNT = 0x0001;
+
+ /* Enable watchdog timer; assert reset at timer timeout */
+ watchdog->WTCON = 0x0021;
+
+ while(1); /* loop forever and wait for reset to happen */
+
+ /*NOTREACHED*/
+}
+
+#endif /* defined(CONFIG_S3C2400) || defined (CONFIG_S3C2410) || defined (CONFIG_TRAB) */
diff --git a/cpu/arm920t/s3c24x0/serial.c b/cpu/arm920t/s3c24x0/serial.c
new file mode 100755
index 0000000..8327443
--- /dev/null
+++ b/cpu/arm920t/s3c24x0/serial.c
@@ -0,0 +1,182 @@
+/*
+ * (C) Copyright 2002
+ * Gary Jennejohn, DENX Software Engineering, <gj@denx.de>
+ *
+ * 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>
+#if defined(CONFIG_S3C2400) || defined (CONFIG_S3C2410) || defined (CONFIG_TRAB)
+
+#if defined(CONFIG_S3C2400) || defined(CONFIG_TRAB)
+#include <s3c2400.h>
+#elif defined(CONFIG_S3C2410)
+#include <s3c2410.h>
+#endif
+
+#ifdef CONFIG_SERIAL1
+#define UART_NR S3C24X0_UART0
+
+#elif defined(CONFIG_SERIAL2)
+# if defined(CONFIG_TRAB)
+# error "TRAB supports only CONFIG_SERIAL1"
+# endif
+#define UART_NR S3C24X0_UART1
+
+#elif defined(CONFIG_SERIAL3)
+# if defined(CONFIG_TRAB)
+# #error "TRAB supports only CONFIG_SERIAL1"
+# endif
+#define UART_NR S3C24X0_UART2
+
+#else
+#error "Bad: you didn't configure serial ..."
+#endif
+
+void serial_setbrg (void)
+{
+ DECLARE_GLOBAL_DATA_PTR;
+ S3C24X0_UART * const uart = S3C24X0_GetBase_UART(UART_NR);
+ int i;
+ unsigned int reg = 0;
+
+ /* value is calculated so : (int)(PCLK/16./baudrate) -1 */
+ reg = get_PCLK() / (16 * gd->baudrate) - 1;
+
+ /* FIFO enable, Tx/Rx FIFO clear */
+ uart->UFCON = 0x07;
+ uart->UMCON = 0x0;
+ /* Normal,No parity,1 stop,8 bit */
+ uart->ULCON = 0x3;
+ /*
+ * tx=level,rx=edge,disable timeout int.,enable rx error int.,
+ * normal,interrupt or polling
+ */
+ uart->UCON = 0x245;
+ uart->UBRDIV = reg;
+
+#ifdef CONFIG_HWFLOW
+ uart->UMCON = 0x1; /* RTS up */
+#endif
+ for (i = 0; i < 100; i++);
+}
+
+/*
+ * Initialise the serial port with the given baudrate. The settings
+ * are always 8 data bits, no parity, 1 stop bit, no start bits.
+ *
+ */
+int serial_init (void)
+{
+ serial_setbrg ();
+
+ return (0);
+}
+
+/*
+ * Read a single byte from the serial port. Returns 1 on success, 0
+ * otherwise. When the function is succesfull, the character read is
+ * written into its argument c.
+ */
+int serial_getc (void)
+{
+ S3C24X0_UART * const uart = S3C24X0_GetBase_UART(UART_NR);
+
+ /* wait for character to arrive */
+ while (!(uart->UTRSTAT & 0x1));
+
+ return uart->URXH & 0xff;
+}
+
+#ifdef CONFIG_HWFLOW
+static int hwflow = 0; /* turned off by default */
+int hwflow_onoff(int on)
+{
+ switch(on) {
+ case 0:
+ default:
+ break; /* return current */
+ case 1:
+ hwflow = 1; /* turn on */
+ break;
+ case -1:
+ hwflow = 0; /* turn off */
+ break;
+ }
+ return hwflow;
+}
+#endif
+
+#ifdef CONFIG_MODEM_SUPPORT
+static int be_quiet = 0;
+void disable_putc(void)
+{
+ be_quiet = 1;
+}
+
+void enable_putc(void)
+{
+ be_quiet = 0;
+}
+#endif
+
+
+/*
+ * Output a single byte to the serial port.
+ */
+void serial_putc (const char c)
+{
+ S3C24X0_UART * const uart = S3C24X0_GetBase_UART(UART_NR);
+#ifdef CONFIG_MODEM_SUPPORT
+ if (be_quiet)
+ return;
+#endif
+
+ /* wait for room in the tx FIFO */
+ while (!(uart->UTRSTAT & 0x2));
+
+#ifdef CONFIG_HWFLOW
+ /* Wait for CTS up */
+ while(hwflow && !(uart->UMSTAT & 0x1))
+ ;
+#endif
+
+ uart->UTXH = c;
+
+ /* If \n, also do \r */
+ if (c == '\n')
+ serial_putc ('\r');
+}
+
+/*
+ * Test whether a character is in the RX buffer
+ */
+int serial_tstc (void)
+{
+ S3C24X0_UART * const uart = S3C24X0_GetBase_UART(UART_NR);
+
+ return uart->UTRSTAT & 0x1;
+}
+
+void
+serial_puts (const char *s)
+{
+ while (*s) {
+ serial_putc (*s++);
+ }
+}
+
+#endif /* defined(CONFIG_S3C2400) || defined (CONFIG_S3C2410) || defined (CONFIG_TRAB) */
diff --git a/cpu/arm920t/s3c24x0/speed.c b/cpu/arm920t/s3c24x0/speed.c
new file mode 100755
index 0000000..e0dca62
--- /dev/null
+++ b/cpu/arm920t/s3c24x0/speed.c
@@ -0,0 +1,101 @@
+/*
+ * (C) Copyright 2001-2004
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * (C) Copyright 2002
+ * David Mueller, ELSOFT AG, d.mueller@elsoft.ch
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/* This code should work for both the S3C2400 and the S3C2410
+ * as they seem to have the same PLL and clock machinery inside.
+ * The different address mapping is handled by the s3c24xx.h files below.
+ */
+
+#include <common.h>
+#if defined(CONFIG_S3C2400) || defined (CONFIG_S3C2410) || defined (CONFIG_TRAB)
+
+#if defined(CONFIG_S3C2400)
+#include <s3c2400.h>
+#elif defined(CONFIG_S3C2410)
+#include <s3c2410.h>
+#endif
+
+#define MPLL 0
+#define UPLL 1
+
+/* ------------------------------------------------------------------------- */
+/* NOTE: This describes the proper use of this file.
+ *
+ * CONFIG_SYS_CLK_FREQ should be defined as the input frequency of the PLL.
+ *
+ * get_FCLK(), get_HCLK(), get_PCLK() and get_UCLK() return the clock of
+ * the specified bus in HZ.
+ */
+/* ------------------------------------------------------------------------- */
+
+static ulong get_PLLCLK(int pllreg)
+{
+ S3C24X0_CLOCK_POWER * const clk_power = S3C24X0_GetBase_CLOCK_POWER();
+ ulong r, m, p, s;
+
+ if (pllreg == MPLL)
+ r = clk_power->MPLLCON;
+ else if (pllreg == UPLL)
+ r = clk_power->UPLLCON;
+ else
+ hang();
+
+ m = ((r & 0xFF000) >> 12) + 8;
+ p = ((r & 0x003F0) >> 4) + 2;
+ s = r & 0x3;
+
+ return((CONFIG_SYS_CLK_FREQ * m) / (p << s));
+}
+
+/* return FCLK frequency */
+ulong get_FCLK(void)
+{
+ return(get_PLLCLK(MPLL));
+}
+
+/* return HCLK frequency */
+ulong get_HCLK(void)
+{
+ S3C24X0_CLOCK_POWER * const clk_power = S3C24X0_GetBase_CLOCK_POWER();
+
+ return((clk_power->CLKDIVN & 0x2) ? get_FCLK()/2 : get_FCLK());
+}
+
+/* return PCLK frequency */
+ulong get_PCLK(void)
+{
+ S3C24X0_CLOCK_POWER * const clk_power = S3C24X0_GetBase_CLOCK_POWER();
+
+ return((clk_power->CLKDIVN & 0x1) ? get_HCLK()/2 : get_HCLK());
+}
+
+/* return UCLK frequency */
+ulong get_UCLK(void)
+{
+ return(get_PLLCLK(UPLL));
+}
+
+#endif /* defined(CONFIG_S3C2400) || defined (CONFIG_S3C2410) || defined (CONFIG_TRAB) */
diff --git a/cpu/arm920t/s3c24x0/usb_ohci.c b/cpu/arm920t/s3c24x0/usb_ohci.c
new file mode 100755
index 0000000..b4cc744
--- /dev/null
+++ b/cpu/arm920t/s3c24x0/usb_ohci.c
@@ -0,0 +1,1688 @@
+/*
+ * URB OHCI HCD (Host Controller Driver) for USB on the S3C2400.
+ *
+ * (C) Copyright 2003
+ * Gary Jennejohn, DENX Software Engineering <gj@denx.de>
+ *
+ * Note: Much of this code has been derived from Linux 2.4
+ * (C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at>
+ * (C) Copyright 2000-2002 David Brownell
+ *
+ * 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
+ *
+ */
+/*
+ * IMPORTANT NOTES
+ * 1 - you MUST define LITTLEENDIAN in the configuration file for the
+ * board or this driver will NOT work!
+ * 2 - this driver is intended for use with USB Mass Storage Devices
+ * (BBB) ONLY. There is NO support for Interrupt or Isochronous pipes!
+ */
+
+#include <common.h>
+/* #include <pci.h> no PCI on the S3C24X0 */
+
+#ifdef CONFIG_USB_OHCI
+
+#if defined(CONFIG_S3C2400)
+#include <s3c2400.h>
+#elif defined(CONFIG_S3C2410)
+#include <s3c2410.h>
+#endif
+
+#include <malloc.h>
+#include <usb.h>
+#include "usb_ohci.h"
+
+#define OHCI_USE_NPS /* force NoPowerSwitching mode */
+#undef OHCI_VERBOSE_DEBUG /* not always helpful */
+
+
+/* For initializing controller (mask in an HCFS mode too) */
+#define OHCI_CONTROL_INIT \
+ (OHCI_CTRL_CBSR & 0x3) | OHCI_CTRL_IE | OHCI_CTRL_PLE
+
+#define readl(a) (*((vu_long *)(a)))
+#define writel(a, b) (*((vu_long *)(b)) = ((vu_long)a))
+
+#define min_t(type,x,y) ({ type __x = (x); type __y = (y); __x < __y ? __x: __y; })
+
+#undef DEBUG
+#ifdef DEBUG
+#define dbg(format, arg...) printf("DEBUG: " format "\n", ## arg)
+#else
+#define dbg(format, arg...) do {} while(0)
+#endif /* DEBUG */
+#define err(format, arg...) printf("ERROR: " format "\n", ## arg)
+#undef SHOW_INFO
+#ifdef SHOW_INFO
+#define info(format, arg...) printf("INFO: " format "\n", ## arg)
+#else
+#define info(format, arg...) do {} while(0)
+#endif
+
+#define m16_swap(x) swap_16(x)
+#define m32_swap(x) swap_32(x)
+
+/* global ohci_t */
+static ohci_t gohci;
+/* this must be aligned to a 256 byte boundary */
+struct ohci_hcca ghcca[1];
+/* a pointer to the aligned storage */
+struct ohci_hcca *phcca;
+/* this allocates EDs for all possible endpoints */
+struct ohci_device ohci_dev;
+/* urb_priv */
+urb_priv_t urb_priv;
+/* RHSC flag */
+int got_rhsc;
+/* device which was disconnected */
+struct usb_device *devgone;
+/* flag guarding URB transation */
+int urb_finished = 0;
+
+/*-------------------------------------------------------------------------*/
+
+/* AMD-756 (D2 rev) reports corrupt register contents in some cases.
+ * The erratum (#4) description is incorrect. AMD's workaround waits
+ * till some bits (mostly reserved) are clear; ok for all revs.
+ */
+#define OHCI_QUIRK_AMD756 0xabcd
+#define read_roothub(hc, register, mask) ({ \
+ u32 temp = readl (&hc->regs->roothub.register); \
+ if (hc->flags & OHCI_QUIRK_AMD756) \
+ while (temp & mask) \
+ temp = readl (&hc->regs->roothub.register); \
+ temp; })
+
+static u32 roothub_a (struct ohci *hc)
+ { return read_roothub (hc, a, 0xfc0fe000); }
+static inline u32 roothub_b (struct ohci *hc)
+ { return readl (&hc->regs->roothub.b); }
+static inline u32 roothub_status (struct ohci *hc)
+ { return readl (&hc->regs->roothub.status); }
+static u32 roothub_portstatus (struct ohci *hc, int i)
+ { return read_roothub (hc, portstatus [i], 0xffe0fce0); }
+
+
+/* forward declaration */
+static int hc_interrupt (void);
+static void
+td_submit_job (struct usb_device * dev, unsigned long pipe, void * buffer,
+ int transfer_len, struct devrequest * setup, urb_priv_t * urb, int interval);
+
+/*-------------------------------------------------------------------------*
+ * URB support functions
+ *-------------------------------------------------------------------------*/
+
+/* free HCD-private data associated with this URB */
+
+static void urb_free_priv (urb_priv_t * urb)
+{
+ int i;
+ int last;
+ struct td * td;
+
+ last = urb->length - 1;
+ if (last >= 0) {
+ for (i = 0; i <= last; i++) {
+ td = urb->td[i];
+ if (td) {
+ td->usb_dev = NULL;
+ urb->td[i] = NULL;
+ }
+ }
+ }
+}
+
+/*-------------------------------------------------------------------------*/
+
+#ifdef DEBUG
+static int sohci_get_current_frame_number (struct usb_device * dev);
+
+/* debug| print the main components of an URB
+ * small: 0) header + data packets 1) just header */
+
+static void pkt_print (struct usb_device * dev, unsigned long pipe, void * buffer,
+ int transfer_len, struct devrequest * setup, char * str, int small)
+{
+ urb_priv_t * purb = &urb_priv;
+
+ dbg("%s URB:[%4x] dev:%2d,ep:%2d-%c,type:%s,len:%d/%d stat:%#lx",
+ str,
+ sohci_get_current_frame_number (dev),
+ usb_pipedevice (pipe),
+ usb_pipeendpoint (pipe),
+ usb_pipeout (pipe)? 'O': 'I',
+ usb_pipetype (pipe) < 2? (usb_pipeint (pipe)? "INTR": "ISOC"):
+ (usb_pipecontrol (pipe)? "CTRL": "BULK"),
+ purb->actual_length,
+ transfer_len, dev->status);
+#ifdef OHCI_VERBOSE_DEBUG
+ if (!small) {
+ int i, len;
+
+ if (usb_pipecontrol (pipe)) {
+ printf (__FILE__ ": cmd(8):");
+ for (i = 0; i < 8 ; i++)
+ printf (" %02x", ((__u8 *) setup) [i]);
+ printf ("\n");
+ }
+ if (transfer_len > 0 && buffer) {
+ printf (__FILE__ ": data(%d/%d):",
+ purb->actual_length,
+ transfer_len);
+ len = usb_pipeout (pipe)?
+ transfer_len: purb->actual_length;
+ for (i = 0; i < 16 && i < len; i++)
+ printf (" %02x", ((__u8 *) buffer) [i]);
+ printf ("%s\n", i < len? "...": "");
+ }
+ }
+#endif
+}
+
+/* just for debugging; prints non-empty branches of the int ed tree inclusive iso eds*/
+void ep_print_int_eds (ohci_t *ohci, char * str) {
+ int i, j;
+ __u32 * ed_p;
+ for (i= 0; i < 32; i++) {
+ j = 5;
+ ed_p = &(ohci->hcca->int_table [i]);
+ if (*ed_p == 0)
+ continue;
+ printf (__FILE__ ": %s branch int %2d(%2x):", str, i, i);
+ while (*ed_p != 0 && j--) {
+ ed_t *ed = (ed_t *)m32_swap(ed_p);
+ printf (" ed: %4x;", ed->hwINFO);
+ ed_p = &ed->hwNextED;
+ }
+ printf ("\n");
+ }
+}
+
+static void ohci_dump_intr_mask (char *label, __u32 mask)
+{
+ dbg ("%s: 0x%08x%s%s%s%s%s%s%s%s%s",
+ label,
+ mask,
+ (mask & OHCI_INTR_MIE) ? " MIE" : "",
+ (mask & OHCI_INTR_OC) ? " OC" : "",
+ (mask & OHCI_INTR_RHSC) ? " RHSC" : "",
+ (mask & OHCI_INTR_FNO) ? " FNO" : "",
+ (mask & OHCI_INTR_UE) ? " UE" : "",
+ (mask & OHCI_INTR_RD) ? " RD" : "",
+ (mask & OHCI_INTR_SF) ? " SF" : "",
+ (mask & OHCI_INTR_WDH) ? " WDH" : "",
+ (mask & OHCI_INTR_SO) ? " SO" : ""
+ );
+}
+
+static void maybe_print_eds (char *label, __u32 value)
+{
+ ed_t *edp = (ed_t *)value;
+
+ if (value) {
+ dbg ("%s %08x", label, value);
+ dbg ("%08x", edp->hwINFO);
+ dbg ("%08x", edp->hwTailP);
+ dbg ("%08x", edp->hwHeadP);
+ dbg ("%08x", edp->hwNextED);
+ }
+}
+
+static char * hcfs2string (int state)
+{
+ switch (state) {
+ case OHCI_USB_RESET: return "reset";
+ case OHCI_USB_RESUME: return "resume";
+ case OHCI_USB_OPER: return "operational";
+ case OHCI_USB_SUSPEND: return "suspend";
+ }
+ return "?";
+}
+
+/* dump control and status registers */
+static void ohci_dump_status (ohci_t *controller)
+{
+ struct ohci_regs *regs = controller->regs;
+ __u32 temp;
+
+ temp = readl (&regs->revision) & 0xff;
+ if (temp != 0x10)
+ dbg ("spec %d.%d", (temp >> 4), (temp & 0x0f));
+
+ temp = readl (&regs->control);
+ dbg ("control: 0x%08x%s%s%s HCFS=%s%s%s%s%s CBSR=%d", temp,
+ (temp & OHCI_CTRL_RWE) ? " RWE" : "",
+ (temp & OHCI_CTRL_RWC) ? " RWC" : "",
+ (temp & OHCI_CTRL_IR) ? " IR" : "",
+ hcfs2string (temp & OHCI_CTRL_HCFS),
+ (temp & OHCI_CTRL_BLE) ? " BLE" : "",
+ (temp & OHCI_CTRL_CLE) ? " CLE" : "",
+ (temp & OHCI_CTRL_IE) ? " IE" : "",
+ (temp & OHCI_CTRL_PLE) ? " PLE" : "",
+ temp & OHCI_CTRL_CBSR
+ );
+
+ temp = readl (&regs->cmdstatus);
+ dbg ("cmdstatus: 0x%08x SOC=%d%s%s%s%s", temp,
+ (temp & OHCI_SOC) >> 16,
+ (temp & OHCI_OCR) ? " OCR" : "",
+ (temp & OHCI_BLF) ? " BLF" : "",
+ (temp & OHCI_CLF) ? " CLF" : "",
+ (temp & OHCI_HCR) ? " HCR" : ""
+ );
+
+ ohci_dump_intr_mask ("intrstatus", readl (&regs->intrstatus));
+ ohci_dump_intr_mask ("intrenable", readl (&regs->intrenable));
+
+ maybe_print_eds ("ed_periodcurrent", readl (&regs->ed_periodcurrent));
+
+ maybe_print_eds ("ed_controlhead", readl (&regs->ed_controlhead));
+ maybe_print_eds ("ed_controlcurrent", readl (&regs->ed_controlcurrent));
+
+ maybe_print_eds ("ed_bulkhead", readl (&regs->ed_bulkhead));
+ maybe_print_eds ("ed_bulkcurrent", readl (&regs->ed_bulkcurrent));
+
+ maybe_print_eds ("donehead", readl (&regs->donehead));
+}
+
+static void ohci_dump_roothub (ohci_t *controller, int verbose)
+{
+ __u32 temp, ndp, i;
+
+ temp = roothub_a (controller);
+ ndp = (temp & RH_A_NDP);
+
+ if (verbose) {
+ dbg ("roothub.a: %08x POTPGT=%d%s%s%s%s%s NDP=%d", temp,
+ ((temp & RH_A_POTPGT) >> 24) & 0xff,
+ (temp & RH_A_NOCP) ? " NOCP" : "",
+ (temp & RH_A_OCPM) ? " OCPM" : "",
+ (temp & RH_A_DT) ? " DT" : "",
+ (temp & RH_A_NPS) ? " NPS" : "",
+ (temp & RH_A_PSM) ? " PSM" : "",
+ ndp
+ );
+ temp = roothub_b (controller);
+ dbg ("roothub.b: %08x PPCM=%04x DR=%04x",
+ temp,
+ (temp & RH_B_PPCM) >> 16,
+ (temp & RH_B_DR)
+ );
+ temp = roothub_status (controller);
+ dbg ("roothub.status: %08x%s%s%s%s%s%s",
+ temp,
+ (temp & RH_HS_CRWE) ? " CRWE" : "",
+ (temp & RH_HS_OCIC) ? " OCIC" : "",
+ (temp & RH_HS_LPSC) ? " LPSC" : "",
+ (temp & RH_HS_DRWE) ? " DRWE" : "",
+ (temp & RH_HS_OCI) ? " OCI" : "",
+ (temp & RH_HS_LPS) ? " LPS" : ""
+ );
+ }
+
+ for (i = 0; i < ndp; i++) {
+ temp = roothub_portstatus (controller, i);
+ dbg ("roothub.portstatus [%d] = 0x%08x%s%s%s%s%s%s%s%s%s%s%s%s",
+ i,
+ temp,
+ (temp & RH_PS_PRSC) ? " PRSC" : "",
+ (temp & RH_PS_OCIC) ? " OCIC" : "",
+ (temp & RH_PS_PSSC) ? " PSSC" : "",
+ (temp & RH_PS_PESC) ? " PESC" : "",
+ (temp & RH_PS_CSC) ? " CSC" : "",
+
+ (temp & RH_PS_LSDA) ? " LSDA" : "",
+ (temp & RH_PS_PPS) ? " PPS" : "",
+ (temp & RH_PS_PRS) ? " PRS" : "",
+ (temp & RH_PS_POCI) ? " POCI" : "",
+ (temp & RH_PS_PSS) ? " PSS" : "",
+
+ (temp & RH_PS_PES) ? " PES" : "",
+ (temp & RH_PS_CCS) ? " CCS" : ""
+ );
+ }
+}
+
+static void ohci_dump (ohci_t *controller, int verbose)
+{
+ dbg ("OHCI controller usb-%s state", controller->slot_name);
+
+ /* dumps some of the state we know about */
+ ohci_dump_status (controller);
+ if (verbose)
+ ep_print_int_eds (controller, "hcca");
+ dbg ("hcca frame #%04x", controller->hcca->frame_no);
+ ohci_dump_roothub (controller, 1);
+}
+
+
+#endif /* DEBUG */
+
+/*-------------------------------------------------------------------------*
+ * Interface functions (URB)
+ *-------------------------------------------------------------------------*/
+
+/* get a transfer request */
+
+int sohci_submit_job(struct usb_device *dev, unsigned long pipe, void *buffer,
+ int transfer_len, struct devrequest *setup, int interval)
+{
+ ohci_t *ohci;
+ ed_t * ed;
+ urb_priv_t *purb_priv;
+ int i, size = 0;
+
+ ohci = &gohci;
+
+ /* when controller's hung, permit only roothub cleanup attempts
+ * such as powering down ports */
+ if (ohci->disabled) {
+ err("sohci_submit_job: EPIPE");
+ return -1;
+ }
+
+ /* if we have an unfinished URB from previous transaction let's
+ * fail and scream as quickly as possible so as not to corrupt
+ * further communication */
+ if (!urb_finished) {
+ err("sohci_submit_job: URB NOT FINISHED");
+ return -1;
+ }
+ /* we're about to begin a new transaction here so mark the URB unfinished */
+ urb_finished = 0;
+
+ /* every endpoint has a ed, locate and fill it */
+ if (!(ed = ep_add_ed (dev, pipe))) {
+ err("sohci_submit_job: ENOMEM");
+ return -1;
+ }
+
+ /* for the private part of the URB we need the number of TDs (size) */
+ switch (usb_pipetype (pipe)) {
+ case PIPE_BULK: /* one TD for every 4096 Byte */
+ size = (transfer_len - 1) / 4096 + 1;
+ break;
+ case PIPE_CONTROL: /* 1 TD for setup, 1 for ACK and 1 for every 4096 B */
+ size = (transfer_len == 0)? 2:
+ (transfer_len - 1) / 4096 + 3;
+ break;
+ }
+
+ if (size >= (N_URB_TD - 1)) {
+ err("need %d TDs, only have %d", size, N_URB_TD);
+ return -1;
+ }
+ purb_priv = &urb_priv;
+ purb_priv->pipe = pipe;
+
+ /* fill the private part of the URB */
+ purb_priv->length = size;
+ purb_priv->ed = ed;
+ purb_priv->actual_length = 0;
+
+ /* allocate the TDs */
+ /* note that td[0] was allocated in ep_add_ed */
+ for (i = 0; i < size; i++) {
+ purb_priv->td[i] = td_alloc (dev);
+ if (!purb_priv->td[i]) {
+ purb_priv->length = i;
+ urb_free_priv (purb_priv);
+ err("sohci_submit_job: ENOMEM");
+ return -1;
+ }
+ }
+
+ if (ed->state == ED_NEW || (ed->state & ED_DEL)) {
+ urb_free_priv (purb_priv);
+ err("sohci_submit_job: EINVAL");
+ return -1;
+ }
+
+ /* link the ed into a chain if is not already */
+ if (ed->state != ED_OPER)
+ ep_link (ohci, ed);
+
+ /* fill the TDs and link it to the ed */
+ td_submit_job(dev, pipe, buffer, transfer_len, setup, purb_priv, interval);
+
+ return 0;
+}
+
+/*-------------------------------------------------------------------------*/
+
+#ifdef DEBUG
+/* tell us the current USB frame number */
+
+static int sohci_get_current_frame_number (struct usb_device *usb_dev)
+{
+ ohci_t *ohci = &gohci;
+
+ return m16_swap (ohci->hcca->frame_no);
+}
+#endif
+
+/*-------------------------------------------------------------------------*
+ * ED handling functions
+ *-------------------------------------------------------------------------*/
+
+/* link an ed into one of the HC chains */
+
+static int ep_link (ohci_t *ohci, ed_t *edi)
+{
+ volatile ed_t *ed = edi;
+
+ ed->state = ED_OPER;
+
+ switch (ed->type) {
+ case PIPE_CONTROL:
+ ed->hwNextED = 0;
+ if (ohci->ed_controltail == NULL) {
+ writel (ed, &ohci->regs->ed_controlhead);
+ } else {
+ ohci->ed_controltail->hwNextED = m32_swap (ed);
+ }
+ ed->ed_prev = ohci->ed_controltail;
+ if (!ohci->ed_controltail && !ohci->ed_rm_list[0] &&
+ !ohci->ed_rm_list[1] && !ohci->sleeping) {
+ ohci->hc_control |= OHCI_CTRL_CLE;
+ writel (ohci->hc_control, &ohci->regs->control);
+ }
+ ohci->ed_controltail = edi;
+ break;
+
+ case PIPE_BULK:
+ ed->hwNextED = 0;
+ if (ohci->ed_bulktail == NULL) {
+ writel (ed, &ohci->regs->ed_bulkhead);
+ } else {
+ ohci->ed_bulktail->hwNextED = m32_swap (ed);
+ }
+ ed->ed_prev = ohci->ed_bulktail;
+ if (!ohci->ed_bulktail && !ohci->ed_rm_list[0] &&
+ !ohci->ed_rm_list[1] && !ohci->sleeping) {
+ ohci->hc_control |= OHCI_CTRL_BLE;
+ writel (ohci->hc_control, &ohci->regs->control);
+ }
+ ohci->ed_bulktail = edi;
+ break;
+ }
+ return 0;
+}
+
+/*-------------------------------------------------------------------------*/
+
+/* unlink an ed from one of the HC chains.
+ * just the link to the ed is unlinked.
+ * the link from the ed still points to another operational ed or 0
+ * so the HC can eventually finish the processing of the unlinked ed */
+
+static int ep_unlink (ohci_t *ohci, ed_t *ed)
+{
+ ed->hwINFO |= m32_swap (OHCI_ED_SKIP);
+
+ switch (ed->type) {
+ case PIPE_CONTROL:
+ if (ed->ed_prev == NULL) {
+ if (!ed->hwNextED) {
+ ohci->hc_control &= ~OHCI_CTRL_CLE;
+ writel (ohci->hc_control, &ohci->regs->control);
+ }
+ writel (m32_swap (*((__u32 *)&ed->hwNextED)), &ohci->regs->ed_controlhead);
+ } else {
+ ed->ed_prev->hwNextED = ed->hwNextED;
+ }
+ if (ohci->ed_controltail == ed) {
+ ohci->ed_controltail = ed->ed_prev;
+ } else {
+ ((ed_t *)m32_swap (*((__u32 *)&ed->hwNextED)))->ed_prev = ed->ed_prev;
+ }
+ break;
+
+ case PIPE_BULK:
+ if (ed->ed_prev == NULL) {
+ if (!ed->hwNextED) {
+ ohci->hc_control &= ~OHCI_CTRL_BLE;
+ writel (ohci->hc_control, &ohci->regs->control);
+ }
+ writel (m32_swap (*((__u32 *)&ed->hwNextED)), &ohci->regs->ed_bulkhead);
+ } else {
+ ed->ed_prev->hwNextED = ed->hwNextED;
+ }
+ if (ohci->ed_bulktail == ed) {
+ ohci->ed_bulktail = ed->ed_prev;
+ } else {
+ ((ed_t *)m32_swap (*((__u32 *)&ed->hwNextED)))->ed_prev = ed->ed_prev;
+ }
+ break;
+ }
+ ed->state = ED_UNLINK;
+ return 0;
+}
+
+
+/*-------------------------------------------------------------------------*/
+
+/* add/reinit an endpoint; this should be done once at the usb_set_configuration command,
+ * but the USB stack is a little bit stateless so we do it at every transaction
+ * if the state of the ed is ED_NEW then a dummy td is added and the state is changed to ED_UNLINK
+ * in all other cases the state is left unchanged
+ * the ed info fields are setted anyway even though most of them should not change */
+
+static ed_t * ep_add_ed (struct usb_device *usb_dev, unsigned long pipe)
+{
+ td_t *td;
+ ed_t *ed_ret;
+ volatile ed_t *ed;
+
+ ed = ed_ret = &ohci_dev.ed[(usb_pipeendpoint (pipe) << 1) |
+ (usb_pipecontrol (pipe)? 0: usb_pipeout (pipe))];
+
+ if ((ed->state & ED_DEL) || (ed->state & ED_URB_DEL)) {
+ err("ep_add_ed: pending delete");
+ /* pending delete request */
+ return NULL;
+ }
+
+ if (ed->state == ED_NEW) {
+ ed->hwINFO = m32_swap (OHCI_ED_SKIP); /* skip ed */
+ /* dummy td; end of td list for ed */
+ td = td_alloc (usb_dev);
+ ed->hwTailP = m32_swap (td);
+ ed->hwHeadP = ed->hwTailP;
+ ed->state = ED_UNLINK;
+ ed->type = usb_pipetype (pipe);
+ ohci_dev.ed_cnt++;
+ }
+
+ ed->hwINFO = m32_swap (usb_pipedevice (pipe)
+ | usb_pipeendpoint (pipe) << 7
+ | (usb_pipeisoc (pipe)? 0x8000: 0)
+ | (usb_pipecontrol (pipe)? 0: (usb_pipeout (pipe)? 0x800: 0x1000))
+ | usb_pipeslow (pipe) << 13
+ | usb_maxpacket (usb_dev, pipe) << 16);
+
+ return ed_ret;
+}
+
+/*-------------------------------------------------------------------------*
+ * TD handling functions
+ *-------------------------------------------------------------------------*/
+
+/* enqueue next TD for this URB (OHCI spec 5.2.8.2) */
+
+static void td_fill (ohci_t *ohci, unsigned int info,
+ void *data, int len,
+ struct usb_device *dev, int index, urb_priv_t *urb_priv)
+{
+ volatile td_t *td, *td_pt;
+#ifdef OHCI_FILL_TRACE
+ int i;
+#endif
+
+ if (index > urb_priv->length) {
+ err("index > length");
+ return;
+ }
+ /* use this td as the next dummy */
+ td_pt = urb_priv->td [index];
+ td_pt->hwNextTD = 0;
+
+ /* fill the old dummy TD */
+ td = urb_priv->td [index] = (td_t *)(m32_swap (urb_priv->ed->hwTailP) & ~0xf);
+
+ td->ed = urb_priv->ed;
+ td->next_dl_td = NULL;
+ td->index = index;
+ td->data = (__u32)data;
+#ifdef OHCI_FILL_TRACE
+ if ((usb_pipetype(urb_priv->pipe) == PIPE_BULK) && usb_pipeout(urb_priv->pipe)) {
+ for (i = 0; i < len; i++)
+ printf("td->data[%d] %#2x ",i, ((unsigned char *)td->data)[i]);
+ printf("\n");
+ }
+#endif
+ if (!len)
+ data = 0;
+
+ td->hwINFO = m32_swap (info);
+ td->hwCBP = m32_swap (data);
+ if (data)
+ td->hwBE = m32_swap (data + len - 1);
+ else
+ td->hwBE = 0;
+ td->hwNextTD = m32_swap (td_pt);
+
+ /* append to queue */
+ td->ed->hwTailP = td->hwNextTD;
+}
+
+/*-------------------------------------------------------------------------*/
+
+/* prepare all TDs of a transfer */
+
+static void td_submit_job (struct usb_device *dev, unsigned long pipe, void *buffer,
+ int transfer_len, struct devrequest *setup, urb_priv_t *urb, int interval)
+{
+ ohci_t *ohci = &gohci;
+ int data_len = transfer_len;
+ void *data;
+ int cnt = 0;
+ __u32 info = 0;
+ unsigned int toggle = 0;
+
+ /* OHCI handles the DATA-toggles itself, we just use the USB-toggle bits for reseting */
+ if(usb_gettoggle(dev, usb_pipeendpoint(pipe), usb_pipeout(pipe))) {
+ toggle = TD_T_TOGGLE;
+ } else {
+ toggle = TD_T_DATA0;
+ usb_settoggle(dev, usb_pipeendpoint(pipe), usb_pipeout(pipe), 1);
+ }
+ urb->td_cnt = 0;
+ if (data_len)
+ data = buffer;
+ else
+ data = 0;
+
+ switch (usb_pipetype (pipe)) {
+ case PIPE_BULK:
+ info = usb_pipeout (pipe)?
+ TD_CC | TD_DP_OUT : TD_CC | TD_DP_IN ;
+ while(data_len > 4096) {
+ td_fill (ohci, info | (cnt? TD_T_TOGGLE:toggle), data, 4096, dev, cnt, urb);
+ data += 4096; data_len -= 4096; cnt++;
+ }
+ info = usb_pipeout (pipe)?
+ TD_CC | TD_DP_OUT : TD_CC | TD_R | TD_DP_IN ;
+ td_fill (ohci, info | (cnt? TD_T_TOGGLE:toggle), data, data_len, dev, cnt, urb);
+ cnt++;
+
+ if (!ohci->sleeping)
+ writel (OHCI_BLF, &ohci->regs->cmdstatus); /* start bulk list */
+ break;
+
+ case PIPE_CONTROL:
+ info = TD_CC | TD_DP_SETUP | TD_T_DATA0;
+ td_fill (ohci, info, setup, 8, dev, cnt++, urb);
+ if (data_len > 0) {
+ info = usb_pipeout (pipe)?
+ TD_CC | TD_R | TD_DP_OUT | TD_T_DATA1 : TD_CC | TD_R | TD_DP_IN | TD_T_DATA1;
+ /* NOTE: mishandles transfers >8K, some >4K */
+ td_fill (ohci, info, data, data_len, dev, cnt++, urb);
+ }
+ info = usb_pipeout (pipe)?
+ TD_CC | TD_DP_IN | TD_T_DATA1: TD_CC | TD_DP_OUT | TD_T_DATA1;
+ td_fill (ohci, info, data, 0, dev, cnt++, urb);
+ if (!ohci->sleeping)
+ writel (OHCI_CLF, &ohci->regs->cmdstatus); /* start Control list */
+ break;
+ }
+ if (urb->length != cnt)
+ dbg("TD LENGTH %d != CNT %d", urb->length, cnt);
+}
+
+/*-------------------------------------------------------------------------*
+ * Done List handling functions
+ *-------------------------------------------------------------------------*/
+
+
+/* calculate the transfer length and update the urb */
+
+static void dl_transfer_length(td_t * td)
+{
+ __u32 tdINFO, tdBE, tdCBP;
+ urb_priv_t *lurb_priv = &urb_priv;
+
+ tdINFO = m32_swap (td->hwINFO);
+ tdBE = m32_swap (td->hwBE);
+ tdCBP = m32_swap (td->hwCBP);
+
+
+ if (!(usb_pipetype (lurb_priv->pipe) == PIPE_CONTROL &&
+ ((td->index == 0) || (td->index == lurb_priv->length - 1)))) {
+ if (tdBE != 0) {
+ if (td->hwCBP == 0)
+ lurb_priv->actual_length += tdBE - td->data + 1;
+ else
+ lurb_priv->actual_length += tdCBP - td->data;
+ }
+ }
+}
+
+/*-------------------------------------------------------------------------*/
+
+/* replies to the request have to be on a FIFO basis so
+ * we reverse the reversed done-list */
+
+static td_t * dl_reverse_done_list (ohci_t *ohci)
+{
+ __u32 td_list_hc;
+ td_t *td_rev = NULL;
+ td_t *td_list = NULL;
+ urb_priv_t *lurb_priv = NULL;
+
+ td_list_hc = m32_swap (ohci->hcca->done_head) & 0xfffffff0;
+ ohci->hcca->done_head = 0;
+
+ while (td_list_hc) {
+ td_list = (td_t *)td_list_hc;
+
+ if (TD_CC_GET (m32_swap (td_list->hwINFO))) {
+ lurb_priv = &urb_priv;
+ dbg(" USB-error/status: %x : %p",
+ TD_CC_GET (m32_swap (td_list->hwINFO)), td_list);
+ if (td_list->ed->hwHeadP & m32_swap (0x1)) {
+ if (lurb_priv && ((td_list->index + 1) < lurb_priv->length)) {
+ td_list->ed->hwHeadP =
+ (lurb_priv->td[lurb_priv->length - 1]->hwNextTD & m32_swap (0xfffffff0)) |
+ (td_list->ed->hwHeadP & m32_swap (0x2));
+ lurb_priv->td_cnt += lurb_priv->length - td_list->index - 1;
+ } else
+ td_list->ed->hwHeadP &= m32_swap (0xfffffff2);
+ }
+ }
+
+ td_list->next_dl_td = td_rev;
+ td_rev = td_list;
+ td_list_hc = m32_swap (td_list->hwNextTD) & 0xfffffff0;
+ }
+
+ return td_list;
+}
+
+/*-------------------------------------------------------------------------*/
+
+/* td done list */
+static int dl_done_list (ohci_t *ohci, td_t *td_list)
+{
+ td_t *td_list_next = NULL;
+ ed_t *ed;
+ int cc = 0;
+ int stat = 0;
+ /* urb_t *urb; */
+ urb_priv_t *lurb_priv;
+ __u32 tdINFO, edHeadP, edTailP;
+
+ while (td_list) {
+ td_list_next = td_list->next_dl_td;
+
+ lurb_priv = &urb_priv;
+ tdINFO = m32_swap (td_list->hwINFO);
+
+ ed = td_list->ed;
+
+ dl_transfer_length(td_list);
+
+ /* error code of transfer */
+ cc = TD_CC_GET (tdINFO);
+ if (cc != 0) {
+ dbg("ConditionCode %#x", cc);
+ stat = cc_to_error[cc];
+ }
+
+ /* see if this done list makes for all TD's of current URB,
+ * and mark the URB finished if so */
+ if (++(lurb_priv->td_cnt) == lurb_priv->length) {
+ if ((ed->state & (ED_OPER | ED_UNLINK)))
+ urb_finished = 1;
+ else
+ dbg("dl_done_list: strange.., ED state %x, ed->state\n");
+ } else
+ dbg("dl_done_list: processing TD %x, len %x\n", lurb_priv->td_cnt,
+ lurb_priv->length);
+
+ if (ed->state != ED_NEW) {
+ edHeadP = m32_swap (ed->hwHeadP) & 0xfffffff0;
+ edTailP = m32_swap (ed->hwTailP);
+
+ /* unlink eds if they are not busy */
+ if ((edHeadP == edTailP) && (ed->state == ED_OPER))
+ ep_unlink (ohci, ed);
+ }
+
+ td_list = td_list_next;
+ }
+ return stat;
+}
+
+/*-------------------------------------------------------------------------*
+ * Virtual Root Hub
+ *-------------------------------------------------------------------------*/
+
+/* Device descriptor */
+static __u8 root_hub_dev_des[] =
+{
+ 0x12, /* __u8 bLength; */
+ 0x01, /* __u8 bDescriptorType; Device */
+ 0x10, /* __u16 bcdUSB; v1.1 */
+ 0x01,
+ 0x09, /* __u8 bDeviceClass; HUB_CLASSCODE */
+ 0x00, /* __u8 bDeviceSubClass; */
+ 0x00, /* __u8 bDeviceProtocol; */
+ 0x08, /* __u8 bMaxPacketSize0; 8 Bytes */
+ 0x00, /* __u16 idVendor; */
+ 0x00,
+ 0x00, /* __u16 idProduct; */
+ 0x00,
+ 0x00, /* __u16 bcdDevice; */
+ 0x00,
+ 0x00, /* __u8 iManufacturer; */
+ 0x01, /* __u8 iProduct; */
+ 0x00, /* __u8 iSerialNumber; */
+ 0x01 /* __u8 bNumConfigurations; */
+};
+
+
+/* Configuration descriptor */
+static __u8 root_hub_config_des[] =
+{
+ 0x09, /* __u8 bLength; */
+ 0x02, /* __u8 bDescriptorType; Configuration */
+ 0x19, /* __u16 wTotalLength; */
+ 0x00,
+ 0x01, /* __u8 bNumInterfaces; */
+ 0x01, /* __u8 bConfigurationValue; */
+ 0x00, /* __u8 iConfiguration; */
+ 0x40, /* __u8 bmAttributes;
+ Bit 7: Bus-powered, 6: Self-powered, 5 Remote-wakwup, 4..0: resvd */
+ 0x00, /* __u8 MaxPower; */
+
+ /* interface */
+ 0x09, /* __u8 if_bLength; */
+ 0x04, /* __u8 if_bDescriptorType; Interface */
+ 0x00, /* __u8 if_bInterfaceNumber; */
+ 0x00, /* __u8 if_bAlternateSetting; */
+ 0x01, /* __u8 if_bNumEndpoints; */
+ 0x09, /* __u8 if_bInterfaceClass; HUB_CLASSCODE */
+ 0x00, /* __u8 if_bInterfaceSubClass; */
+ 0x00, /* __u8 if_bInterfaceProtocol; */
+ 0x00, /* __u8 if_iInterface; */
+
+ /* endpoint */
+ 0x07, /* __u8 ep_bLength; */
+ 0x05, /* __u8 ep_bDescriptorType; Endpoint */
+ 0x81, /* __u8 ep_bEndpointAddress; IN Endpoint 1 */
+ 0x03, /* __u8 ep_bmAttributes; Interrupt */
+ 0x02, /* __u16 ep_wMaxPacketSize; ((MAX_ROOT_PORTS + 1) / 8 */
+ 0x00,
+ 0xff /* __u8 ep_bInterval; 255 ms */
+};
+
+static unsigned char root_hub_str_index0[] =
+{
+ 0x04, /* __u8 bLength; */
+ 0x03, /* __u8 bDescriptorType; String-descriptor */
+ 0x09, /* __u8 lang ID */
+ 0x04, /* __u8 lang ID */
+};
+
+static unsigned char root_hub_str_index1[] =
+{
+ 28, /* __u8 bLength; */
+ 0x03, /* __u8 bDescriptorType; String-descriptor */
+ 'O', /* __u8 Unicode */
+ 0, /* __u8 Unicode */
+ 'H', /* __u8 Unicode */
+ 0, /* __u8 Unicode */
+ 'C', /* __u8 Unicode */
+ 0, /* __u8 Unicode */
+ 'I', /* __u8 Unicode */
+ 0, /* __u8 Unicode */
+ ' ', /* __u8 Unicode */
+ 0, /* __u8 Unicode */
+ 'R', /* __u8 Unicode */
+ 0, /* __u8 Unicode */
+ 'o', /* __u8 Unicode */
+ 0, /* __u8 Unicode */
+ 'o', /* __u8 Unicode */
+ 0, /* __u8 Unicode */
+ 't', /* __u8 Unicode */
+ 0, /* __u8 Unicode */
+ ' ', /* __u8 Unicode */
+ 0, /* __u8 Unicode */
+ 'H', /* __u8 Unicode */
+ 0, /* __u8 Unicode */
+ 'u', /* __u8 Unicode */
+ 0, /* __u8 Unicode */
+ 'b', /* __u8 Unicode */
+ 0, /* __u8 Unicode */
+};
+
+/* Hub class-specific descriptor is constructed dynamically */
+
+
+/*-------------------------------------------------------------------------*/
+
+#define OK(x) len = (x); break
+#ifdef DEBUG
+#define WR_RH_STAT(x) {info("WR:status %#8x", (x));writel((x), &gohci.regs->roothub.status);}
+#define WR_RH_PORTSTAT(x) {info("WR:portstatus[%d] %#8x", wIndex-1, (x));writel((x), &gohci.regs->roothub.portstatus[wIndex-1]);}
+#else
+#define WR_RH_STAT(x) writel((x), &gohci.regs->roothub.status)
+#define WR_RH_PORTSTAT(x) writel((x), &gohci.regs->roothub.portstatus[wIndex-1])
+#endif
+#define RD_RH_STAT roothub_status(&gohci)
+#define RD_RH_PORTSTAT roothub_portstatus(&gohci,wIndex-1)
+
+/* request to virtual root hub */
+
+int rh_check_port_status(ohci_t *controller)
+{
+ __u32 temp, ndp, i;
+ int res;
+
+ res = -1;
+ temp = roothub_a (controller);
+ ndp = (temp & RH_A_NDP);
+ for (i = 0; i < ndp; i++) {
+ temp = roothub_portstatus (controller, i);
+ /* check for a device disconnect */
+ if (((temp & (RH_PS_PESC | RH_PS_CSC)) ==
+ (RH_PS_PESC | RH_PS_CSC)) &&
+ ((temp & RH_PS_CCS) == 0)) {
+ res = i;
+ break;
+ }
+ }
+ return res;
+}
+
+static int ohci_submit_rh_msg(struct usb_device *dev, unsigned long pipe,
+ void *buffer, int transfer_len, struct devrequest *cmd)
+{
+ void * data = buffer;
+ int leni = transfer_len;
+ int len = 0;
+ int stat = 0;
+ __u32 datab[4];
+ __u8 *data_buf = (__u8 *)datab;
+ __u16 bmRType_bReq;
+ __u16 wValue;
+ __u16 wIndex;
+ __u16 wLength;
+
+#ifdef DEBUG
+urb_priv.actual_length = 0;
+pkt_print(dev, pipe, buffer, transfer_len, cmd, "SUB(rh)", usb_pipein(pipe));
+#else
+ wait_ms(1);
+#endif
+ if ((pipe & PIPE_INTERRUPT) == PIPE_INTERRUPT) {
+ info("Root-Hub submit IRQ: NOT implemented");
+ return 0;
+ }
+
+ bmRType_bReq = cmd->requesttype | (cmd->request << 8);
+ wValue = m16_swap (cmd->value);
+ wIndex = m16_swap (cmd->index);
+ wLength = m16_swap (cmd->length);
+
+ info("Root-Hub: adr: %2x cmd(%1x): %08x %04x %04x %04x",
+ dev->devnum, 8, bmRType_bReq, wValue, wIndex, wLength);
+
+ switch (bmRType_bReq) {
+ /* Request Destination:
+ without flags: Device,
+ RH_INTERFACE: interface,
+ RH_ENDPOINT: endpoint,
+ RH_CLASS means HUB here,
+ RH_OTHER | RH_CLASS almost ever means HUB_PORT here
+ */
+
+ case RH_GET_STATUS:
+ *(__u16 *) data_buf = m16_swap (1); OK (2);
+ case RH_GET_STATUS | RH_INTERFACE:
+ *(__u16 *) data_buf = m16_swap (0); OK (2);
+ case RH_GET_STATUS | RH_ENDPOINT:
+ *(__u16 *) data_buf = m16_swap (0); OK (2);
+ case RH_GET_STATUS | RH_CLASS:
+ *(__u32 *) data_buf = m32_swap (
+ RD_RH_STAT & ~(RH_HS_CRWE | RH_HS_DRWE));
+ OK (4);
+ case RH_GET_STATUS | RH_OTHER | RH_CLASS:
+ *(__u32 *) data_buf = m32_swap (RD_RH_PORTSTAT); OK (4);
+
+ case RH_CLEAR_FEATURE | RH_ENDPOINT:
+ switch (wValue) {
+ case (RH_ENDPOINT_STALL): OK (0);
+ }
+ break;
+
+ case RH_CLEAR_FEATURE | RH_CLASS:
+ switch (wValue) {
+ case RH_C_HUB_LOCAL_POWER:
+ OK(0);
+ case (RH_C_HUB_OVER_CURRENT):
+ WR_RH_STAT(RH_HS_OCIC); OK (0);
+ }
+ break;
+
+ case RH_CLEAR_FEATURE | RH_OTHER | RH_CLASS:
+ switch (wValue) {
+ case (RH_PORT_ENABLE):
+ WR_RH_PORTSTAT (RH_PS_CCS ); OK (0);
+ case (RH_PORT_SUSPEND):
+ WR_RH_PORTSTAT (RH_PS_POCI); OK (0);
+ case (RH_PORT_POWER):
+ WR_RH_PORTSTAT (RH_PS_LSDA); OK (0);
+ case (RH_C_PORT_CONNECTION):
+ WR_RH_PORTSTAT (RH_PS_CSC ); OK (0);
+ case (RH_C_PORT_ENABLE):
+ WR_RH_PORTSTAT (RH_PS_PESC); OK (0);
+ case (RH_C_PORT_SUSPEND):
+ WR_RH_PORTSTAT (RH_PS_PSSC); OK (0);
+ case (RH_C_PORT_OVER_CURRENT):
+ WR_RH_PORTSTAT (RH_PS_OCIC); OK (0);
+ case (RH_C_PORT_RESET):
+ WR_RH_PORTSTAT (RH_PS_PRSC); OK (0);
+ }
+ break;
+
+ case RH_SET_FEATURE | RH_OTHER | RH_CLASS:
+ switch (wValue) {
+ case (RH_PORT_SUSPEND):
+ WR_RH_PORTSTAT (RH_PS_PSS ); OK (0);
+ case (RH_PORT_RESET): /* BUG IN HUP CODE *********/
+ if (RD_RH_PORTSTAT & RH_PS_CCS)
+ WR_RH_PORTSTAT (RH_PS_PRS);
+ OK (0);
+ case (RH_PORT_POWER):
+ WR_RH_PORTSTAT (RH_PS_PPS ); OK (0);
+ case (RH_PORT_ENABLE): /* BUG IN HUP CODE *********/
+ if (RD_RH_PORTSTAT & RH_PS_CCS)
+ WR_RH_PORTSTAT (RH_PS_PES );
+ OK (0);
+ }
+ break;
+
+ case RH_SET_ADDRESS: gohci.rh.devnum = wValue; OK(0);
+
+ case RH_GET_DESCRIPTOR:
+ switch ((wValue & 0xff00) >> 8) {
+ case (0x01): /* device descriptor */
+ len = min_t(unsigned int,
+ leni,
+ min_t(unsigned int,
+ sizeof (root_hub_dev_des),
+ wLength));
+ data_buf = root_hub_dev_des; OK(len);
+ case (0x02): /* configuration descriptor */
+ len = min_t(unsigned int,
+ leni,
+ min_t(unsigned int,
+ sizeof (root_hub_config_des),
+ wLength));
+ data_buf = root_hub_config_des; OK(len);
+ case (0x03): /* string descriptors */
+ if(wValue==0x0300) {
+ len = min_t(unsigned int,
+ leni,
+ min_t(unsigned int,
+ sizeof (root_hub_str_index0),
+ wLength));
+ data_buf = root_hub_str_index0;
+ OK(len);
+ }
+ if(wValue==0x0301) {
+ len = min_t(unsigned int,
+ leni,
+ min_t(unsigned int,
+ sizeof (root_hub_str_index1),
+ wLength));
+ data_buf = root_hub_str_index1;
+ OK(len);
+ }
+ default:
+ stat = USB_ST_STALLED;
+ }
+ break;
+
+ case RH_GET_DESCRIPTOR | RH_CLASS:
+ {
+ __u32 temp = roothub_a (&gohci);
+
+ data_buf [0] = 9; /* min length; */
+ data_buf [1] = 0x29;
+ data_buf [2] = temp & RH_A_NDP;
+ data_buf [3] = 0;
+ if (temp & RH_A_PSM) /* per-port power switching? */
+ data_buf [3] |= 0x1;
+ if (temp & RH_A_NOCP) /* no overcurrent reporting? */
+ data_buf [3] |= 0x10;
+ else if (temp & RH_A_OCPM) /* per-port overcurrent reporting? */
+ data_buf [3] |= 0x8;
+
+ /* corresponds to data_buf[4-7] */
+ datab [1] = 0;
+ data_buf [5] = (temp & RH_A_POTPGT) >> 24;
+ temp = roothub_b (&gohci);
+ data_buf [7] = temp & RH_B_DR;
+ if (data_buf [2] < 7) {
+ data_buf [8] = 0xff;
+ } else {
+ data_buf [0] += 2;
+ data_buf [8] = (temp & RH_B_DR) >> 8;
+ data_buf [10] = data_buf [9] = 0xff;
+ }
+
+ len = min_t(unsigned int, leni,
+ min_t(unsigned int, data_buf [0], wLength));
+ OK (len);
+ }
+
+ case RH_GET_CONFIGURATION: *(__u8 *) data_buf = 0x01; OK (1);
+
+ case RH_SET_CONFIGURATION: WR_RH_STAT (0x10000); OK (0);
+
+ default:
+ dbg ("unsupported root hub command");
+ stat = USB_ST_STALLED;
+ }
+
+#ifdef DEBUG
+ ohci_dump_roothub (&gohci, 1);
+#else
+ wait_ms(1);
+#endif
+
+ len = min_t(int, len, leni);
+ if (data != data_buf)
+ memcpy (data, data_buf, len);
+ dev->act_len = len;
+ dev->status = stat;
+
+#ifdef DEBUG
+ if (transfer_len)
+ urb_priv.actual_length = transfer_len;
+ pkt_print(dev, pipe, buffer, transfer_len, cmd, "RET(rh)", 0/*usb_pipein(pipe)*/);
+#else
+ wait_ms(1);
+#endif
+
+ return stat;
+}
+
+/*-------------------------------------------------------------------------*/
+
+/* common code for handling submit messages - used for all but root hub */
+/* accesses. */
+int submit_common_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
+ int transfer_len, struct devrequest *setup, int interval)
+{
+ int stat = 0;
+ int maxsize = usb_maxpacket(dev, pipe);
+ int timeout;
+
+ /* device pulled? Shortcut the action. */
+ if (devgone == dev) {
+ dev->status = USB_ST_CRC_ERR;
+ return 0;
+ }
+
+#ifdef DEBUG
+ urb_priv.actual_length = 0;
+ pkt_print(dev, pipe, buffer, transfer_len, setup, "SUB", usb_pipein(pipe));
+#else
+ wait_ms(1);
+#endif
+ if (!maxsize) {
+ err("submit_common_message: pipesize for pipe %lx is zero",
+ pipe);
+ return -1;
+ }
+
+ if (sohci_submit_job(dev, pipe, buffer, transfer_len, setup, interval) < 0) {
+ err("sohci_submit_job failed");
+ return -1;
+ }
+
+ wait_ms(10);
+ /* ohci_dump_status(&gohci); */
+
+ /* allow more time for a BULK device to react - some are slow */
+#define BULK_TO 5000 /* timeout in milliseconds */
+ if (usb_pipetype (pipe) == PIPE_BULK)
+ timeout = BULK_TO;
+ else
+ timeout = 100;
+
+ /* wait for it to complete */
+ for (;;) {
+ /* check whether the controller is done */
+ stat = hc_interrupt();
+
+ if (stat < 0) {
+ stat = USB_ST_CRC_ERR;
+ break;
+ }
+
+ /* NOTE: since we are not interrupt driven in U-Boot and always
+ * handle only one URB at a time, we cannot assume the
+ * transaction finished on the first successful return from
+ * hc_interrupt().. unless the flag for current URB is set,
+ * meaning that all TD's to/from device got actually
+ * transferred and processed. If the current URB is not
+ * finished we need to re-iterate this loop so as
+ * hc_interrupt() gets called again as there needs to be some
+ * more TD's to process still */
+ if ((stat >= 0) && (stat != 0xff) && (urb_finished)) {
+ /* 0xff is returned for an SF-interrupt */
+ break;
+ }
+
+ if (--timeout) {
+ wait_ms(1);
+ if (!urb_finished)
+ dbg("\%");
+
+ } else {
+ err("CTL:TIMEOUT ");
+ dbg("submit_common_msg: TO status %x\n", stat);
+ stat = USB_ST_CRC_ERR;
+ urb_finished = 1;
+ break;
+ }
+ }
+
+#if 0
+ /* we got an Root Hub Status Change interrupt */
+ if (got_rhsc) {
+#ifdef DEBUG
+ ohci_dump_roothub (&gohci, 1);
+#endif
+ got_rhsc = 0;
+ /* abuse timeout */
+ timeout = rh_check_port_status(&gohci);
+ if (timeout >= 0) {
+#if 0 /* this does nothing useful, but leave it here in case that changes */
+ /* the called routine adds 1 to the passed value */
+ usb_hub_port_connect_change(gohci.rh.dev, timeout - 1);
+#endif
+ /*
+ * XXX
+ * This is potentially dangerous because it assumes
+ * that only one device is ever plugged in!
+ */
+ devgone = dev;
+ }
+ }
+#endif
+
+ dev->status = stat;
+ dev->act_len = transfer_len;
+
+#ifdef DEBUG
+ pkt_print(dev, pipe, buffer, transfer_len, setup, "RET(ctlr)", usb_pipein(pipe));
+#else
+ wait_ms(1);
+#endif
+
+ /* free TDs in urb_priv */
+ urb_free_priv (&urb_priv);
+ return 0;
+}
+
+/* submit routines called from usb.c */
+int submit_bulk_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
+ int transfer_len)
+{
+ info("submit_bulk_msg");
+ return submit_common_msg(dev, pipe, buffer, transfer_len, NULL, 0);
+}
+
+int submit_control_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
+ int transfer_len, struct devrequest *setup)
+{
+ int maxsize = usb_maxpacket(dev, pipe);
+
+ info("submit_control_msg");
+#ifdef DEBUG
+ urb_priv.actual_length = 0;
+ pkt_print(dev, pipe, buffer, transfer_len, setup, "SUB", usb_pipein(pipe));
+#else
+ wait_ms(1);
+#endif
+ if (!maxsize) {
+ err("submit_control_message: pipesize for pipe %lx is zero",
+ pipe);
+ return -1;
+ }
+ if (((pipe >> 8) & 0x7f) == gohci.rh.devnum) {
+ gohci.rh.dev = dev;
+ /* root hub - redirect */
+ return ohci_submit_rh_msg(dev, pipe, buffer, transfer_len,
+ setup);
+ }
+
+ return submit_common_msg(dev, pipe, buffer, transfer_len, setup, 0);
+}
+
+int submit_int_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
+ int transfer_len, int interval)
+{
+ info("submit_int_msg");
+ return -1;
+}
+
+/*-------------------------------------------------------------------------*
+ * HC functions
+ *-------------------------------------------------------------------------*/
+
+/* reset the HC and BUS */
+
+static int hc_reset (ohci_t *ohci)
+{
+ int timeout = 30;
+ int smm_timeout = 50; /* 0,5 sec */
+
+ if (readl (&ohci->regs->control) & OHCI_CTRL_IR) { /* SMM owns the HC */
+ writel (OHCI_OCR, &ohci->regs->cmdstatus); /* request ownership */
+ info("USB HC TakeOver from SMM");
+ while (readl (&ohci->regs->control) & OHCI_CTRL_IR) {
+ wait_ms (10);
+ if (--smm_timeout == 0) {
+ err("USB HC TakeOver failed!");
+ return -1;
+ }
+ }
+ }
+
+ /* Disable HC interrupts */
+ writel (OHCI_INTR_MIE, &ohci->regs->intrdisable);
+
+ dbg("USB HC reset_hc usb-%s: ctrl = 0x%X ;",
+ ohci->slot_name,
+ readl (&ohci->regs->control));
+
+ /* Reset USB (needed by some controllers) */
+ writel (0, &ohci->regs->control);
+
+ /* HC Reset requires max 10 us delay */
+ writel (OHCI_HCR, &ohci->regs->cmdstatus);
+ while ((readl (&ohci->regs->cmdstatus) & OHCI_HCR) != 0) {
+ if (--timeout == 0) {
+ err("USB HC reset timed out!");
+ return -1;
+ }
+ udelay (1);
+ }
+ return 0;
+}
+
+/*-------------------------------------------------------------------------*/
+
+/* Start an OHCI controller, set the BUS operational
+ * enable interrupts
+ * connect the virtual root hub */
+
+static int hc_start (ohci_t * ohci)
+{
+ __u32 mask;
+ unsigned int fminterval;
+
+ ohci->disabled = 1;
+
+ /* Tell the controller where the control and bulk lists are
+ * The lists are empty now. */
+
+ writel (0, &ohci->regs->ed_controlhead);
+ writel (0, &ohci->regs->ed_bulkhead);
+
+ writel ((__u32)ohci->hcca, &ohci->regs->hcca); /* a reset clears this */
+
+ fminterval = 0x2edf;
+ writel ((fminterval * 9) / 10, &ohci->regs->periodicstart);
+ fminterval |= ((((fminterval - 210) * 6) / 7) << 16);
+ writel (fminterval, &ohci->regs->fminterval);
+ writel (0x628, &ohci->regs->lsthresh);
+
+ /* start controller operations */
+ ohci->hc_control = OHCI_CONTROL_INIT | OHCI_USB_OPER;
+ ohci->disabled = 0;
+ writel (ohci->hc_control, &ohci->regs->control);
+
+ /* disable all interrupts */
+ mask = (OHCI_INTR_SO | OHCI_INTR_WDH | OHCI_INTR_SF | OHCI_INTR_RD |
+ OHCI_INTR_UE | OHCI_INTR_FNO | OHCI_INTR_RHSC |
+ OHCI_INTR_OC | OHCI_INTR_MIE);
+ writel (mask, &ohci->regs->intrdisable);
+ /* clear all interrupts */
+ mask &= ~OHCI_INTR_MIE;
+ writel (mask, &ohci->regs->intrstatus);
+ /* Choose the interrupts we care about now - but w/o MIE */
+ mask = OHCI_INTR_RHSC | OHCI_INTR_UE | OHCI_INTR_WDH | OHCI_INTR_SO;
+ writel (mask, &ohci->regs->intrenable);
+
+#ifdef OHCI_USE_NPS
+ /* required for AMD-756 and some Mac platforms */
+ writel ((roothub_a (ohci) | RH_A_NPS) & ~RH_A_PSM,
+ &ohci->regs->roothub.a);
+ writel (RH_HS_LPSC, &ohci->regs->roothub.status);
+#endif /* OHCI_USE_NPS */
+
+#define mdelay(n) ({unsigned long msec=(n); while (msec--) udelay(1000);})
+ /* POTPGT delay is bits 24-31, in 2 ms units. */
+ mdelay ((roothub_a (ohci) >> 23) & 0x1fe);
+
+ /* connect the virtual root hub */
+ ohci->rh.devnum = 0;
+
+ return 0;
+}
+
+/*-------------------------------------------------------------------------*/
+
+/* an interrupt happens */
+
+static int
+hc_interrupt (void)
+{
+ ohci_t *ohci = &gohci;
+ struct ohci_regs *regs = ohci->regs;
+ int ints;
+ int stat = -1;
+
+ if ((ohci->hcca->done_head != 0) &&
+ !(m32_swap (ohci->hcca->done_head) & 0x01)) {
+
+ ints = OHCI_INTR_WDH;
+
+ } else if ((ints = readl (&regs->intrstatus)) == ~(u32)0) {
+ ohci->disabled++;
+ err ("%s device removed!", ohci->slot_name);
+ return -1;
+
+ } else if ((ints &= readl (&regs->intrenable)) == 0) {
+ dbg("hc_interrupt: returning..\n");
+ return 0xff;
+ }
+
+ /* dbg("Interrupt: %x frame: %x", ints, le16_to_cpu (ohci->hcca->frame_no)); */
+
+ if (ints & OHCI_INTR_RHSC) {
+ got_rhsc = 1;
+ stat = 0xff;
+ }
+
+ if (ints & OHCI_INTR_UE) {
+ ohci->disabled++;
+ err ("OHCI Unrecoverable Error, controller usb-%s disabled",
+ ohci->slot_name);
+ /* e.g. due to PCI Master/Target Abort */
+
+#ifdef DEBUG
+ ohci_dump (ohci, 1);
+#else
+ wait_ms(1);
+#endif
+ /* FIXME: be optimistic, hope that bug won't repeat often. */
+ /* Make some non-interrupt context restart the controller. */
+ /* Count and limit the retries though; either hardware or */
+ /* software errors can go forever... */
+ hc_reset (ohci);
+ return -1;
+ }
+
+ if (ints & OHCI_INTR_WDH) {
+ wait_ms(1);
+
+ writel (OHCI_INTR_WDH, &regs->intrdisable);
+ stat = dl_done_list (&gohci, dl_reverse_done_list (&gohci));
+ writel (OHCI_INTR_WDH, &regs->intrenable);
+ }
+
+ if (ints & OHCI_INTR_SO) {
+ dbg("USB Schedule overrun\n");
+ writel (OHCI_INTR_SO, &regs->intrenable);
+ stat = -1;
+ }
+
+ /* FIXME: this assumes SOF (1/ms) interrupts don't get lost... */
+ if (ints & OHCI_INTR_SF) {
+ unsigned int frame = m16_swap (ohci->hcca->frame_no) & 1;
+ wait_ms(1);
+ writel (OHCI_INTR_SF, &regs->intrdisable);
+ if (ohci->ed_rm_list[frame] != NULL)
+ writel (OHCI_INTR_SF, &regs->intrenable);
+ stat = 0xff;
+ }
+
+ writel (ints, &regs->intrstatus);
+ return stat;
+}
+
+/*-------------------------------------------------------------------------*/
+
+/*-------------------------------------------------------------------------*/
+
+/* De-allocate all resources.. */
+
+static void hc_release_ohci (ohci_t *ohci)
+{
+ dbg ("USB HC release ohci usb-%s", ohci->slot_name);
+
+ if (!ohci->disabled)
+ hc_reset (ohci);
+}
+
+/*-------------------------------------------------------------------------*/
+
+/*
+ * low level initalisation routine, called from usb.c
+ */
+static char ohci_inited = 0;
+
+int usb_lowlevel_init(void)
+{
+ S3C24X0_CLOCK_POWER * const clk_power = S3C24X0_GetBase_CLOCK_POWER();
+ S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
+
+ /*
+ * Set the 48 MHz UPLL clocking. Values are taken from
+ * "PLL value selection guide", 6-23, s3c2400_UM.pdf.
+ */
+ clk_power->UPLLCON = ((40 << 12) + (1 << 4) + 2);
+ gpio->MISCCR |= 0x8; /* 1 = use pads related USB for USB host */
+
+ /*
+ * Enable USB host clock.
+ */
+ clk_power->CLKCON |= (1 << 4);
+
+ memset (&gohci, 0, sizeof (ohci_t));
+ memset (&urb_priv, 0, sizeof (urb_priv_t));
+
+ /* align the storage */
+ if ((__u32)&ghcca[0] & 0xff) {
+ err("HCCA not aligned!!");
+ return -1;
+ }
+ phcca = &ghcca[0];
+ info("aligned ghcca %p", phcca);
+ memset(&ohci_dev, 0, sizeof(struct ohci_device));
+ if ((__u32)&ohci_dev.ed[0] & 0x7) {
+ err("EDs not aligned!!");
+ return -1;
+ }
+ memset(gtd, 0, sizeof(td_t) * (NUM_TD + 1));
+ if ((__u32)gtd & 0x7) {
+ err("TDs not aligned!!");
+ return -1;
+ }
+ ptd = gtd;
+ gohci.hcca = phcca;
+ memset (phcca, 0, sizeof (struct ohci_hcca));
+
+ gohci.disabled = 1;
+ gohci.sleeping = 0;
+ gohci.irq = -1;
+ gohci.regs = (struct ohci_regs *)S3C24X0_USB_HOST_BASE;
+
+ gohci.flags = 0;
+ gohci.slot_name = "s3c2400";
+
+ if (hc_reset (&gohci) < 0) {
+ hc_release_ohci (&gohci);
+ /* Initialization failed */
+ clk_power->CLKCON &= ~(1 << 4);
+ return -1;
+ }
+
+ /* FIXME this is a second HC reset; why?? */
+ writel (gohci.hc_control = OHCI_USB_RESET, &gohci.regs->control);
+ wait_ms (10);
+
+ if (hc_start (&gohci) < 0) {
+ err ("can't start usb-%s", gohci.slot_name);
+ hc_release_ohci (&gohci);
+ /* Initialization failed */
+ clk_power->CLKCON &= ~(1 << 4);
+ return -1;
+ }
+
+#ifdef DEBUG
+ ohci_dump (&gohci, 1);
+#else
+ wait_ms(1);
+#endif
+ ohci_inited = 1;
+ urb_finished = 1;
+
+ return 0;
+}
+
+int usb_lowlevel_stop(void)
+{
+ S3C24X0_CLOCK_POWER * const clk_power = S3C24X0_GetBase_CLOCK_POWER();
+
+ /* this gets called really early - before the controller has */
+ /* even been initialized! */
+ if (!ohci_inited)
+ return 0;
+ /* TODO release any interrupts, etc. */
+ /* call hc_release_ohci() here ? */
+ hc_reset (&gohci);
+ /* may not want to do this */
+ clk_power->CLKCON &= ~(1 << 4);
+ return 0;
+}
+
+#endif /* CONFIG_USB_OHCI */
diff --git a/cpu/arm920t/s3c24x0/usb_ohci.h b/cpu/arm920t/s3c24x0/usb_ohci.h
new file mode 100755
index 0000000..5e9a0fd
--- /dev/null
+++ b/cpu/arm920t/s3c24x0/usb_ohci.h
@@ -0,0 +1,417 @@
+/*
+ * URB OHCI HCD (Host Controller Driver) for USB.
+ *
+ * (C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at>
+ * (C) Copyright 2000-2001 David Brownell <dbrownell@users.sourceforge.net>
+ *
+ * usb-ohci.h
+ */
+
+
+static int cc_to_error[16] = {
+
+/* mapping of the OHCI CC status to error codes */
+ /* No Error */ 0,
+ /* CRC Error */ USB_ST_CRC_ERR,
+ /* Bit Stuff */ USB_ST_BIT_ERR,
+ /* Data Togg */ USB_ST_CRC_ERR,
+ /* Stall */ USB_ST_STALLED,
+ /* DevNotResp */ -1,
+ /* PIDCheck */ USB_ST_BIT_ERR,
+ /* UnExpPID */ USB_ST_BIT_ERR,
+ /* DataOver */ USB_ST_BUF_ERR,
+ /* DataUnder */ USB_ST_BUF_ERR,
+ /* reservd */ -1,
+ /* reservd */ -1,
+ /* BufferOver */ USB_ST_BUF_ERR,
+ /* BuffUnder */ USB_ST_BUF_ERR,
+ /* Not Access */ -1,
+ /* Not Access */ -1
+};
+
+/* ED States */
+#define ED_NEW 0x00
+#define ED_UNLINK 0x01
+#define ED_OPER 0x02
+#define ED_DEL 0x04
+#define ED_URB_DEL 0x08
+
+/* usb_ohci_ed */
+struct ed {
+ __u32 hwINFO;
+ __u32 hwTailP;
+ __u32 hwHeadP;
+ __u32 hwNextED;
+
+ struct ed *ed_prev;
+ __u8 int_period;
+ __u8 int_branch;
+ __u8 int_load;
+ __u8 int_interval;
+ __u8 state;
+ __u8 type;
+ __u16 last_iso;
+ struct ed *ed_rm_list;
+
+ struct usb_device *usb_dev;
+ __u32 unused[3];
+} __attribute((aligned(16)));
+typedef struct ed ed_t;
+
+
+/* TD info field */
+#define TD_CC 0xf0000000
+#define TD_CC_GET(td_p) ((td_p >>28) & 0x0f)
+#define TD_CC_SET(td_p, cc) (td_p) = ((td_p) & 0x0fffffff) | (((cc) & 0x0f) << 28)
+#define TD_EC 0x0C000000
+#define TD_T 0x03000000
+#define TD_T_DATA0 0x02000000
+#define TD_T_DATA1 0x03000000
+#define TD_T_TOGGLE 0x00000000
+#define TD_R 0x00040000
+#define TD_DI 0x00E00000
+#define TD_DI_SET(X) (((X) & 0x07)<< 21)
+#define TD_DP 0x00180000
+#define TD_DP_SETUP 0x00000000
+#define TD_DP_IN 0x00100000
+#define TD_DP_OUT 0x00080000
+
+#define TD_ISO 0x00010000
+#define TD_DEL 0x00020000
+
+/* CC Codes */
+#define TD_CC_NOERROR 0x00
+#define TD_CC_CRC 0x01
+#define TD_CC_BITSTUFFING 0x02
+#define TD_CC_DATATOGGLEM 0x03
+#define TD_CC_STALL 0x04
+#define TD_DEVNOTRESP 0x05
+#define TD_PIDCHECKFAIL 0x06
+#define TD_UNEXPECTEDPID 0x07
+#define TD_DATAOVERRUN 0x08
+#define TD_DATAUNDERRUN 0x09
+#define TD_BUFFEROVERRUN 0x0C
+#define TD_BUFFERUNDERRUN 0x0D
+#define TD_NOTACCESSED 0x0F
+
+
+#define MAXPSW 1
+
+struct td {
+ __u32 hwINFO;
+ __u32 hwCBP; /* Current Buffer Pointer */
+ __u32 hwNextTD; /* Next TD Pointer */
+ __u32 hwBE; /* Memory Buffer End Pointer */
+
+ __u8 unused;
+ __u8 index;
+ struct ed *ed;
+ struct td *next_dl_td;
+ struct usb_device *usb_dev;
+ int transfer_len;
+ __u32 data;
+
+ __u32 unused2[2];
+} __attribute((aligned(32)));
+typedef struct td td_t;
+
+#define OHCI_ED_SKIP (1 << 14)
+
+/*
+ * The HCCA (Host Controller Communications Area) is a 256 byte
+ * structure defined in the OHCI spec. that the host controller is
+ * told the base address of. It must be 256-byte aligned.
+ */
+
+#define NUM_INTS 32 /* part of the OHCI standard */
+struct ohci_hcca {
+ __u32 int_table[NUM_INTS]; /* Interrupt ED table */
+ __u16 frame_no; /* current frame number */
+ __u16 pad1; /* set to 0 on each frame_no change */
+ __u32 done_head; /* info returned for an interrupt */
+ u8 reserved_for_hc[116];
+} __attribute((aligned(256)));
+
+
+/*
+ * Maximum number of root hub ports.
+ */
+#define MAX_ROOT_PORTS 15 /* maximum OHCI root hub ports */
+
+/*
+ * This is the structure of the OHCI controller's memory mapped I/O
+ * region. This is Memory Mapped I/O. You must use the readl() and
+ * writel() macros defined in asm/io.h to access these!!
+ */
+struct ohci_regs {
+ /* control and status registers */
+ __u32 revision;
+ __u32 control;
+ __u32 cmdstatus;
+ __u32 intrstatus;
+ __u32 intrenable;
+ __u32 intrdisable;
+ /* memory pointers */
+ __u32 hcca;
+ __u32 ed_periodcurrent;
+ __u32 ed_controlhead;
+ __u32 ed_controlcurrent;
+ __u32 ed_bulkhead;
+ __u32 ed_bulkcurrent;
+ __u32 donehead;
+ /* frame counters */
+ __u32 fminterval;
+ __u32 fmremaining;
+ __u32 fmnumber;
+ __u32 periodicstart;
+ __u32 lsthresh;
+ /* Root hub ports */
+ struct ohci_roothub_regs {
+ __u32 a;
+ __u32 b;
+ __u32 status;
+ __u32 portstatus[MAX_ROOT_PORTS];
+ } roothub;
+} __attribute((aligned(32)));
+
+
+/* OHCI CONTROL AND STATUS REGISTER MASKS */
+
+/*
+ * HcControl (control) register masks
+ */
+#define OHCI_CTRL_CBSR (3 << 0) /* control/bulk service ratio */
+#define OHCI_CTRL_PLE (1 << 2) /* periodic list enable */
+#define OHCI_CTRL_IE (1 << 3) /* isochronous enable */
+#define OHCI_CTRL_CLE (1 << 4) /* control list enable */
+#define OHCI_CTRL_BLE (1 << 5) /* bulk list enable */
+#define OHCI_CTRL_HCFS (3 << 6) /* host controller functional state */
+#define OHCI_CTRL_IR (1 << 8) /* interrupt routing */
+#define OHCI_CTRL_RWC (1 << 9) /* remote wakeup connected */
+#define OHCI_CTRL_RWE (1 << 10) /* remote wakeup enable */
+
+/* pre-shifted values for HCFS */
+# define OHCI_USB_RESET (0 << 6)
+# define OHCI_USB_RESUME (1 << 6)
+# define OHCI_USB_OPER (2 << 6)
+# define OHCI_USB_SUSPEND (3 << 6)
+
+/*
+ * HcCommandStatus (cmdstatus) register masks
+ */
+#define OHCI_HCR (1 << 0) /* host controller reset */
+#define OHCI_CLF (1 << 1) /* control list filled */
+#define OHCI_BLF (1 << 2) /* bulk list filled */
+#define OHCI_OCR (1 << 3) /* ownership change request */
+#define OHCI_SOC (3 << 16) /* scheduling overrun count */
+
+/*
+ * masks used with interrupt registers:
+ * HcInterruptStatus (intrstatus)
+ * HcInterruptEnable (intrenable)
+ * HcInterruptDisable (intrdisable)
+ */
+#define OHCI_INTR_SO (1 << 0) /* scheduling overrun */
+#define OHCI_INTR_WDH (1 << 1) /* writeback of done_head */
+#define OHCI_INTR_SF (1 << 2) /* start frame */
+#define OHCI_INTR_RD (1 << 3) /* resume detect */
+#define OHCI_INTR_UE (1 << 4) /* unrecoverable error */
+#define OHCI_INTR_FNO (1 << 5) /* frame number overflow */
+#define OHCI_INTR_RHSC (1 << 6) /* root hub status change */
+#define OHCI_INTR_OC (1 << 30) /* ownership change */
+#define OHCI_INTR_MIE (1 << 31) /* master interrupt enable */
+
+
+/* Virtual Root HUB */
+struct virt_root_hub {
+ int devnum; /* Address of Root Hub endpoint */
+ void *dev; /* was urb */
+ void *int_addr;
+ int send;
+ int interval;
+};
+
+/* USB HUB CONSTANTS (not OHCI-specific; see hub.h) */
+
+/* destination of request */
+#define RH_INTERFACE 0x01
+#define RH_ENDPOINT 0x02
+#define RH_OTHER 0x03
+
+#define RH_CLASS 0x20
+#define RH_VENDOR 0x40
+
+/* Requests: bRequest << 8 | bmRequestType */
+#define RH_GET_STATUS 0x0080
+#define RH_CLEAR_FEATURE 0x0100
+#define RH_SET_FEATURE 0x0300
+#define RH_SET_ADDRESS 0x0500
+#define RH_GET_DESCRIPTOR 0x0680
+#define RH_SET_DESCRIPTOR 0x0700
+#define RH_GET_CONFIGURATION 0x0880
+#define RH_SET_CONFIGURATION 0x0900
+#define RH_GET_STATE 0x0280
+#define RH_GET_INTERFACE 0x0A80
+#define RH_SET_INTERFACE 0x0B00
+#define RH_SYNC_FRAME 0x0C80
+/* Our Vendor Specific Request */
+#define RH_SET_EP 0x2000
+
+
+/* Hub port features */
+#define RH_PORT_CONNECTION 0x00
+#define RH_PORT_ENABLE 0x01
+#define RH_PORT_SUSPEND 0x02
+#define RH_PORT_OVER_CURRENT 0x03
+#define RH_PORT_RESET 0x04
+#define RH_PORT_POWER 0x08
+#define RH_PORT_LOW_SPEED 0x09
+
+#define RH_C_PORT_CONNECTION 0x10
+#define RH_C_PORT_ENABLE 0x11
+#define RH_C_PORT_SUSPEND 0x12
+#define RH_C_PORT_OVER_CURRENT 0x13
+#define RH_C_PORT_RESET 0x14
+
+/* Hub features */
+#define RH_C_HUB_LOCAL_POWER 0x00
+#define RH_C_HUB_OVER_CURRENT 0x01
+
+#define RH_DEVICE_REMOTE_WAKEUP 0x00
+#define RH_ENDPOINT_STALL 0x01
+
+#define RH_ACK 0x01
+#define RH_REQ_ERR -1
+#define RH_NACK 0x00
+
+
+/* OHCI ROOT HUB REGISTER MASKS */
+
+/* roothub.portstatus [i] bits */
+#define RH_PS_CCS 0x00000001 /* current connect status */
+#define RH_PS_PES 0x00000002 /* port enable status*/
+#define RH_PS_PSS 0x00000004 /* port suspend status */
+#define RH_PS_POCI 0x00000008 /* port over current indicator */
+#define RH_PS_PRS 0x00000010 /* port reset status */
+#define RH_PS_PPS 0x00000100 /* port power status */
+#define RH_PS_LSDA 0x00000200 /* low speed device attached */
+#define RH_PS_CSC 0x00010000 /* connect status change */
+#define RH_PS_PESC 0x00020000 /* port enable status change */
+#define RH_PS_PSSC 0x00040000 /* port suspend status change */
+#define RH_PS_OCIC 0x00080000 /* over current indicator change */
+#define RH_PS_PRSC 0x00100000 /* port reset status change */
+
+/* roothub.status bits */
+#define RH_HS_LPS 0x00000001 /* local power status */
+#define RH_HS_OCI 0x00000002 /* over current indicator */
+#define RH_HS_DRWE 0x00008000 /* device remote wakeup enable */
+#define RH_HS_LPSC 0x00010000 /* local power status change */
+#define RH_HS_OCIC 0x00020000 /* over current indicator change */
+#define RH_HS_CRWE 0x80000000 /* clear remote wakeup enable */
+
+/* roothub.b masks */
+#define RH_B_DR 0x0000ffff /* device removable flags */
+#define RH_B_PPCM 0xffff0000 /* port power control mask */
+
+/* roothub.a masks */
+#define RH_A_NDP (0xff << 0) /* number of downstream ports */
+#define RH_A_PSM (1 << 8) /* power switching mode */
+#define RH_A_NPS (1 << 9) /* no power switching */
+#define RH_A_DT (1 << 10) /* device type (mbz) */
+#define RH_A_OCPM (1 << 11) /* over current protection mode */
+#define RH_A_NOCP (1 << 12) /* no over current protection */
+#define RH_A_POTPGT (0xff << 24) /* power on to power good time */
+
+/* urb */
+#define N_URB_TD 48
+typedef struct
+{
+ ed_t *ed;
+ __u16 length; /* number of tds associated with this request */
+ __u16 td_cnt; /* number of tds already serviced */
+ int state;
+ unsigned long pipe;
+ int actual_length;
+ td_t *td[N_URB_TD]; /* list pointer to all corresponding TDs associated with this request */
+} urb_priv_t;
+#define URB_DEL 1
+
+/*
+ * This is the full ohci controller description
+ *
+ * Note how the "proper" USB information is just
+ * a subset of what the full implementation needs. (Linus)
+ */
+
+
+typedef struct ohci {
+ struct ohci_hcca *hcca; /* hcca */
+ /*dma_addr_t hcca_dma;*/
+
+ int irq;
+ int disabled; /* e.g. got a UE, we're hung */
+ int sleeping;
+ unsigned long flags; /* for HC bugs */
+
+ struct ohci_regs *regs; /* OHCI controller's memory */
+
+ ed_t *ed_rm_list[2]; /* lists of all endpoints to be removed */
+ ed_t *ed_bulktail; /* last endpoint of bulk list */
+ ed_t *ed_controltail; /* last endpoint of control list */
+ int intrstatus;
+ __u32 hc_control; /* copy of the hc control reg */
+ struct usb_device *dev[32];
+ struct virt_root_hub rh;
+
+ const char *slot_name;
+} ohci_t;
+
+#define NUM_EDS 8 /* num of preallocated endpoint descriptors */
+
+struct ohci_device {
+ ed_t ed[NUM_EDS];
+ int ed_cnt;
+};
+
+/* hcd */
+/* endpoint */
+static int ep_link(ohci_t * ohci, ed_t * ed);
+static int ep_unlink(ohci_t * ohci, ed_t * ed);
+static ed_t * ep_add_ed(struct usb_device * usb_dev, unsigned long pipe);
+
+/*-------------------------------------------------------------------------*/
+
+/* we need more TDs than EDs */
+#define NUM_TD 64
+
+/* +1 so we can align the storage */
+td_t gtd[NUM_TD+1];
+/* pointers to aligned storage */
+td_t *ptd;
+
+/* TDs ... */
+static inline struct td *
+td_alloc (struct usb_device *usb_dev)
+{
+ int i;
+ struct td *td;
+
+ td = NULL;
+ for (i = 0; i < NUM_TD; i++)
+ {
+ if (ptd[i].usb_dev == NULL)
+ {
+ td = &ptd[i];
+ td->usb_dev = usb_dev;
+ break;
+ }
+ }
+
+ return td;
+}
+
+static inline void
+ed_free (struct ed *ed)
+{
+ ed->usb_dev = NULL;
+}
diff --git a/cpu/arm920t/start.S b/cpu/arm920t/start.S
new file mode 100755
index 0000000..b082fae
--- /dev/null
+++ b/cpu/arm920t/start.S
@@ -0,0 +1,528 @@
+/*
+ * armboot - Startup Code for ARM920 CPU-core
+ *
+ * Copyright (c) 2001 Marius Gröger <mag@sysgo.de>
+ * Copyright (c) 2002 Alex Züpke <azu@sysgo.de>
+ * Copyright (c) 2002 Gary Jennejohn <gj@denx.de>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * Copyright (c) 2008 WonderMedia Technologies, Inc.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ *
+ * WonderMedia Technologies, Inc.
+ * 10F, 529, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C.
+ */
+
+#include <config.h>
+#include <version.h>
+
+/*
+ *************************************************************************
+ *
+ * Jump vector table as in table 3.1 in [1]
+ *
+ *************************************************************************
+ */
+
+.globl _start
+_start: b reset
+ ldr pc, _undefined_instruction
+ ldr pc, _software_interrupt
+ ldr pc, _prefetch_abort
+ ldr pc, _data_abort
+ ldr pc, _not_used
+ ldr pc, _irq
+ ldr pc, _fiq
+
+_undefined_instruction: .word undefined_instruction
+_software_interrupt: .word software_interrupt
+_prefetch_abort: .word prefetch_abort
+_data_abort: .word data_abort
+_not_used: .word not_used
+_irq: .word irq
+_fiq: .word fiq
+
+ .balignl 16,0xdeadbeef
+
+/*
+ *************************************************************************
+ *
+ * Startup Code (reset vector)
+ *
+ * do important init only if we don't start from memory!
+ * relocate armboot to ram
+ * setup stack
+ * jump to second stage
+ *
+ *************************************************************************
+ */
+
+_TEXT_BASE:
+ .word TEXT_BASE
+
+.globl _armboot_start
+_armboot_start:
+ .word _start
+
+/*
+ * These are defined in the board-specific linker script.
+ */
+.globl _bss_start
+_bss_start:
+ .word __bss_start
+
+.globl _bss_end
+_bss_end:
+ .word _end
+
+#ifdef CONFIG_USE_IRQ
+/* IRQ stack memory (calculated at run-time) */
+.globl IRQ_STACK_START
+IRQ_STACK_START:
+ .word 0x0badc0de
+
+/* IRQ stack memory (calculated at run-time) */
+.globl FIQ_STACK_START
+FIQ_STACK_START:
+ .word 0x0badc0de
+#endif
+
+
+/*
+ * the actual reset code
+ */
+
+reset:
+ /*
+ * set the cpu to SVC32 mode
+ */
+ mrs r0,cpsr
+ bic r0,r0,#0x1f
+ orr r0,r0,#0xd3
+ msr cpsr,r0
+
+/* turn off the watchdog */
+#if defined(CONFIG_S3C2400)
+# define pWTCON 0x15300000
+# define INTMSK 0x14400008 /* Interupt-Controller base addresses */
+# define CLKDIVN 0x14800014 /* clock divisor register */
+#elif defined(CONFIG_S3C2410)
+# define pWTCON 0x53000000
+# define INTMSK 0x4A000008 /* Interupt-Controller base addresses */
+# define INTSUBMSK 0x4A00001C
+# define CLKDIVN 0x4C000014 /* clock divisor register */
+#endif
+
+#if defined(CONFIG_S3C2400) || defined(CONFIG_S3C2410)
+ ldr r0, =pWTCON
+ mov r1, #0x0
+ str r1, [r0]
+
+ /*
+ * mask all IRQs by setting all bits in the INTMR - default
+ */
+ mov r1, #0xffffffff
+ ldr r0, =INTMSK
+ str r1, [r0]
+# if defined(CONFIG_S3C2410)
+ ldr r1, =0x3ff
+ ldr r0, =INTSUBMSK
+ str r1, [r0]
+# endif
+
+ /* FCLK:HCLK:PCLK = 1:2:4 */
+ /* default FCLK is 120 MHz ! */
+ ldr r0, =CLKDIVN
+ mov r1, #3
+ str r1, [r0]
+#endif /* CONFIG_S3C2400 || CONFIG_S3C2410 */
+
+ /*
+ * we do sys-critical inits only at reboot,
+ * not when booting from ram!
+ */
+#ifndef CONFIG_SKIP_LOWLEVEL_INIT
+ bl cpu_init_crit
+#endif
+
+#ifndef CONFIG_SKIP_RELOCATE_UBOOT
+relocate: /* relocate U-Boot to RAM */
+ adr r0, _start /* r0 <- current position of code */
+ ldr r1, _TEXT_BASE /* test if we run from flash or RAM */
+ cmp r0, r1 /* don't reloc during debug */
+ beq stack_setup
+
+ ldr r2, _armboot_start
+ ldr r3, _bss_start
+ sub r2, r3, r2 /* r2 <- size of armboot */
+ add r2, r0, r2 /* r2 <- source end address */
+
+copy_loop:
+ ldmia r0!, {r3-r10} /* copy from source address [r0] */
+ stmia r1!, {r3-r10} /* copy to target address [r1] */
+ cmp r0, r2 /* until source end addreee [r2] */
+ ble copy_loop
+#endif /* CONFIG_SKIP_RELOCATE_UBOOT */
+
+ /* Set up the stack */
+stack_setup:
+ ldr r0, _TEXT_BASE /* upper 128 KiB: relocated uboot */
+ sub r0, r0, #CFG_MALLOC_LEN /* malloc area */
+ sub r0, r0, #CFG_GBL_DATA_SIZE /* bdinfo */
+#ifdef CONFIG_USE_IRQ
+ sub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ)
+#endif
+ sub sp, r0, #12 /* leave 3 words for abort-stack */
+
+clear_bss:
+ ldr r0, _bss_start /* find start of bss segment */
+ ldr r1, _bss_end /* stop here */
+ mov r2, #0x00000000 /* clear */
+
+clbss_l:str r2, [r0] /* clear loop... */
+ add r0, r0, #4
+ cmp r0, r1
+ ble clbss_l
+
+#if 0
+ /* try doing this stuff after the relocation */
+ ldr r0, =pWTCON
+ mov r1, #0x0
+ str r1, [r0]
+
+ /*
+ * mask all IRQs by setting all bits in the INTMR - default
+ */
+ mov r1, #0xffffffff
+ ldr r0, =INTMR
+ str r1, [r0]
+
+ /* FCLK:HCLK:PCLK = 1:2:4 */
+ /* default FCLK is 120 MHz ! */
+ ldr r0, =CLKDIVN
+ mov r1, #3
+ str r1, [r0]
+ /* END stuff after relocation */
+#endif
+
+ ldr pc, _start_armboot
+
+_start_armboot: .word start_armboot
+
+
+/*
+ *************************************************************************
+ *
+ * CPU_init_critical registers
+ *
+ * setup important registers
+ * setup memory timing
+ *
+ *************************************************************************
+ */
+
+
+cpu_init_crit:
+
+ /*
+ * Invalidate L1 I/D
+ */
+ mov r0, #0 @ set up for MCR
+ mcr p15, 0, r0, c8, c7, 0 @ invalidate TLBs
+ mcr p15, 0, r0, c7, c5, 0 @ invalidate icache
+ mcr p15, 0, r0, c7, c5, 6 @ invalidate BP array
+ mcr p15, 0, r0, c7, c10, 4 @ DSB
+ mcr p15, 0, r0, c7, c5, 4 @ ISB
+
+ /*
+ * disable MMU stuff and caches
+ */
+ mrc p15, 0, r0, c1, c0, 0
+
+#if defined (CONFIG_WMT)
+ bic r0, r0, #0x00000300 @ clear bits 9:8 (---- --RS)
+ bic r0, r0, #0x0000000F @ clear bits 3:0 (---- WCAM)
+ orr r0, r0, #0x00002000 @ set bit 13 (--V--)
+#else
+ bic r0, r0, #0x00002300 @ clear bits 13, 9:8 (--V- --RS)
+ bic r0, r0, #0x00000087 @ clear bits 7, 2:0 (B--- -CAM)
+#endif
+ orr r0, r0, #0x00000002 @ set bit 2 (A) Align
+ orr r0, r0, #0x00001000 @ set bit 12 (I) I-Cache
+ mcr p15, 0, r0, c1, c0, 0
+
+ /*
+ * before relocating, we have to setup RAM timing
+ * because memory timing is board-dependend, you will
+ * find a lowlevel_init.S in your board directory.
+ */
+ mov ip, lr
+ bl lowlevel_init
+ mov lr, ip
+ mov pc, lr
+
+
+/*
+ *************************************************************************
+ *
+ * Interrupt handling
+ *
+ *************************************************************************
+ */
+
+@
+@ IRQ stack frame.
+@
+#define S_FRAME_SIZE 72
+
+#define S_OLD_R0 68
+#define S_PSR 64
+#define S_PC 60
+#define S_LR 56
+#define S_SP 52
+
+#define S_IP 48
+#define S_FP 44
+#define S_R10 40
+#define S_R9 36
+#define S_R8 32
+#define S_R7 28
+#define S_R6 24
+#define S_R5 20
+#define S_R4 16
+#define S_R3 12
+#define S_R2 8
+#define S_R1 4
+#define S_R0 0
+
+#define MODE_SVC 0x13
+#define I_BIT 0x80
+
+/*
+ * use bad_save_user_regs for abort/prefetch/undef/swi ...
+ * use irq_save_user_regs / irq_restore_user_regs for IRQ/FIQ handling
+ */
+
+ .macro bad_save_user_regs
+ sub sp, sp, #S_FRAME_SIZE
+ stmia sp, {r0 - r12} @ Calling r0-r12
+ ldr r2, _armboot_start
+ sub r2, r2, #(CONFIG_STACKSIZE+CFG_MALLOC_LEN)
+ sub r2, r2, #(CFG_GBL_DATA_SIZE+8) @ set base 2 words into abort stack
+ ldmia r2, {r2 - r3} @ get pc, cpsr
+ add r0, sp, #S_FRAME_SIZE @ restore sp_SVC
+
+ add r5, sp, #S_SP
+ mov r1, lr
+ stmia r5, {r0 - r3} @ save sp_SVC, lr_SVC, pc, cpsr
+ mov r0, sp
+ .endm
+
+ .macro irq_save_user_regs
+ sub sp, sp, #S_FRAME_SIZE
+ stmia sp, {r0 - r12} @ Calling r0-r12
+ add r8, sp, #S_PC
+ stmdb r8, {sp, lr}^ @ Calling SP, LR
+ str lr, [r8, #0] @ Save calling PC
+ mrs r6, spsr
+ str r6, [r8, #4] @ Save CPSR
+ str r0, [r8, #8] @ Save OLD_R0
+ mov r0, sp
+ .endm
+
+ .macro irq_restore_user_regs
+ ldmia sp, {r0 - lr}^ @ Calling r0 - lr
+ mov r0, r0
+ ldr lr, [sp, #S_PC] @ Get PC
+ add sp, sp, #S_FRAME_SIZE
+ subs pc, lr, #4 @ return & move spsr_svc into cpsr
+ .endm
+
+ .macro get_bad_stack
+ ldr r13, _armboot_start @ setup our mode stack
+ sub r13, r13, #(CONFIG_STACKSIZE+CFG_MALLOC_LEN)
+ sub r13, r13, #(CFG_GBL_DATA_SIZE+8) @ reserved a couple spots in abort stack
+
+ str lr, [r13] @ save caller lr / spsr
+ mrs lr, spsr
+ str lr, [r13, #4]
+
+ mov r13, #MODE_SVC @ prepare SVC-Mode
+ @ msr spsr_c, r13
+ msr spsr, r13
+ mov lr, pc
+ movs pc, lr
+ .endm
+
+ .macro get_irq_stack @ setup IRQ stack
+ ldr sp, IRQ_STACK_START
+ .endm
+
+ .macro get_fiq_stack @ setup FIQ stack
+ ldr sp, FIQ_STACK_START
+ .endm
+
+/*
+ * exception handlers
+ */
+ .align 5
+undefined_instruction:
+ get_bad_stack
+ bad_save_user_regs
+ bl do_undefined_instruction
+
+ .align 5
+software_interrupt:
+ get_bad_stack
+ bad_save_user_regs
+ bl do_software_interrupt
+
+ .align 5
+prefetch_abort:
+ get_bad_stack
+ bad_save_user_regs
+ bl do_prefetch_abort
+
+ .align 5
+data_abort:
+ get_bad_stack
+ bad_save_user_regs
+ bl do_data_abort
+
+ .align 5
+not_used:
+ get_bad_stack
+ bad_save_user_regs
+ bl do_not_used
+
+#ifdef CONFIG_USE_IRQ
+
+ .align 5
+irq:
+ get_irq_stack
+ irq_save_user_regs
+ bl do_irq
+ irq_restore_user_regs
+
+ .align 5
+fiq:
+ get_fiq_stack
+ /* someone ought to write a more effiction fiq_save_user_regs */
+ irq_save_user_regs
+ bl do_fiq
+ irq_restore_user_regs
+
+#else
+
+ .align 5
+irq:
+ get_bad_stack
+ bad_save_user_regs
+ bl do_irq
+
+ .align 5
+fiq:
+ get_bad_stack
+ bad_save_user_regs
+ bl do_fiq
+
+#endif
+
+
+
+
+
+//#if 0
+.global memset_32Byte
+memset_32Byte:
+ stmfd sp!,{r3-r12,lr}
+
+ add r7,r0,r2
+
+ ands r4,r0,#0x1f
+ beq set_loop_
+for_align: subs r4,r4,#1 //r4-1
+ blt set_loop_
+ strb r1,[r0],#1
+ b for_align
+
+set_loop_:
+#if 0
+ and r4,r1,r1, lsl #8
+ and r5,r4,r4, lsl #16
+ mov r4,r5
+#endif
+ mov r4,r1
+ add r4,r4,r1,lsl #8
+ add r4,r4,r1,lsl #16
+ add r4,r4,r1,lsl #24
+
+ mov r5,r4
+ mov r8,r4
+ mov r9,r4
+ mov r10,r4
+ mov r11,r4
+ mov r12,r4
+ mov r3,r4
+
+ and r6,r7,#0xffffffe0
+
+main_loop: cmp r0,r6
+ beq last_loop
+ stmia r0!,{r3,r4,r5,r8,r9,r10,r11,r12}
+ //strd r4,r5,[r0],#8
+ b main_loop
+
+last_loop: cmp r0,r7
+ beq memset_quit
+ strb r1,[r0],#1
+ b last_loop
+memset_quit:
+ ldmfd sp!,{r3-r12,pc}
+
+
+
+
+
+.global memcpy_32Byte
+memcpy_32Byte:
+ stmfd sp!,{r3-r12,lr}
+
+ add r7,r1,r2 //r7 src_end addr
+//#if 0
+ ands r4,r0,#0x1f
+ bne byte_cpy
+ ands r5,r1,#0x1f
+ bne byte_cpy
+
+ add r6,r7,#0xffffffe0 //r6 src_aligned_end addr
+dword_cpy: cmp r1,r6
+ beq byte_cpy
+ //ldrd r4,r5,[r1],#8
+ //strd r4,r5,[r0],#8
+ ldmia r1!,{r3,r4,r5,r8,r9,r10,r11,r12}
+ stmia r0!,{r3,r4,r5,r8,r9,r10,r11,r12}
+ b dword_cpy
+//#endif
+
+byte_cpy: cmp r1,r7
+ beq cpy_quit
+ ldrb r4,[r1],#1
+ strb r4,[r0],#1
+ b byte_cpy
+cpy_quit:
+ ldmfd sp!,{r3-r12,pc}
+
+
+//#endif \ No newline at end of file
diff --git a/cpu/arm920t/wmt/Makefile b/cpu/arm920t/wmt/Makefile
new file mode 100755
index 0000000..a3e420e
--- /dev/null
+++ b/cpu/arm920t/wmt/Makefile
@@ -0,0 +1,72 @@
+#
+# (C) Copyright 2000, 2001, 2002
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# Some descriptions of such software. Copyright (c) 2008 WonderMedia Technologies, Inc.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+#
+# WonderMedia Technologies, Inc.
+# 10F, 529, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C.
+#
+
+include $(TOPDIR)/config.mk
+
+LIB = lib$(SOC).a
+
+OBJS = interrupts.o \
+ serial.o \
+ zde.o \
+ upcix.o \
+ pcinet.o \
+ tconvert.o \
+ mem.o \
+ tcrc.o \
+ vpci.o \
+ dma.o \
+ api-loader.o \
+ cypher.o \
+ cypherif.o \
+ mmc.o
+#ether.o \
+#mac.o \
+#macif.o \
+#adapter.o \
+#alloct.o \
+#mii.o \
+#macif.o \
+#gmacif.o \
+#gmii.o \
+#gcard.o \
+#gmib.o \
+#gisr.o \
+#galloct.o \
+#gmac.o \
+#gadapter.o \
+#proto.o \
+#proco.o \
+
+all: .depend $(LIB)
+
+$(LIB): $(OBJS)
+ $(AR) crv $@ $(OBJS)
+
+#########################################################################
+
+.depend: Makefile $(OBJS:.o=.c)
+ $(CC) -M $(CFLAGS) $(OBJS:.o=.c) > $@
+
+sinclude .depend
+
+#########################################################################
diff --git a/cpu/arm920t/wmt/adapter.c b/cpu/arm920t/wmt/adapter.c
new file mode 100755
index 0000000..7c1a322
--- /dev/null
+++ b/cpu/arm920t/wmt/adapter.c
@@ -0,0 +1,503 @@
+/*++
+Copyright (c) 2010 WonderMedia Technologies, Inc.
+
+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, see http://www.gnu.org/licenses/>.
+
+WonderMedia Technologies, Inc.
+10F, 529, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C.
+--*/
+
+
+/* modified by kevin */
+/*#ifndef _GLOBAL_H_
+#include "global.h"
+#endif
+#ifndef _EXTVARS_H_
+#include "extvars.h"
+#endif*/
+
+#if !defined(__UPC_H__)
+#include "upc.h"
+#endif
+#if !defined(__CARD_H__)
+#include "card.h"
+#endif
+#if !defined(__EMACISR_H__)
+/* #include "emacisr.h" */
+#endif
+#if !defined(__ALLOCT_H__)
+#include "alloct.h"
+#endif
+#if !defined(__VPCI_H__)
+#include "vpci.h"
+#endif
+#if !defined(__MAC_H__)
+#include "mac.h"
+#endif
+#if !defined(__ADAPTER_H__)
+#include "adapter.h"
+#endif
+#include "macif.h"
+#if !defined(__DBG_H__)
+#include "dbg.h"
+#endif
+
+/*--------------------- Static Definitions -------------------------*/
+
+/*--------------------- Static Classes ----------------------------*/
+
+/*--------------------- Static Variables --------------------------*/
+
+/*--------------------- Static Functions --------------------------*/
+static void s_vInit(PSAdapterInfo pAdapter, UINT uTotalNum, UINT uIdx);
+
+/*--------------------- Export Variables --------------------------*/
+PSAdapterInfo sg_aAdapter;
+SAdapterOpts g_sOptions = {0, 0, 0, 0, 0, 0};
+
+/*--------------------- Export Functions --------------------------*/
+BOOL
+ADPbBind(
+ PSAdapterInfo pAdapter
+ )
+{
+ /* build RDR/TDR */
+ if (!ALCbAllocateRdrMemory(pAdapter)) {
+ printf("allocate Buffer or RD fail!\n");
+ return FALSE;
+ }
+ if (!ALCbAllocateTdrMemory(pAdapter)) {
+ printf("allocate Buffer or TD fail!\n");
+ return FALSE;
+ }
+
+ ALCvChainRdrMemory(pAdapter);
+ ALCvChainTdrMemory(pAdapter);
+ /* Mac init & mii init */
+ if (!ADPbInitializeEx(pAdapter)) {
+ printf("init ex fail\n");
+ return FALSE;
+ }
+ /* Hook Interrupt Service Routine on IRQ */
+ /* set_irq_handlers(pAdapter->byIrqLevel, pAdapter->pvAdapterIsr); */
+
+ /* Enable Interrupt Mask */
+ /* unmask_interrupt(pAdapter->byIrqLevel); */
+
+ /* MacDump(MACDBG_INFO, ("[ADPbBind] - Hook ISR on IRQ%d\n", pAdapter->byIrqLevel)); */
+
+ /* Start ISR */
+ MACvIntEnable(pAdapter->dwIoBase, pAdapter->byRevId, IMR_MASK_VALUE);
+
+ /* Wait MAUTO to poll twice, then MIISR_LNKFL will be correct status */
+ /* kevin???? */
+ PCAvDelayByIO(CB_DELAY_MII_STABLE * 20000);
+ /* Update link status */
+ pAdapter->bLinkPass = MACbIsCableLinkOk(pAdapter->dwIoBase);
+ if (pAdapter->bLinkPass) {
+ MacDump(MACDBG_INFO, ("[ADPbBind]- Link Pass\n"));
+
+ /* update duplex status */
+ /* NOTE.... here we don't call MIIbIsInFullDuplexMode(), because */
+ /* we won't turn on/off MAUTO */
+ MACvIsInFullDuplexMode(&pAdapter->bFullDuplex, pAdapter->dwIoBase);
+ /* Update speed status */
+ pAdapter->bSpeed100M = MACbIsIn100MMode(pAdapter->dwIoBase, pAdapter->byRevId);
+ } else
+ MacDump(MACDBG_INFO, ("[ADPbBind]- Fail\n"));
+
+ pAdapter->pbyTmpBuff = (PBYTE)mALLOc(CB_MAX_BUF_SIZE);
+ MacDump(MACDBG_INFO, ("[ADPbBind]- Exit!\n"));
+
+ return TRUE;
+}
+
+static BOOL ADPbDynaAllocBuf(
+ PSAdapterInfo pAdapter
+ )
+{
+ /* Allocate RD/TD pointer array & DescBuf SAllocMap array. */
+ /* modified by kevin:mALLOc supplied by u-boot */
+ pAdapter->apRD = (PSRxDesc *)mALLOc(sizeof(PSRxDesc) * pAdapter->cbRD);
+ MacDump(MACDBG_INFO, ("[ADPbDynaAllocBuf] - pAdapter->apRD : %p, size : %d\n", pAdapter->apRD,
+ sizeof(PSRxDesc)*pAdapter->cbRD));
+ pAdapter->aamRxDescBuf = (PSAllocMap)mALLOc(sizeof(SAllocMap) * pAdapter->cbRD);
+ MacDump(MACDBG_INFO, ("[ADPbDynaAllocBuf] - pAdapter->aamRxDescBuf : %p, size : %d\n",
+ pAdapter->aamRxDescBuf, sizeof(SAllocMap) * pAdapter->cbRD));
+
+ pAdapter->apTD = (PSTxDesc *)mALLOc(sizeof(PSTxDesc) * pAdapter->cbTD);
+ MacDump(MACDBG_INFO, ("[ADPbDynaAllocBuf] - pAdapter->apTD : %p, size : %d\n", pAdapter->apTD,
+ sizeof(PSTxDesc)*pAdapter->cbTD));
+ pAdapter->aamTxDescBuf = (PSAllocMap)mALLOc(sizeof(SAllocMap) * pAdapter->cbTD);
+ MacDump(MACDBG_INFO, ("[ADPbDynaAllocBuf] - pAdapter->aamTxDescBuf : %p, size : %d\n",
+ pAdapter->aamTxDescBuf, sizeof(SAllocMap) * pAdapter->cbTD));
+
+ if ((pAdapter->apRD == NULL) || (pAdapter->apTD == NULL) ||
+ (pAdapter->aamTxDescBuf == NULL) || (pAdapter->aamRxDescBuf == NULL))
+ return FALSE;
+
+ return TRUE;
+}
+
+BOOL
+ADPbInitializeEx(
+ PSAdapterInfo pAdapter
+ )
+{
+ BYTE byOrgData, byPMRegOffset;
+
+ /* Fill default value */
+ /* marked by kevin:repeat again */
+ /* ALCvSetDefaultRD(pAdapter); */
+ /* ALCvSetDefaultTD(pAdapter); */
+
+ /* Init PCI */
+ VPCIvInitialize(pAdapter->dwIoBase, pAdapter->byRevId);
+
+ /* Write-clear PME status bit */
+ VPCIvReadB(pAdapter->dwIoBase, PCI_REG_CAP, &byPMRegOffset);
+ VPCIvReadB(pAdapter->dwIoBase, (BYTE)(byPMRegOffset + PM_PMCSR1), &byOrgData);
+ VPCIvWriteB(pAdapter->dwIoBase, (BYTE)(byPMRegOffset + PM_PMCSR1),
+ (BYTE)(PMCSR1_PME_STATUS | byOrgData));
+
+ if (!g_sOptions.bNoInit) {
+ /* Init MAC */
+ MACvInitialize(pAdapter->dwIoBase, pAdapter->byRevId);
+
+ /* PATCH.... */
+ /* PCI speed is too slow on some mainboard will cause */
+ /* tx fifo underflow, so set tx threshold to SF */
+ /* set tx threshold, SF */
+ /* Masked by Ray for WMT */
+ /* MACvSetTxThreshold(pAdapter->dwIoBase, 7); */
+
+ /* Set address filter to accept any packet */
+ /* MACvSetPacketFilter(pAdapter->dwIoBase, PKT_TYPE_PROMISCUOUS); */
+
+ /* Detect PHY is from which company */
+ MIIvReadPhyCmrId(pAdapter->dwIoBase, pAdapter->byRevId, &pAdapter->dwPhyCmrId);
+ /* Init MII */
+ MIIvInitialize(pAdapter->dwIoBase, pAdapter->byRevId, pAdapter->dwPhyCmrId);
+
+ CARDvSetLoopbackMode(pAdapter->dwIoBase, pAdapter->byRevId, CARD_LB_NONE);
+ /* set mii NWAY or AUTO */
+ CARDvSetMediaLinkMode(pAdapter->dwIoBase, pAdapter->byRevId, pAdapter->uConnectionType);
+
+ if (pAdapter->uConnectionType == MEDIA_AUTO) {
+ /* Restart AUTO-NEGO to make sure AUTO-NEGO is correct */
+ /* Modified by Ray, Not sure if this instruction is wrong. */
+ /* MIIvSetResetOn(pAdapter->dwIoBase, pAdapter->byRevId); */
+ MIIvSetReAuto(pAdapter->dwIoBase, pAdapter->byRevId);
+ }
+
+ VNSvOutPortB(pAdapter->dwIoBase + MAC_REG_FLOWCR0, (BYTE)pAdapter->cbRD);
+
+ }
+
+ /* Set init rx/tx descriptor address into chip */
+ MACvSetCurrRxDescAddr(pAdapter->dwIoBase, pAdapter->amRxDescRing.dwPAddr);
+ MACvSetCurrTxDescAddr(pAdapter->dwIoBase, pAdapter->amTxDescRing.dwPAddr);
+
+ /* Set current rx/tx descriptor index to 0 */
+ pAdapter->idxRxCurDesc = 0;
+ pAdapter->idxTxCurDesc = 0;
+ /* added by kevin for checking serviced TD RD status */
+ pAdapter->idxRxdirtyDesc = 0;
+ pAdapter->idxTxdirtyDesc = 0;
+ pAdapter->idxRxPktStartDesc = 0;
+
+ return TRUE;
+}
+
+BOOL
+ADPbShutdown(
+ PSAdapterInfo pAdapter
+ )
+{
+ /* Stop chip */
+ if (!MACbSafeStop(pAdapter->dwIoBase, pAdapter->byRevId))
+ return FALSE;
+
+ /* Stop ISR */
+ MACvIntDisable(pAdapter->dwIoBase, pAdapter->byRevId);
+
+ /* Take off Interrupt Service Routine */
+ /* unset_irq_handlers(pAdapter->byIrqLevel); */
+
+ /* Disable Interrupt */
+ /* mask_interrupt(pAdapter->byIrqLevel); */
+
+ MacDump(MACDBG_INFO, ("[ADPbShutdown] - Take off ISR on IRQ%d\n", pAdapter->byIrqLevel));
+
+ /* Destroy RDR/TDR */
+ /* ALCvFreeRdrMemory(pAdapter); */
+ /* ALCvFreeTdrMemory(pAdapter); */
+
+ if (pAdapter->pbyTmpBuff != NULL)
+ pAdapter->pbyTmpBuff = NULL;
+
+ return TRUE;
+}
+
+UINT
+ADPuInitAll(
+ void
+ )
+{
+ int ii;
+ UINT uTotalDev = 0;
+
+ /* modified by kevin:mALLOc supplied by u-boot */
+ if (!g_bInit) {
+ sg_aAdapter = (PSAdapterInfo)mALLOc(sizeof(SAdapterInfo) * CB_MAX_NET_DEVICE);
+
+ if (sg_aAdapter != NULL) {
+ /* modifiey by kevin:memset supplied by u-boot */
+ memset(sg_aAdapter, 0, sizeof(SAdapterInfo) * CB_MAX_NET_DEVICE);
+ } else {
+ return 0;
+ }
+ }
+
+ for (ii = 0; ii < CB_MAX_NET_DEVICE; ii++) {
+ s_vInit(&sg_aAdapter[ii], CB_MAX_NET_DEVICE, ii);
+
+ if ((&sg_aAdapter[ii])->wDevId == W_DEVICE_ID_3106A ||
+ (&sg_aAdapter[ii])->wDevId == W_DEVICE_ID_3053A)
+ uTotalDev++;
+ }
+
+ return uTotalDev;
+}
+
+VOID
+CARDvSetLoopbackMode(
+ DWORD dwIoBase,
+ BYTE byRevId,
+ WORD wLoopbackMode
+ )
+{
+ switch (wLoopbackMode) {
+ case CARD_LB_NONE:
+ case CARD_LB_MAC:
+ case CARD_LB_MII:
+ break;
+ default:
+ /* DBG_ASSERT(FALSE); */
+ break;
+ }
+
+ /* set MAC loopback */
+ MACvSetLoopbackMode(dwIoBase, LOBYTE(wLoopbackMode));
+ /* set MII loopback */
+ MIIvSetLoopbackMode(dwIoBase, byRevId, HIBYTE(wLoopbackMode));
+}
+
+VOID
+CARDvSetMediaLinkMode(
+ DWORD dwIoBase,
+ BYTE byRevId,
+ UINT uConnectionType
+ )
+{
+ DWORD dwData;
+
+ MIIbReadEmbedded(dwIoBase, byRevId, MII_REG_PHYID2, (PWORD)&dwData);
+ MIIbReadEmbedded(dwIoBase, byRevId, MII_REG_PHYID1, (PWORD)&dwData + 1);
+
+ /* If connection type is AUTO */
+ if (uConnectionType == MEDIA_AUTO) {
+ /* Set duplex mode of MAC according to duplex mode of MII */
+ if (MIIbIsInFullDuplexMode(dwIoBase, byRevId))
+ MACvSetDuplexMode(dwIoBase, byRevId, TRUE);
+ else
+ MACvSetDuplexMode(dwIoBase, byRevId, FALSE);
+
+ MIIvRegBitsOn(dwIoBase, byRevId, MII_REG_ANAR, ANAR_TXFD|ANAR_TX|ANAR_10FD|ANAR_10);
+ /* not force */
+ MIIvRegBitsOff(dwIoBase, byRevId, MII_REG_MODCFG, 1);
+
+ /* enable AUTO-NEGO mode */
+ MIIvSetAutoNegotiationOn(dwIoBase, byRevId);
+ } else {
+ /* If not, then */
+ /* 1). Turn off AUTO-NEGO */
+ /* 2). Set USER-FORCED speed (10/100) & duplex (half/full) mode of MII and MAC */
+
+ /* For 3065/3106, Nway-force */
+ WORD wANAR;
+
+ MIIvSetAutoNegotiationOff(dwIoBase, byRevId);
+ MIIbReadEmbedded(dwIoBase, byRevId, MII_REG_ANAR, &wANAR);
+
+ wANAR &= (~(ANAR_TXFD|ANAR_TX|ANAR_10FD|ANAR_10));
+
+ switch (uConnectionType) {
+ case MEDIA_100M_FULL:
+ wANAR |= ANAR_TXFD;
+ MACvSetDuplexMode(dwIoBase, byRevId, TRUE);
+ break;
+
+ case MEDIA_100M_HALF:
+ wANAR |= ANAR_TX;
+ MACvSetDuplexMode(dwIoBase, byRevId, FALSE);
+ break;
+
+ case MEDIA_10M_FULL:
+ wANAR |= ANAR_10FD;
+ MACvSetDuplexMode(dwIoBase, byRevId, TRUE);
+ break;
+
+ case MEDIA_10M_HALF:
+ wANAR |= ANAR_10;
+ MACvSetDuplexMode(dwIoBase, byRevId, FALSE);
+ break;
+
+ default:
+ break;
+ }
+
+ MIIbWriteEmbedded(dwIoBase, byRevId, MII_REG_ANAR, wANAR);
+ /* force */
+ MIIvRegBitsOn(dwIoBase, byRevId, MII_REG_MODCFG, 1);
+
+ /* Enable AUTO-NEGO mode */
+ MIIvSetAutoNegotiationOn(dwIoBase, byRevId);
+ }
+}
+
+static void s_vInit(
+ PSAdapterInfo pAdapter,
+ UINT uTotalNum,
+ UINT uIdx
+ )
+{
+ int ii;
+ unsigned char check;
+
+ pAdapter->cbTotalAdapterNum = uTotalNum;
+ pAdapter->uAdapterIndex = uIdx;
+
+ /* Save Memory Mapped IO base address */
+ switch (uIdx) {
+ case 0:
+ pAdapter->dwIoBase = BA_MAC0;
+ break;
+
+ case 1:
+ pAdapter->dwIoBase = BA_MAC1;
+ break;
+
+ default:
+ break;
+ }
+ MacDump(MACDBG_INFO, ("Memory mapped IO base address:%08X\n", pAdapter->dwIoBase));
+
+ /* check vee oe pee */
+ VNSvInPortB(pAdapter->dwIoBase+0x77, &check);
+ if (check & 0x40){
+ /* Issue AUTOLD in EECSR to reload eeprom to ensure right data from eeprom */
+ MACvRegBitsOn(pAdapter->dwIoBase, MAC_REG_EECSR, EECSR_AUTOLD);
+ /* set VEELD */
+ VNSvOutPortB(pAdapter->dwIoBase+PCI_Configuration_Space_Offset+VMSTS, 0x1);
+ /* wait until VEELD is set */
+ ii = 0;
+ while (1) {
+ VNSvInPortB(pAdapter->dwIoBase+PCI_Configuration_Space_Offset+VMSTS, &check);
+ if (check&0x2 || ii == MaxTimeOut)
+ break;
+ ii++;
+ }
+ /* clear VEELD */
+ VNSvOutPortB(pAdapter->dwIoBase+PCI_Configuration_Space_Offset+VMSTS, 0x0);
+ } else {
+ /* Issue AUTOLD in EECSR to reload eeprom to ensure right data from eeprom */
+ MACvRegBitsOn(pAdapter->dwIoBase, MAC_REG_EECSR, EECSR_AUTOLD);
+ /* Wait until EEPROM loading complete */
+ while (TRUE) {
+ BYTE byData;
+ VNSvInPortB(pAdapter->dwIoBase + MAC_REG_EECSR, &byData);
+ if (BITbIsBitOff(byData, EECSR_AUTOLD))
+ break;
+ }
+ }
+
+ /* Get Device ID from PCI configuration space */
+ VPCIvReadW(pAdapter->dwIoBase, PCI_REG_DEVICE_ID, &pAdapter->wDevId);
+ MacDump(MACDBG_INFO, ("Device ID:%04X\n", pAdapter->wDevId));
+
+ if (pAdapter->wDevId != W_DEVICE_ID_3106A && pAdapter->wDevId != W_DEVICE_ID_3053A)
+ return;
+
+ /* Get Revision ID from PCI configuration */
+ VPCIvReadB(pAdapter->dwIoBase, PCI_REG_REV_ID, &pAdapter->byRevId);
+ MacDump(MACDBG_INFO, ("Revision ID:%02X\n", pAdapter->byRevId));
+
+ /* Clear sticky bits */
+ if (g_sOptions.ulInitCmds & INIT_CMD_CLEAR_STICKHW)
+ MACvClearStckDS(pAdapter->dwIoBase);
+
+ if (g_sOptions.byRevId != 0)
+ pAdapter->byRevId = g_sOptions.byRevId;
+
+ /* Set RD,TD number for this adapter now */
+ /* For 3065, 3106J, 3206 */
+ pAdapter->cbRD = (g_sOptions.iRDescNum) ? g_sOptions.iRDescNum : CB_INIT_RD_NUM;
+ pAdapter->cbTD = (g_sOptions.iTDescNum) ? g_sOptions.iTDescNum : CB_INIT_TD_NUM;
+
+ /* Save IRQ number */
+ switch (uIdx) {
+ case 0:
+ pAdapter->byIrqLevel = IRQ_ETH0;
+ /* pAdapter->pvAdapterIsr = ISRvIsrForMAC0; */
+ break;
+
+ case 1:
+ pAdapter->byIrqLevel = IRQ_ETH1;
+ /* pAdapter->pvAdapterIsr = ISRvIsrForMAC1; */
+ break;
+
+ default:
+ break;
+ }
+
+ g_sOptions.uiBuffsize = (g_sOptions.uiBuffsize) ? g_sOptions.uiBuffsize : CB_MAX_BUF_SIZE;
+
+ /* Get the offset of PM Capability and save it from pci configuration space */
+ VPCIvReadB(pAdapter->dwIoBase, PCI_REG_CAP, &pAdapter->byPMRegOffset);
+
+ /* Get PHY address */
+ pAdapter->byPhyId = MACbyGetPhyId(pAdapter->dwIoBase);
+ MacDump(MACDBG_INFO, ("PHY Address:%02X\n", pAdapter->byPhyId));
+
+ /* Get Ethernet address */
+ for (ii = 0; ii < U_ETHER_ADDR_LEN; ii++)
+ VNSvInPortB(pAdapter->dwIoBase + MAC_REG_PAR, pAdapter->abyEtherAddr + ii);
+
+ /* Allocate RD/TD poiter array & DescBuf array data structure */
+ if (!g_bInit) {
+ if (!ADPbDynaAllocBuf(pAdapter)) {
+ printf("ADPbDynaAllocBuf() can't allocate buffer.\n");
+ return;
+ }
+ }
+
+ pAdapter->dwCacheLineSize = sizeof(DWORD) * 4;
+
+ /* Set default value of connection type to MEDIA_AUTO */
+ pAdapter->uConnectionType = MEDIA_AUTO;
+
+ /* Init default descriptor number per packet in monitor mode */
+ pAdapter->uTxDescNumPerPacket = 1;
+
+ /* Background timer send as default */
+ pAdapter->bTxContFunTest = TRUE;
+}
diff --git a/cpu/arm920t/wmt/adapter.h b/cpu/arm920t/wmt/adapter.h
new file mode 100755
index 0000000..8d4a8d8
--- /dev/null
+++ b/cpu/arm920t/wmt/adapter.h
@@ -0,0 +1,201 @@
+/*++
+Copyright (c) 2010 WonderMedia Technologies, Inc.
+
+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, see http://www.gnu.org/licenses/>.
+
+WonderMedia Technologies, Inc.
+10F, 529, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C.
+--*/
+
+
+#ifndef __ADAPTER_H__
+#define __ADAPTER_H__
+
+#if !defined(__TTYPE_H__)
+#include "ttype.h"
+#endif
+#if !defined(__TETHER_H__)
+#include "tether.h"
+#endif
+#if !defined(__MIB_H__)
+#include "mib.h"
+#endif
+
+#include <malloc.h>
+
+#if !defined(__DESC_H__)
+#include "desc.h"
+#endif
+#if !defined(__MEM_H__)
+#include "mem.h"
+#endif
+#include <common.h>
+#include "tbit.h"
+/*--------------------- Export Definitions -------------------------*/
+//
+// constants
+//
+#define W_DEVICE_ID_3106A 0x3106 // device ID for 3106A
+#define W_DEVICE_ID_3053A 0x3053
+
+//
+// Adapter Information
+//
+typedef struct tagSAdapterInfo {
+
+ UINT cbTotalAdapterNum;
+ UINT uAdapterIndex; // device index
+
+ // got from PCI regs
+ WORD wDevId; // The Device ID of this adapter
+ BYTE byRevId; // The Revision Number of this adapter
+ DWORD dwIoBase;
+ BYTE byPMRegOffset; // the content of Cap_Ptr
+
+ // got from MAC regs (loaded from EEPROM)
+ BYTE byPhyId;
+ BYTE abyEtherAddr[U_ETHER_ADDR_LEN];
+
+ // got from MII regs (updated by Link-Change)
+ DWORD dwPhyCmrId; // Company/Module/Revision ID of the PHY
+ BOOL bLinkPass; // current link status
+ BOOL bSpeed100M; // current speed status
+ BOOL bFullDuplex; // current duplex status
+ UINT uConnectionType; // for media connect type parameter
+
+ // for RDR
+ UINT cbRD; // number of total RD
+ PSRxDesc *apRD; // RD pointer array
+ SAllocMap amRxDescRing;
+ SAllocMap *aamRxDescBuf;
+ int idxRxCurDesc;
+ int idxRxdirtyDesc;
+ int idxRxPktStartDesc; // if multi-RD, this is the starting RD
+
+ // for TDR
+ UINT cbTD; // number of total TD
+ PSTxDesc *apTD; // TD pointer array
+ SAllocMap amTxDescRing;
+ SAllocMap *aamTxDescBuf;
+ int idxTxCurDesc;
+ int idxTxdirtyDesc;
+ int idxTxPktStartDesc; // if multi-TD, this is the starting TD
+ UINT cbTxAbortRetry;
+
+ DWORD dwCacheLineSize;
+
+ // for IRQ
+ BYTE byIrqLevel; // IRQ number
+ PVOID pvAdapterIsr; // adapter's ISR
+
+ INT iRxPktHandled; // rx packets has been handled
+ INT iTxPktPosted; // tx packets posted and wait to be sent
+
+ // for statistic
+ SStatCounter scStatistic;
+
+ // for default setting
+ BOOL bTxOn;
+ BOOL bTxContinuous; // for origional performance test (Tx Continuous - performance test)
+ BOOL bTxContFunTest; // for functional test (Tx Continuous - functional test)
+ BOOL bTxSinglePacket;
+ BOOL bRandomPktLength;
+ BOOL bRandomPktData;
+ LONG lTxPacketNum;
+ LONG lTxPacketNumShadow;
+
+ // DEBUG....
+ BOOL bWhenRxCrcErrNoBuf;
+ BOOL bWhenRxDataErrNoBuf;
+ BOOL bIncPktLength;
+ UINT cbPktSize;
+
+ PBYTE pbyTmpBuff;
+
+ // for 3065, multiple descriptors in one packet
+ UINT uTxDescNumPerPacket;
+ UINT uTxPktSize;
+
+ // for 3065, Early Receive handling
+ BOOL bERNow;
+
+ BOOL bPktFw;
+ PVOID pvFwAdapter;
+
+} SAdapterInfo, *PSAdapterInfo;
+
+
+typedef struct _adapter_option {
+ int iTdRingNum;
+ int iRDescNum;
+ int iTDescNum;
+ UINT uiBuffsize;
+ BYTE byRevId;
+ BOOL bNoInit;
+ ULONG ulInitCmds;
+} SAdapterOpts, *PSAdapterOpts;
+
+#define INIT_CMD_NONE 0
+#define INIT_CMD_CLEAR_STICKHW 0x00000001UL
+
+#define W_MAX_TIMEOUT 0x0FFFU //
+
+/*--------------------- Export Classes ----------------------------*/
+
+/*--------------------- Export Variables --------------------------*/
+extern PSAdapterInfo sg_aAdapter;
+extern SAdapterOpts g_sOptions;
+
+/*--------------------- Export Functions --------------------------*/
+#ifdef __cplusplus
+extern "C" { /* Assume C declarations for C++ */
+#endif /* __cplusplus */
+
+BOOL
+ADPbBind(
+ PSAdapterInfo pAdapter
+ );
+
+BOOL
+ADPbInitializeEx(
+ PSAdapterInfo pAdapter
+ );
+
+BOOL
+ADPbShutdown(
+ PSAdapterInfo pAdapter
+ );
+
+UINT
+ADPuInitAll(
+ void
+ );
+
+VOID
+CARDvSetLoopbackMode(
+ DWORD dwIoBase,
+ BYTE byRevId,
+ WORD wLoopbackMode
+ );
+
+VOID
+CARDvSetMediaLinkMode(
+ DWORD dwIoBase,
+ BYTE byRevId,
+ UINT uConnectionType
+ );
+
+#ifdef __cplusplus
+} /* End of extern "C" { */
+#endif /* __cplusplus */
+
+#endif // __ADAPTER_H__
+
diff --git a/cpu/arm920t/wmt/alloct.c b/cpu/arm920t/wmt/alloct.c
new file mode 100755
index 0000000..da75657
--- /dev/null
+++ b/cpu/arm920t/wmt/alloct.c
@@ -0,0 +1,289 @@
+/*++
+Copyright (c) 2010 WonderMedia Technologies, Inc.
+
+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, see http://www.gnu.org/licenses/>.
+
+WonderMedia Technologies, Inc.
+10F, 529, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C.
+--*/
+
+
+#if !defined(__MEM_H__)
+#include "mem.h"
+#endif
+#if !defined(__CARD_H__)
+#include "card.h"
+#endif
+#if !defined(__ALLOCT_H__)
+#include "alloct.h"
+#endif
+#include "macif.h"
+#if !defined(__DBG_H__)
+#include "dbg.h"
+#endif
+
+/*--------------------- Static Definitions -------------------------*/
+
+/*--------------------- Static Classes ----------------------------*/
+
+/*--------------------- Static Variables --------------------------*/
+
+/*--------------------- Static Functions --------------------------*/
+
+/*--------------------- Export Variables --------------------------*/
+
+/*--------------------- Export Functions --------------------------*/
+
+BOOL
+ALCbAllocateRdrMemory(
+ PSAdapterInfo pAdapter
+ )
+{
+ int jj;
+
+ /* Allocate the Receive Descriptor ring */
+ /* (Physically contiguous and non cached) */
+ pAdapter->amRxDescRing.dwRawSize = sizeof(SRxDesc) * pAdapter->cbRD + pAdapter->dwCacheLineSize;
+ pAdapter->amRxDescRing.dwSize = sizeof(SRxDesc) * pAdapter->cbRD;
+ /* allocate raw RD : add cacheline */
+ MEMvAllocateShared(&pAdapter->amRxDescRing);
+ MacDump(MACDBG_INFO, ("[ALCbAllocateRdrMemory] - pAdapter->amRxDescRing.dwRawVAddr : %p, size : %d\n",
+ (PVOID)pAdapter->amRxDescRing.dwRawVAddr, pAdapter->amRxDescRing.dwRawSize));
+
+ if (pAdapter->amRxDescRing.dwRawVAddr == 0)
+ return FALSE;
+
+ /* descriptor MUST aligned by 4 dword */
+ MEMvAlign(&pAdapter->amRxDescRing, (UINT)pAdapter->dwCacheLineSize);
+
+ for (jj = 0; jj < pAdapter->cbRD; jj++) {
+ pAdapter->aamRxDescBuf[jj].dwRawSize = g_sOptions.uiBuffsize + pAdapter->dwCacheLineSize;
+ pAdapter->aamRxDescBuf[jj].dwSize = g_sOptions.uiBuffsize;
+ /* allocate Rx Buffer raw:add cacheline */
+ MEMvAllocateShared(&pAdapter->aamRxDescBuf[jj]);
+ if (pAdapter->aamRxDescBuf[jj].dwRawVAddr == 0) {
+ printf("allocate RX Buffer failed\n ");
+ return FALSE;
+ }
+ MEMvAlign(&pAdapter->aamRxDescBuf[jj], (UINT)pAdapter->dwCacheLineSize);
+ }
+
+ return TRUE;
+}
+
+
+BOOL
+ALCbAllocateTdrMemory(
+ PSAdapterInfo pAdapter
+ )
+{
+ /* Allocate the transmit descriptor ring */
+ /* (Physically contiguous and non cached) */
+ pAdapter->amTxDescRing.dwRawSize = sizeof(STxDesc) * pAdapter->cbTD + pAdapter->dwCacheLineSize;
+ pAdapter->amTxDescRing.dwSize = sizeof(STxDesc) * pAdapter->cbTD;
+ MEMvAllocateShared(&pAdapter->amTxDescRing);
+ MacDump(MACDBG_INFO, ("[ALCbAllocateTdrMemory] - pAdapter->amTxDescRing.dwRawVAddr : %p, size : %d\n",
+ (PVOID)pAdapter->amTxDescRing.dwRawVAddr, pAdapter->amTxDescRing.dwRawSize));
+
+ if (pAdapter->amTxDescRing.dwRawVAddr == 0)
+ return FALSE;
+
+ /* Descriptor MUST aligned by 4 dword */
+ MEMvAlign(&pAdapter->amTxDescRing, (UINT)pAdapter->dwCacheLineSize);
+
+ if (!ALCbAllocateTdrBuffer(pAdapter, pAdapter->aamTxDescBuf, pAdapter->cbTD)) {
+ printf("allocte TX buffer failed\n");
+ return FALSE;
+ }
+ return TRUE;
+}
+
+BOOL
+ALCbAllocateTdrBuffer(
+ PSAdapterInfo pAdapter,
+ SAllocMap asMaps[],
+ UINT cbTD
+ )
+{
+ int ii;
+
+
+ for (ii = 0; ii < cbTD; ii++) {
+ asMaps[ii].dwRawSize = g_sOptions.uiBuffsize + pAdapter->dwCacheLineSize;
+ asMaps[ii].dwSize = g_sOptions.uiBuffsize;
+
+ MEMvAllocateShared(&asMaps[ii]);
+
+ if (asMaps[ii].dwRawVAddr == 0)
+ return FALSE;
+
+ /* If allocated Tx buffers are double-word alignment, make it byte-alignment */
+ if (asMaps[ii].dwRawVAddr % sizeof(DWORD) == 0) {
+ asMaps[ii].dwVAddr = asMaps[ii].dwRawVAddr + (ii % 4);
+ asMaps[ii].dwPAddr = LODWORD(asMaps[ii].qwRawPAddr) + (ii % 4);
+ } else {
+ asMaps[ii].dwVAddr = asMaps[ii].dwRawVAddr;
+ asMaps[ii].dwPAddr = LODWORD(asMaps[ii].qwRawPAddr);
+ }
+ }
+
+ return TRUE;
+}
+
+VOID
+ALCvChainRdrMemory(
+ PSAdapterInfo pAdapter
+ )
+{
+ int ii;
+ PSRxDesc pRD;
+
+ /* Initialize the receive descriptor poniter array and */
+ /* each individual receive descriptor */
+ pRD = (PSRxDesc)pAdapter->amRxDescRing.dwVAddr;
+
+ for (ii = 0; ii < pAdapter->cbRD; ii++) {
+ pAdapter->apRD[ii] = pRD;
+
+ /* Init descriptor value */
+ pRD->m_rd0RD0.f15FrameLen = 0;
+ pRD->m_rd0RD0.f1Owner = B_OWNED_BY_CHIP;
+ pRD->m_rd1RD1.f15RxBufLen = CB_MAX_BUF_SIZE;
+
+ /* Set default RD buffer size to 512 bytes if 3065 (for multi-Rx descs per packet) */
+ pRD->m_rd1RD1.f15RxBufLen = CB_BUF_SIZE_65;
+
+ pRD->m_dwRxBufferAddr = pAdapter->aamRxDescBuf[ii].dwPAddr;
+ if (ii == (pAdapter->cbRD - 1))
+ pRD->m_dwRxNextDescAddr = pAdapter->amRxDescRing.dwPAddr;
+ else
+ pRD->m_dwRxNextDescAddr = pAdapter->amRxDescRing.dwPAddr + sizeof(SRxDesc) * (ii + 1);
+
+ pRD = (PSRxDesc)(pAdapter->amRxDescRing.dwVAddr + sizeof(SRxDesc) * (ii + 1));
+ }
+}
+
+VOID
+ALCvChainTdrMemory(
+ PSAdapterInfo pAdapter
+ )
+{
+ int ii;
+ PSTxDesc pTD;
+
+ /* Initialize the tx desc ring */
+ /* Initialize the Transmit Descriptor pointer array */
+ pTD = (PSTxDesc)pAdapter->amTxDescRing.dwVAddr;
+
+ for (ii = 0; ii < pAdapter->cbTD; ii++) {
+ pAdapter->apTD[ii] = pTD;
+ /* Init descriptor value */
+ pTD->m_td0TD0.f1Owner = B_OWNED_BY_HOST;
+ /* modified by kevin:length =0 */
+ pTD->m_td1TD1.f15TxBufLen = 0;
+ pTD->m_td1TD1.f1Chain = 1;
+ pTD->m_td1TD1.byTCR = TCR_IC | TCR_EDP | TCR_STP;
+
+ pTD->m_dwTxBufferAddr = pAdapter->aamTxDescBuf[ii].dwPAddr;
+ if (ii == (pAdapter->cbTD - 1))
+ pTD->m_dwTxNextDescAddr = pAdapter->amTxDescRing.dwPAddr;
+ else
+ pTD->m_dwTxNextDescAddr = pAdapter->amTxDescRing.dwPAddr + sizeof(STxDesc) * (ii + 1);
+
+ pTD = (PSTxDesc)(pAdapter->amTxDescRing.dwVAddr + sizeof(STxDesc) * (ii + 1));
+ }
+
+ /* Init adapter's sturcture also, init value = MAX_PACKET_LEN */
+ pAdapter->uTxPktSize = MAX_PACKET_LEN;
+
+}
+
+VOID
+ALCvFreeRdrMemory(
+ PSAdapterInfo pAdapter
+ )
+{
+ int ii;
+
+ /* Free the receive descriptor ring. */
+ if (pAdapter->amRxDescRing.dwRawVAddr != 0)
+ pAdapter->amRxDescRing.dwRawVAddr = 0;
+
+ /* Free the Receive buffers */
+ for (ii = 0; ii < pAdapter->cbRD; ii++) {
+ if (pAdapter->aamRxDescBuf[ii].dwRawVAddr != 0)
+ pAdapter->aamRxDescBuf[ii].dwRawVAddr = 0;
+ }
+}
+
+VOID
+ALCvFreeTdrMemory(
+ PSAdapterInfo pAdapter
+ )
+{
+ int ii;
+
+ /* Free the transmit descriptor ring */
+ if (pAdapter->amTxDescRing.dwRawVAddr != 0)
+ pAdapter->amTxDescRing.dwRawVAddr = 0;
+
+ /* Free the Transmit Buffers */
+ for (ii = 0; ii < pAdapter->cbTD; ii++) {
+ if (pAdapter->aamTxDescBuf[ii].dwRawVAddr != 0)
+ pAdapter->aamTxDescBuf[ii].dwRawVAddr = 0;
+ }
+}
+
+VOID
+ALCvSetDefaultRD(
+ PSAdapterInfo pAdapter
+ )
+{
+ /* set init RD value */
+ ALCvChainRdrMemory(pAdapter);
+}
+
+VOID
+ALCvSetDefaultTD(
+ PSAdapterInfo pAdapter
+ )
+{
+ int ii;
+ int jj;
+ PBYTE pbyBuf;
+
+ DWORD adwPattern[4] = {
+ 0xFFFFFFFFL, 0x00000000L,
+ 0xAAAAAAAAL, 0x55555555L
+ };
+
+ /* Set init TD value */
+ ALCvChainTdrMemory(pAdapter);
+
+ /* Set tx descriptors owner to host(0) */
+ /* Set IC = 1, EDP = 1, STP = 1 */
+ for (ii = pAdapter->cbTD - 1; ii >= 0; ii--) {
+ pbyBuf = (PBYTE)pAdapter->aamTxDescBuf[ii].dwVAddr;
+
+ /* Packet length maybe multiples of 16 */
+ jj = 0;
+ while (jj < pAdapter->apTD[ii]->m_td1TD1.f15TxBufLen) {
+ if (jj < pAdapter->apTD[ii]->m_td1TD1.f15TxBufLen - 8) {
+ *(PDWORD)(pbyBuf + jj) = adwPattern[ii % 4];
+ *(PDWORD)(pbyBuf + jj + 4) = adwPattern[ii % 4];
+ jj += 8;
+ } else {
+ *(PBYTE)(pbyBuf + jj) = (BYTE)adwPattern[ii % 4];
+ jj++;
+ }
+ }
+ }
+}
diff --git a/cpu/arm920t/wmt/alloct.h b/cpu/arm920t/wmt/alloct.h
new file mode 100755
index 0000000..ecf9ee5
--- /dev/null
+++ b/cpu/arm920t/wmt/alloct.h
@@ -0,0 +1,94 @@
+/*++
+Copyright (c) 2010 WonderMedia Technologies, Inc.
+
+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, see http://www.gnu.org/licenses/>.
+
+WonderMedia Technologies, Inc.
+10F, 529, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C.
+--*/
+
+
+#ifndef __ALLOCT_H__
+#define __ALLOCT_H__
+
+#if !defined(__ADAPTER_H__)
+#include "adapter.h"
+#include "mem.h"
+#endif
+
+
+/*--------------------- Export Definitions -------------------------*/
+
+/*--------------------- Export Types ------------------------------*/
+
+/*--------------------- Export Macros ------------------------------*/
+
+/*--------------------- Export Classes ----------------------------*/
+
+/*--------------------- Export Variables --------------------------*/
+
+/*--------------------- Export Functions --------------------------*/
+#ifdef __cplusplus
+extern "C" { /* Assume C declarations for C++ */
+#endif /* __cplusplus */
+
+BOOL
+ALCbAllocateRdrMemory(
+ PSAdapterInfo pAdapter
+ );
+
+BOOL
+ALCbAllocateTdrMemory(
+ PSAdapterInfo pAdapter
+ );
+
+BOOL
+ALCbAllocateTdrBuffer(
+ PSAdapterInfo pAdapter,
+ SAllocMap asMaps[],
+ UINT cbTD
+ );
+
+VOID
+ALCvChainRdrMemory(
+ PSAdapterInfo pAdapter
+ );
+
+VOID
+ALCvChainTdrMemory(
+ PSAdapterInfo pAdapter
+ );
+
+VOID
+ALCvFreeRdrMemory(
+ PSAdapterInfo pAdapter
+ );
+
+VOID
+ALCvFreeTdrMemory(
+ PSAdapterInfo pAdapter
+ );
+
+VOID
+ALCvSetDefaultRD(
+ PSAdapterInfo pAdapter
+ );
+
+VOID
+ALCvSetDefaultTD(
+ PSAdapterInfo pAdapter
+ );
+
+#ifdef __cplusplus
+} /* End of extern "C" { */
+#endif /* __cplusplus */
+
+#endif // __ALLOCT_H__
diff --git a/cpu/arm920t/wmt/api-loader.c b/cpu/arm920t/wmt/api-loader.c
new file mode 100755
index 0000000..8cda718
--- /dev/null
+++ b/cpu/arm920t/wmt/api-loader.c
@@ -0,0 +1,66 @@
+/*
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * Copyright (c) 2010 WonderMedia Technologies, Inc.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ *
+ * WonderMedia Technologies, Inc.
+ * 10F, 529, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C.
+ */
+
+/*
+ * api-loader.c - this is entry support for the WMT evaluation board to go to loader
+ */
+
+//#include <common.h>
+#include <api_loader.h>
+
+#define LOADER_ADDR 0xffff0000
+#define HIBERNATION_ENTER_EXIT_CODE_BASE_ADDR 0xFFFFFFC0
+#define DO_DVO_PLL_SET (HIBERNATION_ENTER_EXIT_CODE_BASE_ADDR + 0x38)
+//#define wmt_debug
+#ifdef wmt_debug
+#define WMprintf(fmt, args...) printk("[%s]: " fmt, __FUNCTION__ , ## args)
+#else
+#define WMprintf(fmt, args...)
+#endif
+
+int dvo_pll_set (unsigned int multi, unsigned char divisor, unsigned short resx, unsigned short resy)
+{
+ volatile unsigned int base = 0;
+ unsigned int exec_at = (unsigned int)-1;
+ int (*theKernel_dvo)(int from, unsigned int multi, unsigned char divisor, unsigned short resx, unsigned short resy);
+ int retval = 0;
+
+ WMprintf("entry 0x%8.8X 0x%8.8X %d %d\n",multi, divisor, resx, resy);
+ /*enble SF clock*/
+ /*REG32_VAL(PMCEU_ADDR) |= 0x00800000;*/
+
+ /*jump to loader api to do something*/
+/* base = (unsigned int)ioremap_nocache(LOADER_ADDR, 0x10000);*/
+ base = (unsigned int)LOADER_ADDR;
+ exec_at = base + (DO_DVO_PLL_SET - LOADER_ADDR);
+ theKernel_dvo = (int (*)(int from, unsigned int multi, unsigned char divisor, unsigned short resx, unsigned short resy))exec_at;
+
+ retval = theKernel_dvo(1, multi, divisor, resx, resy);
+
+/* iounmap((void *)base);*/
+
+ /*disable SF clock*/
+/* REG32_VAL(PMCEU_ADDR) &= ~0x00800000;*/
+
+ WMprintf("exit!!(%d)\n",retval);
+
+ return retval;
+}
+
diff --git a/cpu/arm920t/wmt/card.h b/cpu/arm920t/wmt/card.h
new file mode 100755
index 0000000..cd49991
--- /dev/null
+++ b/cpu/arm920t/wmt/card.h
@@ -0,0 +1,73 @@
+/*++
+Copyright (c) 2010 WonderMedia Technologies, Inc.
+
+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, see http://www.gnu.org/licenses/>.
+
+WonderMedia Technologies, Inc.
+10F, 529, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C.
+--*/
+
+
+#ifndef __CARD_H__
+#define __CARD_H__
+
+#if !defined(__TTYPE_H__)
+#include "ttype.h"
+#endif
+#if !defined(__MAC_H__)
+#include "mac.h"
+#endif
+#if !defined(__MII_H__)
+#include "mii.h"
+#endif
+
+
+/*--------------------- Export Definitions -------------------------*/
+
+// media type
+#define MEDIA_AUTO 0x00 //
+#define MEDIA_100M_HALF 0x01 //
+#define MEDIA_100M_FULL 0x02 //
+#define MEDIA_10M_HALF 0x03 //
+#define MEDIA_10M_FULL 0x04 //
+#define MEDIA_1M 0x05 // Home PHY
+
+
+
+/*
+ * Loopback mode
+ */
+/* LOBYTE is MAC LB mode, HIBYTE is MII LB mode */
+#define CARD_LB_NONE MAKEWORD(MAC_LB_NONE, MII_LB_NONE)
+/* PHY must ISO, avoid MAC loopback packet go out */
+#define CARD_LB_MAC MAKEWORD(MAC_LB_INTERNAL, MII_LB_ISO) // PHY must ISO, avoid MAC loopback packet go out
+#define CARD_LB_MII MAKEWORD(MAC_LB_PHY, MII_LB_INTERNAL)
+
+/*--------------------- Export Classes ----------------------------*/
+
+/*--------------------- Export Variables --------------------------*/
+
+/*--------------------- Export Functions --------------------------*/
+#ifdef __cplusplus
+extern "C" { /* Assume C declarations for C++ */
+#endif /* __cplusplus */
+
+
+
+
+#ifdef __cplusplus
+} /* End of extern "C" { */
+#endif /* __cplusplus */
+
+#endif /* __CARD_H__ */
+
+
+
diff --git a/cpu/arm920t/wmt/cypher.c b/cpu/arm920t/wmt/cypher.c
new file mode 100755
index 0000000..41de88d
--- /dev/null
+++ b/cpu/arm920t/wmt/cypher.c
@@ -0,0 +1,415 @@
+/*++
+Copyright (c) 2010 WonderMedia Technologies, Inc.
+
+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, see http://www.gnu.org/licenses/>.
+
+WonderMedia Technologies, Inc.
+10F, 529, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C.
+--*/
+/*--
+Revision History:
+-------------------------------------------------------------------------------
+
+--*/
+
+#include <malloc.h>
+
+#include "cypher.h"
+
+#ifdef DPRINTK
+ #undef DPRINTK
+#endif
+
+//#define DEBUG_CYPHER
+#ifdef DEBUG_CYPHER
+
+ #define DPRINTK printf
+
+ #define DPRINT_FUNC_IN() DPRINTK("--- Enter %s() ---\n", __FUNCTION__)
+ #define DPRINT_FUNC_OUT() DPRINTK("=== Exit %s() ===\n", __FUNCTION__)
+#else
+ #define DPRINTK(a,...)
+ #define DPRINT_FUNC_IN()
+ #define DPRINT_FUNC_OUT()
+#endif
+
+
+
+/*****************************************************************/
+u32 OUTPUT_buf[BUFFER_MAX];
+u32 in_table_buf[40960], out_table_buf[10];
+u32 KEY_buf[8], IV_buf[4], INC_buf;
+u8 cipher_int_flag = 0;
+
+/*****************************************************************/
+#define AHB_NOP(str) // DPRINTK("wait %d nop...\n", str)
+#ifndef AHB_NOP
+void AHB_NOP(int count)
+{
+ while(count) {
+ asm("nop");
+ count--;
+ }
+}
+#endif
+
+/****************************************************************/
+void cypher_isr(void)
+{
+ REG_SET32(CYPHER_DMA_INT_STATUS_REG, 0x00000001); //clear interrupt bit
+ cipher_int_flag = 1;
+ DPRINTK("cipher interrupt mode done! \n");
+}
+
+/*****************************************************************/
+void cypher_enable(
+ IN cypher_algo_t algo_mode)
+{
+ DPRINT_FUNC_IN();
+
+#ifdef CYPHER_INT_ENABLE
+ // enable cipher DMA Interrupt
+ REG_SET32(CYPHER_DMA_INT_ENABLE_REG, CYPHER_DMA_INT_ENABLE);
+#endif
+
+ // enable cipher Clock
+ switch(algo_mode) {
+ case CYPHER_ALGO_SHA256:
+ REG_SET32(CYPHER_CLK_ENABLE_REG, CYPHER_SHA256_CLK_ENABLE);
+ break;
+ default:
+ break;
+ }
+
+ // doing software reset to makesure ervrything is going well
+ REG_SET32(CYPHER_SW_RESET_REG, 0x01);
+ REG_SET32(CYPHER_SW_RESET_REG, 0x00);
+
+ DPRINT_FUNC_OUT();
+}
+
+/*****************************************************************/
+void cypher_disable(void)
+{
+ DPRINT_FUNC_IN();
+
+#ifdef CYPHER_INT_ENABLE
+ // disable cipher DMA Interrupt
+ REG_SET32(CYPHER_DMA_INT_ENABLE_REG, CYPHER_DMA_INT_DISABLE);
+#endif
+
+ // disable cipher Clock
+ REG_SET32(CYPHER_CLK_ENABLE_REG, CYPHER_CLK_DISABLE);
+
+ DPRINT_FUNC_OUT();
+}
+
+/*****************************************************************/
+void cypher_mode_set(
+ IN cypher_base_cfg_t *cypher_base_cfg)
+{
+ u32 sha256_variable = 0x00;
+
+ DPRINT_FUNC_IN();
+
+ if(cypher_base_cfg->algo_mode == CYPHER_ALGO_SHA256) {
+ REG_SET32(CYPHER_MODE_REG, CYPHER_SHA256_MODE); //Set cipher mode to SHA256
+
+ /* set data length to bit25-16, write 1 to bit1 to swap buffer, write 1 to bit0 to enable SHA256 */
+ sha256_variable = cypher_base_cfg->sha256_data_length;
+ REG_SET32(CYPHER_SHA256_DATA_LEN_REG, sha256_variable);
+
+ REG_SET32(CYPHER_SHA256_START_REG, (0x01 | 0x02 << 2));
+ }
+
+
+ DPRINT_FUNC_OUT();
+}
+
+
+
+/*****************************************************************/
+void cypher_prd_table(
+ IN int prd_tbl_addr,
+ IN int phy_base_addr,
+ IN int byte_count)
+{
+ int edt_byte_cnt, edt_bit;
+ int j, prd_bytecount;
+
+ DPRINT_FUNC_IN();
+
+ for (j = 0, edt_bit = 0; byte_count > 0; j++) {
+ if (byte_count > PRD_BYTE_COUNT_MAX) {
+ prd_bytecount = PRD_BYTE_COUNT_MAX;
+ byte_count -= PRD_BYTE_COUNT_MAX ;
+ }
+ else {
+ prd_bytecount = byte_count;
+ edt_bit = 1;
+ byte_count = 0;
+ }
+
+ edt_byte_cnt = (edt_bit << 31) + prd_bytecount;
+
+ REG_SET32((prd_tbl_addr + (j * PRD_TABLE_BOUNDARY)), (phy_base_addr + (j * PRD_BYTE_COUNT_MAX))); // Set memory read base address
+ REG_SET32((prd_tbl_addr + (j * PRD_TABLE_BOUNDARY) + 4), edt_byte_cnt); // Set EDT, Byte count
+ }
+
+#if 0
+DPRINTK("addr = %x \n", REG_GET32(prd_tbl_addr));
+DPRINTK("addr+4 = %x \n", REG_GET32(prd_tbl_addr+4));
+#endif
+
+ DPRINT_FUNC_OUT();
+}
+
+/*****************************************************************/
+void cypher_dma_start(void)
+{
+#ifndef CYPHER_INT_ENABLE
+ int r_value;
+#endif
+
+ DPRINT_FUNC_IN();
+
+ cipher_int_flag = 0;
+ REG_SET32(CYPHER_DMA_START_REG, 0x01); /*Set the DMA start*/
+
+ while(1) {
+#ifndef CYPHER_INT_ENABLE
+ r_value = REG_GET32(CYPHER_DMA_INT_STATUS_REG);
+
+ if( (r_value & 0x01) == 1 ) {
+ REG_SET32(CYPHER_DMA_INT_STATUS_REG, 0x00000001); //clear interrupt bit
+ cipher_int_flag = 1;
+ DPRINTK("cipher polling mode done! \n");
+ }
+#endif
+
+ if (cipher_int_flag)
+ break;
+ }
+
+ DPRINT_FUNC_OUT();
+}
+
+/****************************************************************/
+unsigned long cypher_transform(IN unsigned long temp)
+{
+ int i;
+ u32 buf;
+ buf = 0;
+
+ for (i = 0; i < 4; i++) {
+ buf += ((temp << 8 * (3 - i)) & 0xff000000) >> (8 * i);
+ }
+
+ return (buf);
+}
+
+
+/*****************************************************************/
+void Get_Output_Buf( OUT u32 dest_addr, u32 dest_size, u32 dec_enc )
+{
+ int patterns;
+ int total_u32;
+
+ DPRINT_FUNC_IN();
+
+ if (dest_size % DMA_BOUNDARY)
+ patterns = (dest_size / DMA_BOUNDARY) + 1;
+ else
+ patterns = (dest_size / DMA_BOUNDARY);
+
+ memset((void*)dest_addr, CYPHER_ZERO, dest_size * sizeof(u8));
+
+ total_u32 = patterns * (DMA_BOUNDARY / sizeof(u32));
+ memcpy((void*)dest_addr, OUTPUT_buf, total_u32 * sizeof(u32));
+
+#if 0
+#ifdef DEBUG
+{
+ int idx;
+
+ if (dec_enc == CYPHER_ENCRYPT) {
+ DPRINTK("ciphertext: ");
+ }
+ else {
+ DPRINTK("plaintext: ");
+ }
+
+ for (idx = 0; idx < total_u32; idx++) {
+ DPRINTK("%08x ", (uint)cypher_transform(OUTPUT_buf[idx]));
+ }
+ DPRINTK(" [%d]\n", total_u32);
+}
+#endif
+#endif
+
+ DPRINT_FUNC_OUT();
+}
+
+/*****************************************************************/
+void Count_Patterns(
+ IN int patterns,
+ OUT int *in_bytecount,
+ OUT int *out_bytecount,
+ OUT int *total_patterns )
+{
+ DPRINT_FUNC_IN();
+
+#if 1
+ *in_bytecount = patterns * DMA_BOUNDARY;
+ *out_bytecount = patterns * DMA_BOUNDARY;
+ *total_patterns = patterns * (DMA_BOUNDARY / sizeof(u32));
+#else
+ if(algo_mode == CYPHER_ALGO_DES || algo_mode == CYPHER_ALGO_TDES)
+ patterns = cypher_base->patterns * 2;
+
+ if(algo_mode == CYPHER_ALGO_AES || algo_mode == CYPHER_ALGO_RC4)
+ {
+ in_bytecount = patterns*128/8; //read data byte count
+ out_bytecount = patterns*128/8; //write data byte count
+ }
+ else if(algo_mode == CYPHER_ALGO_DES || algo_mode == CYPHER_ALGO_TDES)
+ {
+ in_bytecount = patterns*64/8; //read data byte count
+ out_bytecount = patterns*64/8; //write data byte count
+ }
+
+ //Compute total words of data
+ if(algo_mode == CYPHER_ALGO_AES || algo_mode == CYPHER_ALGO_RC4)
+ total_patterns = 4 * patterns;
+ else if(algo_mode == CYPHER_ALGO_DES || algo_mode == CYPHER_ALGO_TDES)
+ total_patterns = 2 * patterns;
+#endif
+
+ DPRINTK("in_bytecount: %d \n", *in_bytecount);
+ DPRINTK("out_bytecount: %d \n", *out_bytecount);
+ DPRINTK("total_patterns: %d \n", *total_patterns);
+
+ DPRINT_FUNC_OUT();
+}
+
+/*****************************************************************/
+int Cypher_Action( IN OUT cypher_base_cfg_t *cypher_base )
+{
+ int i;
+ int in_bytecount;
+ int out_bytecount;
+ int total_patterns;
+ int patterns;
+
+ DPRINT_FUNC_IN();
+
+ //memset(in_table_buf, CYPHER_ZERO, 1000 * sizeof(u32));
+ //memset(out_table_buf, CYPHER_ZERO, 1000 * sizeof(u32));
+
+ if (cypher_base->text_length % DMA_BOUNDARY)
+ patterns = (cypher_base->text_length / DMA_BOUNDARY) + 1;
+ else
+ patterns = (cypher_base->text_length / DMA_BOUNDARY);
+
+ if (cypher_base->algo_mode > CYPHER_ALGO_BASE_END)
+ return 1;
+
+
+ //Compute total words of data
+ Count_Patterns(patterns, &in_bytecount, &out_bytecount, &total_patterns);
+
+
+ /* actuality output bytes of SHA256 encrypt always = 32 Bytes */
+ if (cypher_base->algo_mode == CYPHER_ALGO_SHA256) {
+ out_bytecount = 32;
+ }
+
+ DPRINTK("*******************************************\n");
+
+
+ cypher_enable(cypher_base->algo_mode);
+ cypher_mode_set(cypher_base);
+
+
+ /****************************
+ Write PRD CIPHER_IN Control register
+ ****************************/
+ cypher_prd_table((int)in_table_buf, cypher_base->input_addr, in_bytecount);
+ //cypher_prd_table((int)in_table_buf, (int)INPUT_buf, in_bytecount);
+ REG_SET32(CYPHER_DMA_SOUR_ADDR_REG, (int)in_table_buf); // Set PRD read point
+
+ /****************************
+ Write PRD CIPHER_OUT Control register
+ ****************************/
+ cypher_prd_table((int)out_table_buf, (int)OUTPUT_buf, out_bytecount);
+ REG_SET32(CYPHER_DMA_DEST_ADDR_REG, (int)out_table_buf); // Set PRD write point
+
+ DPRINTK("in_table_buf=0x%08x \n", (uint)in_table_buf);
+ //DPRINTK("INPUT_buf=0x%08x \n", (uint)INPUT_buf);
+ DPRINTK("out_table_buf=0x%08x \n", (uint)out_table_buf);
+ DPRINTK("OUTPUT_buf=0x%08x \n", (uint)OUTPUT_buf);
+
+ /*if (total_patterns <= 32) {
+ DPRINTK("INPUT_buf: \n");
+ for(i = 0; i < total_patterns; i++)
+ DPRINTK("%08x ", (uint)INPUT_buf[i]);
+ DPRINTK(" [%d]\n", total_patterns);
+ }*/
+
+
+ //START CIPHER DMA
+ cypher_dma_start();
+
+
+ /*Now, text_length should be output bytes of SHA256 encrypt always = 32 Bytes */
+ if (cypher_base->algo_mode == CYPHER_ALGO_SHA256) {
+ cypher_base->text_length = 32;
+ }
+
+ if (total_patterns <= 32) {
+ DPRINTK("OUTPUT_buf: \n");
+ for(i = 0; i < total_patterns; i++)
+ DPRINTK("%08x ", (uint)OUTPUT_buf[i]);
+ DPRINTK(" [%d]\n", total_patterns);
+ }
+
+ DPRINT_FUNC_OUT();
+
+ cypher_disable();
+ return 0;
+}
+
+
+/*****************************************************************/
+void Clear_All_Buf(void)
+{
+ //memset(INPUT_buf, CYPHER_ZERO, BUFFER_MAX * sizeof(u32));
+ //memset(OUTPUT_buf, CYPHER_ZERO, BUFFER_MAX * sizeof(u32));
+ memset(KEY_buf, CYPHER_ZERO, 6 * sizeof(u32));
+ memset(IV_buf, CYPHER_ZERO, 4 * sizeof(u32));
+ INC_buf = CYPHER_ZERO;
+}
+
+/*****************************************************************/
+void Show_Register(int start, int end)
+{
+ int idx;
+ u32 value;
+
+ DPRINTK("Register [ 0x%x ~ 0x%x ]\n", start, end);
+ for (idx = start; idx <= end; idx += 4) {
+ value = REG_GET32(CYPHER_REG_BASE + idx);
+ DPRINTK("[0x%02x] %08x \n", idx, (uint)value);
+ }
+
+}
+
diff --git a/cpu/arm920t/wmt/cypher.h b/cpu/arm920t/wmt/cypher.h
new file mode 100755
index 0000000..e7ce6a5
--- /dev/null
+++ b/cpu/arm920t/wmt/cypher.h
@@ -0,0 +1,159 @@
+/*++
+Copyright (c) 2010 WonderMedia Technologies, Inc.
+
+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, see http://www.gnu.org/licenses/>.
+
+WonderMedia Technologies, Inc.
+10F, 529, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C.
+--*/
+/*--
+Revision History:
+-------------------------------------------------------------------------------
+
+--*/
+
+#ifndef __CYPHER_H__
+#define __CYPHER_H__
+
+//#include "../../../board/wmt/include/global.h"
+#include "../../../common/wmt_display/hw/wmt_mmap.h"
+
+#define IN
+#define OUT
+#define IO
+
+/* Basic Define*/
+#define REG32 *(volatile unsigned int *)
+#define REG16 *(volatile unsigned short *)
+#define REG8 *(volatile unsigned char *)
+#define REG_GET32(addr) ( REG32(addr) ) /* Read 32 bits Register */
+#define REG_GET16(addr) ( REG16(addr) ) /* Read 16 bits Register */
+#define REG_GET8(addr) ( REG8(addr) ) /* Read 8 bits Register */
+#define REG_SET32(addr, val) ( REG32(addr) = (val) ) /* Write 32 bits Register */
+#define REG_SET16(addr, val) ( REG16(addr) = (val) ) /* Write 16 bits Register */
+#define REG_SET8(addr, val) ( REG8(addr) = (val) ) /* Write 8 bits Register */
+
+/*
+ * Refer CYPHER Module ver. 0.01
+ *
+ */
+
+#define CYPHER_REG_BASE SECURITY_ENGINE_CFG_BASE_ADDR// 1KB
+
+//the CYPHER status
+#define CYPHER_OK 0
+#define CYPHER_FAIL 1
+
+
+/*
+ * Registers
+ */
+// MISC
+#define CYPHER_SRAM_WR_DATA_REG CYPHER_REG_BASE + 0x0A8
+#define CYPHER_SRAM_WR_ADDR_REG CYPHER_REG_BASE + 0x0AC
+#define CYPHER_SRAM_WR_ENABLE_REG CYPHER_REG_BASE + 0x0B0
+#define CYPHER_MODE_REG CYPHER_REG_BASE + 0x0C0
+#define CYPHER_SW_RESET_REG CYPHER_REG_BASE + 0x0C4
+#define CYPHER_CLK_ENABLE_REG CYPHER_REG_BASE + 0x0C8
+#define CYPHER_DMA_INT_ENABLE_REG CYPHER_REG_BASE + 0x0CC
+
+// DMA
+#define CYPHER_DMA_START_REG CYPHER_REG_BASE + 0x0D0
+#define CYPHER_DMA_INT_STATUS_REG CYPHER_REG_BASE + 0x0D4
+#define CYPHER_DMA_SOUR_ADDR_REG CYPHER_REG_BASE + 0x0E0
+#define CYPHER_DMA_SOUR_RD_ADDR_REG CYPHER_REG_BASE + 0x0E4
+#define CYPHER_DMA_SOUR_RD_DWC_REG CYPHER_REG_BASE + 0x0E8
+#define CYPHER_DMA_DEST_ADDR_REG CYPHER_REG_BASE + 0x0F0
+#define CYPHER_DMA_DEST_RD_ADDR_REG CYPHER_REG_BASE + 0x0F4
+#define CYPHER_DMA_DEST_RD_DWC_REG CYPHER_REG_BASE + 0x0F8
+
+
+// SHA256
+#define CYPHER_SHA256_START_REG CYPHER_REG_BASE + 0x50
+#define CYPHER_SHA256_DATA_LEN_REG CYPHER_REG_BASE + 0x54
+
+
+//---------------------------------------------------------------------------------------
+// CYPHER define
+//---------------------------------------------------------------------------------------
+#define BUFFER_MAX 76802
+
+#define PRD_BYTE_COUNT_MAX 65520 // have to meet 16 Bytes alignment
+#define PRD_TABLE_BOUNDARY 8
+#define PRD_BYTE_COUNT_BOUNDARY 16
+
+#define DMA_BOUNDARY 16 // 16 bytes
+
+#define DATA_MAX 307200
+
+
+#define SHA256_TEXT_BOUNDARY 4
+#define SHA256_OUTPUT_SIZE 32
+
+// Encrypt/Decrypt mode
+#define CYPHER_ENCRYPT 1
+#define CYPHER_DECRYPT 0
+#define CYPHER_ZERO 0x0L
+
+// Cipher mode
+#define CYPHER_SHA256_MODE 4
+#define CYPHER_EXTERNAL_MODE 7
+
+#define CYPHER_SHA256_CLK_ENABLE 0x2003
+
+#define CYPHER_CLK_DISABLE 0
+
+// Cipher DMA Interrupt
+#define CYPHER_DMA_INT_ENABLE 1
+#define CYPHER_DMA_INT_DISABLE 0
+
+//---------------------------------------------------------------------------------------
+// CYPHER Data structure
+//---------------------------------------------------------------------------------------
+typedef enum cypher_algo_e
+{
+ CYPHER_ALGO_SHA256 = 7 // Secure Hash Algorithm 256
+} cypher_algo_t;
+
+#define CYPHER_ALGO_BASE_START CYPHER_ALGO_SHA256
+#define CYPHER_ALGO_BASE_END CYPHER_ALGO_SHA256
+
+// http://www-128.ibm.com/developerworks/tw/library/s-crypt02.html
+
+#define SIZEOF(x) sizeof(x)
+#define NO_OF( x ) ( SIZEOF( (x) ) / SIZEOF( (x)[0] ) )
+
+typedef struct cypher_base_cfg_s
+{
+ cypher_algo_t algo_mode;
+ int op_mode;
+ u32 dec_enc;
+ u32 input_addr;
+ u32 output_addr;
+ u32 text_length;
+ u32 key_addr;
+ u32 IV_addr; // Initial Vector address for CBC, CTR and OFB mode of AES
+ u32 INC; // for CTR mode of AES
+ u32 sha1_data_length; // for SHA1 only
+ u32 sha256_data_length; // for SHA256 only
+ int aes_hwkey;
+} cypher_base_cfg_t;
+
+//---------------------------------------------------------------------------------------
+// Defined in the cypherif.c
+//---------------------------------------------------------------------------------------
+void cypher_initialization(void);
+
+
+#endif // _CYPHER_H_
+
+
diff --git a/cpu/arm920t/wmt/cypherif.c b/cpu/arm920t/wmt/cypherif.c
new file mode 100755
index 0000000..7077c83
--- /dev/null
+++ b/cpu/arm920t/wmt/cypherif.c
@@ -0,0 +1,180 @@
+/*++
+Copyright (c) 2010 WonderMedia Technologies, Inc.
+
+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, see http://www.gnu.org/licenses/>.
+
+WonderMedia Technologies, Inc.
+10F, 529, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C.
+--*/
+/*--
+Revision History:
+-------------------------------------------------------------------------------
+
+--*/
+
+#include "common.h"
+#include <malloc.h>
+
+#include <stdarg.h>
+#include "../../../board/wmt/include/wmt_clk.h"
+#include "cypher.h"
+
+
+
+//#define DEBUG_CYPHER
+#ifdef DEBUG_CYPHER
+
+ #define DPRINTK printf
+
+ #define DPRINT_FUNC_IN() DPRINTK("--- Enter %s() ---\n", __FUNCTION__)
+ #define DPRINT_FUNC_OUT() DPRINTK("=== Exit %s() ===\n", __FUNCTION__)
+#else
+ #define DPRINT_FUNC_IN()
+ #define DPRINT_FUNC_OUT()
+#endif
+
+/****************************************************************/
+extern int auto_pll_divisor(enum dev_id dev, enum clk_cmd cmd, int unit, int freq);
+
+
+
+/* NOTICE: the input data length of SHA256 must be multiple of 4Bytes */
+u8 Input_Plainttext[] = "abc";
+
+u8 Output_Plainttext[3] = {0};
+
+
+
+
+u8 Plaintext[DATA_MAX + 1]; // for output of decrypt
+
+u8 Ciphertext[DATA_MAX + 1]; // for output of encrypt
+
+int text_len;
+
+
+
+/****************************************************************/
+int Cypher_Action( IN OUT cypher_base_cfg_t *cypher_base );
+void Clear_All_Buf(void);
+void Set_Input_Buf( IN unsigned int src_addr, unsigned int src_size, unsigned int dec_enc );
+void Get_Output_Buf( OUT unsigned int dest_addr, unsigned int dest_size, unsigned int dec_enc );
+void Show_Register(int start, int end);
+void cypher_isr(void);
+
+
+
+
+
+/****************************************************************/
+int cipher_enc_dec( IN OUT cypher_base_cfg_t *cipher_obj )
+{
+ DPRINT_FUNC_IN();
+
+ Clear_All_Buf();
+ Cypher_Action(cipher_obj);
+ Get_Output_Buf(cipher_obj->output_addr, cipher_obj->text_length, cipher_obj->dec_enc);
+
+ DPRINT_FUNC_OUT();
+
+ return 0;
+}
+
+
+
+/****************************************************************/
+void cipher_obj_clear( IN cypher_base_cfg_t *cipher_obj )
+{
+ DPRINT_FUNC_IN();
+
+ cipher_obj->algo_mode = CYPHER_ALGO_SHA256;
+ cipher_obj->op_mode = 0;
+ cipher_obj->dec_enc = CYPHER_DECRYPT;
+ cipher_obj->text_length = 0x0;
+ cipher_obj->key_addr = CYPHER_ZERO;
+ cipher_obj->IV_addr = CYPHER_ZERO;
+
+ cipher_obj->input_addr = CYPHER_ZERO; // address
+ cipher_obj->output_addr = CYPHER_ZERO; // address
+ cipher_obj->INC = 0x0;
+ cipher_obj->sha1_data_length = 0x0;
+ cipher_obj->sha256_data_length = 0x0;
+
+ DPRINT_FUNC_OUT();
+}
+
+
+
+
+/****************************************************************/
+int sha256_action( cypher_base_cfg_t *test_object, u32 input_buf, u32 output_buf)
+{
+ int ret = 0;
+
+ test_object->algo_mode = CYPHER_ALGO_SHA256;
+ test_object->op_mode = 0;
+
+ // encrypt
+ test_object->input_addr = (u32)input_buf; // address
+ test_object->output_addr = (u32)Ciphertext; // address
+
+ test_object->dec_enc = CYPHER_ENCRYPT;
+ cipher_enc_dec(test_object);
+
+ memcpy((void*)output_buf, (void*)Ciphertext, 32);
+
+ return ret;
+}
+
+
+
+/****************************************************************/
+void cypher_initialization(void)
+{
+ auto_pll_divisor(DEV_SAE,CLK_ENABLE,0,0);
+#ifdef CYPHER_INT_ENABLE
+ /* Interrupt setting */
+ set_irq_handlers(IRQ_SAE, cypher_isr);
+ set_int_route(IRQ_SAE, 0);
+ unmask_interrupt(IRQ_SAE);
+#endif
+
+}
+
+void cipher_release(void)
+{
+
+ auto_pll_divisor(DEV_SAE,CLK_DISABLE,0,0);
+
+} /* End of cipher_release() */
+
+
+int cypher_encode(unsigned int buf_in, unsigned int in_len, unsigned int buf_out)
+{
+ cypher_base_cfg_t test_object;
+ int ret = 1;
+
+ cipher_obj_clear(&test_object);
+
+ test_object.sha256_data_length = in_len;
+ test_object.text_length = in_len;
+
+ ret = sha256_action(&test_object, (unsigned int)buf_in, (unsigned int)buf_out);
+
+ return ret;
+}
+
+
+
+
+
+
diff --git a/cpu/arm920t/wmt/dbg.h b/cpu/arm920t/wmt/dbg.h
new file mode 100755
index 0000000..d9152b1
--- /dev/null
+++ b/cpu/arm920t/wmt/dbg.h
@@ -0,0 +1,47 @@
+/*++
+Copyright (c) 2010 WonderMedia Technologies, Inc.
+
+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, see http://www.gnu.org/licenses/>.
+
+WonderMedia Technologies, Inc.
+10F, 529, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C.
+--*/
+
+#ifndef __DBG_H__
+#define __DBG_H__
+
+
+/*--------------------- Export Definitions -------------------------*/
+#if MACDBG
+#define MACDBG_INFO ((ULONG)0x00000001)
+#define MACDBG_ISR ((ULONG)0x00000002)
+#define MACDBG_MAC ((ULONG)0x00000004)
+#define MACDBG_SROM ((ULONG)0x00000008)
+
+extern ULONG MacDebugLevel;
+#define MacDump(LEVEL,STRING) \
+ do { \
+ if (MacDebugLevel & (LEVEL)) { \
+ printf STRING; \
+ } \
+ } while (0)
+#else
+#define MacDump(LEVEL,STRING) do {;} while (0)
+#endif
+
+/*--------------------- Export Classes ----------------------------*/
+
+/*--------------------- Export Variables --------------------------*/
+
+/*--------------------- Export Functions --------------------------*/
+
+#endif // __DBG_H__
+
diff --git a/cpu/arm920t/wmt/desc.h b/cpu/arm920t/wmt/desc.h
new file mode 100755
index 0000000..cad492f
--- /dev/null
+++ b/cpu/arm920t/wmt/desc.h
@@ -0,0 +1,191 @@
+/*++
+Copyright (c) 2010 WonderMedia Technologies, Inc.
+
+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, see http://www.gnu.org/licenses/>.
+
+WonderMedia Technologies, Inc.
+10F, 529, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C.
+--*/
+
+
+#ifndef __DESC_H__
+#define __DESC_H__
+
+
+#if !defined(__TTYPE_H__)
+#include "ttype.h"
+#endif
+
+
+/*--------------------- Export Definitions -------------------------*/
+
+#define B_OWNED_BY_CHIP 1 //
+#define B_OWNED_BY_HOST 0 //
+
+//
+// Bits in the RSR0 register
+//
+#define RSR0_BUFF 0x80 //
+#define RSR0_SERR 0x40 //
+#define RSR0_RUNT 0x20 //
+#define RSR0_LONG 0x10 //
+#define RSR0_FOV 0x08 //
+#define RSR0_FAE 0x04 //
+#define RSR0_CRC 0x02 //
+#define RSR0_RERR 0x01 //
+
+//
+// Bits in the RSR1 register
+//
+#define RSR1_RXOK 0x80 // rx OK
+#define RSR1_VIDHIT 0x40 // VID Hit
+#define RSR1_MAR 0x20 // MAC accept multicast address packet
+#define RSR1_BAR 0x10 // MAC accept broadcast address packet
+#define RSR1_PHY 0x08 // MAC accept physical address packet
+#define RSR1_CHN 0x04 // chain buffer, always = 1
+#define RSR1_STP 0x02 // start of packet
+#define RSR1_EDP 0x01 // end of packet
+
+#define PQSTS_IPOK 0x20 //IP Checkusm validatiaon ok
+#define PQSTS_TUOK 0x10 //TCP/UDP Checkusm validatiaon ok
+#define PQSTS_IPKT 0x08 //Received an IP packet
+#define PQSTS_TCPKT 0x04 //Received a TCP packet
+#define PQSTS_UDPKT 0x02 //Received a UDP packet
+#define PQSTS_TAG 0x01 //Received a tagged packet
+
+//
+// Bits in the TSR0 register
+//
+#define TSR0_CDH 0x80 // AQE test fail (CD heartbeat)
+#define TSR0_COLS 0x10 // experience collision in this transmit event
+#define TSR0_NCR3 0x08 // collision retry counter[3]
+#define TSR0_NCR2 0x04 // collision retry counter[2]
+#define TSR0_NCR1 0x02 // collision retry counter[1]
+#define TSR0_NCR0 0x01 // collision retry counter[0]
+
+//
+// Bits in the TSR1 register
+//
+#define TSR1_TERR 0x80 //
+#define TSR1_JAB 0x40 // jabber condition occured
+#define TSR1_SERR 0x20 //
+#define TSR1_TBUFF 0x10 //
+#define TSR1_UDF 0x08 //
+#define TSR1_CRS 0x04 //
+#define TSR1_OWC 0x02 // late collision
+#define TSR1_ABT 0x01 //
+
+//
+// Bits in the TCR register
+//
+#define TCR_IC 0x80 // assert interrupt immediately
+ // while descriptor has been send complete
+#define TCR_EDP 0x40 // end of packet
+#define TCR_STP 0x20 // start of packet
+#define TCR_TCPCK 0x10 // request TCP checksum calculation.
+#define TCR_UDPCK 0x08 // request UDP checksum calculation.
+#define TCR_IPCK 0x04 // request TCP checksum calculation.
+#define TCR_CRC 0x01 // disable CRC generation
+
+
+// max transmit or receive buffer size
+//#define CB_MAX_BUF_SIZE 1536U // max buffer size
+#define CB_MAX_BUF_SIZE 2048U // max buffer size
+#define CB_BUF_SIZE_65 2048U // default Rx buffer size for 3065
+ // NOTE: must be multiple of 4
+#define CB_MAX_RD_NUM 64 // MAX # of RD
+#define CB_MAX_TD_NUM 32 // MAX # of TD
+
+#define CB_INIT_RD_NUM 10 // init # of RD, for setup default
+#define CB_INIT_TD_NUM 10 // init # of TD, for setup default
+
+// for 3106S
+#define CB_TD_RING_NUM 7 // # of TD rings.
+
+#define CB_MAX_DESC_PER_PKT 4 // max descriptors per packet (Tx)
+
+// max number of physical segments
+// in a single NDIS packet. Above this threshold, the packet
+// is copied into a single physically contiguous buffer
+#define CB_MAX_SEGMENT (1 * CB_MIN_TX_DESC)
+
+#define CB_MAP_REGISTER_NUM (1 * CB_MAX_SEGMENT)
+
+// if collisions excess 15 times , tx will abort, and
+// if tx fifo underflow, tx will fail
+// we should try to resend it
+#define CB_MAX_TX_ABORT_RETRY 3
+
+
+/*--------------------- Export Types ------------------------------*/
+
+typedef struct tagRDES0 {
+ BYTE byRSR0;
+ BYTE byRSR1;
+ WORD f15FrameLen : 15;
+ WORD f1Owner : 1;
+} SRDES0;
+
+typedef struct tagRDES1 {
+ WORD f15RxBufLen : 15;
+ WORD f1Reserve : 1;
+ BYTE byPQSTS; // VT3106
+ BYTE byIPKT; // VT3106
+} SRDES1;
+
+//
+// receive descriptor
+//
+typedef struct tagSRxDesc {
+ SRDES0 m_rd0RD0;
+ SRDES1 m_rd1RD1;
+ DWORD m_dwRxBufferAddr; // pointer to logical buffer
+ DWORD m_dwRxNextDescAddr; // pointer to next logical descriptor
+} SRxDesc, *PSRxDesc;
+typedef const SRxDesc* PCSRxDesc;
+
+typedef struct tagTDES0 {
+ BYTE byTSR0;
+ BYTE byTSR1;
+ WORD f12VID:12;
+ WORD f4Prioity:3;
+ WORD f1Owner : 1;
+} STDES0;
+
+typedef struct tagTDES1 {
+ WORD f15TxBufLen : 15;
+ WORD f1Chain : 1;
+ BYTE byTCR;
+ BYTE byReserve;
+} STDES1;
+
+//
+// transmit descriptor
+//
+typedef struct tagSTxDesc {
+ STDES0 m_td0TD0;
+ STDES1 m_td1TD1;
+ DWORD m_dwTxBufferAddr; // pointer to logical buffer
+ DWORD m_dwTxNextDescAddr; // pointer to next logical descriptor
+} STxDesc, *PSTxDesc;
+typedef const STxDesc* PCSTxDesc;
+
+/*--------------------- Export Macros ------------------------------*/
+
+/*--------------------- Export Classes ----------------------------*/
+
+/*--------------------- Export Variables --------------------------*/
+
+/*--------------------- Export Functions --------------------------*/
+
+
+#endif // __DESC_H__
+
diff --git a/cpu/arm920t/wmt/diag.h b/cpu/arm920t/wmt/diag.h
new file mode 100755
index 0000000..b29afef
--- /dev/null
+++ b/cpu/arm920t/wmt/diag.h
@@ -0,0 +1,98 @@
+/*++
+Copyright (c) 2010 WonderMedia Technologies, Inc.
+
+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, see http://www.gnu.org/licenses/>.
+
+WonderMedia Technologies, Inc.
+10F, 529, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C.
+--*/
+
+
+#ifndef __DIAG_H__
+#define __DIAG_H__
+
+#if !defined(__TTYPE_H__)
+#include "ttype.h"
+#endif
+#if !defined(__ADAPTER_H__)
+#include "adapter.h"
+#endif
+
+
+/*--------------------- Export Definitions -------------------------*/
+#define CMD_RBTST_TXRAM 0x01
+#define CMD_RBTST_RXRAM 0x02
+#define CMD_RBTST_SCANMODE 0x04
+#define CMD_RBTST_SEQMODE 0x08
+#define CMD_RBTST_PATMASK 0x70
+
+typedef enum tagDIAG_TEST_ITEM {
+ DIAG_TEST_MAC_REG_RW = 1,
+ DIAG_TEST_EEP_CONT_RW = 2,
+ DIAG_TEST_MII_REG_RW = 3,
+ DIAG_TEST_MII_FLOWREG_RW = 4,
+ DIAG_TEST_IRQ_CONN = 5,
+ DIAG_TEST_INT_EXT_LBK = 6,
+ DIAG_TEST_RD_TD_HANDLE = 7,
+ DIAG_TEST_ADDR_MATCH_LOG = 8,
+ DIAG_TEST_CABLE_LINK = 9,
+ DIAG_TEST_ITEM_MAX
+} DIAG_TEST_ITEM;
+/*--------------------- Export Classes ----------------------------*/
+
+/*--------------------- Export Variables --------------------------*/
+
+/*--------------------- Export Functions --------------------------*/
+
+#ifdef __cplusplus
+extern "C" { /* Assume C declarations for C++ */
+#endif /* __cplusplus */
+
+BOOL GDIAGbLoopbackOnceByPoll(PSAdapterInfo pAdapter);
+
+BOOL GDIAGbTestMacRegReadWrite(PSAdapterInfo pAdapter);
+BOOL GDIAGbTestSromReadWrite(PSAdapterInfo pAdapter);
+BOOL GDIAGbTestMiiRegReadWrite(PSAdapterInfo pAdapter);
+
+BOOL GDIAGbTestMiiRegRWPAUSE(PSAdapterInfo pAdapter);
+
+BOOL GDIAGbTestIrqConnect(PSAdapterInfo pAdapter);
+BOOL GDIAGbTestRdTdHandling(PSAdapterInfo pAdapter);
+BOOL GDIAGbTestAddrMatchLogic(PSAdapterInfo pAdapter);
+BOOL GDIAGbTestCableLink(PSAdapterInfo pAdapter);
+
+BOOL GDIAGbTestLoopbackMac(PSAdapterInfo pAdapter);
+BOOL GDIAGbTestLoopbackExt(PSAdapterInfo pAdapter);
+BOOL GDIAGbTestLoopbackExtGiga(PSAdapterInfo pAdapter);
+
+BOOL GDIAGbTestPromiscuousMode(PSAdapterInfo pAdapter);
+BOOL GDIAGbTestBroadcastMode(PSAdapterInfo pAdapter);
+BOOL GDIAGbTestMulticastMode(PSAdapterInfo pAdapter);
+BOOL GDIAGbTestDirectedMode(PSAdapterInfo pAdapter);
+BOOL GDIAGbTestRuntPktMode(PSAdapterInfo pAdapter);
+BOOL GDIAGbTestLongPktMode(PSAdapterInfo pAdapter);
+
+BOOL GDIAGbRAMBISTTest(PSAdapterInfo pAdapter);
+
+BOOL GDIAGbFIFOTest(PSAdapterInfo pAdapter);
+VOID GDIAGvShowHWMibCounter(
+ PSAdapterInfo pAdapter,
+ PSHWMibCounter psHWMibCounter
+ );
+
+ULONG GDIAGuNetworkTest(DWORD dwTimes, UINT uPktSize);
+
+#ifdef __cplusplus
+} /* End of extern "C" { */
+#endif /* __cplusplus */
+
+#endif /* __DIAG_H__ */
diff --git a/cpu/arm920t/wmt/dma.c b/cpu/arm920t/wmt/dma.c
new file mode 100755
index 0000000..60c2e7f
--- /dev/null
+++ b/cpu/arm920t/wmt/dma.c
@@ -0,0 +1,926 @@
+/*++
+Copyright (c) 2010 WonderMedia Technologies, Inc.
+
+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, see http://www.gnu.org/licenses/>.
+
+WonderMedia Technologies, Inc.
+10F, 529, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C.
+--*/
+
+#include <config.h>
+#include <common.h>
+#include <asm/errno.h>
+#include <asm/arch/hardware.h>
+#include <part.h>
+#include <asm-arm/arch-wmt/common_def.h>
+
+#include <dma.h>
+#include <malloc.h>
+
+static struct dma_state dma_status;
+static struct DMA_INFO dma_chan[DMA_CHANNELS];
+
+static struct DMA_DESCRIPT_ADDR descript_chan[DMA_CHANNELS];
+
+/*
+* [Table Description]
+* Default dma channel setting for each peripheral device
+* [Arguments]
+* DeviceReq -> device dma request source
+* DefaultCCR -> default channel configuration register setting
+* Source_0/Destination_0 -> address settings for buffer 0
+* Source_1/Destination_1 -> address settings for buffer 1
+*/
+struct dma_device_cfg dma_device_cfg_table[] = {
+/* DeviceReq , DefaultCCR , Source_0, Destination_0 */
+ { SPI0_DMA_TX_REQ , 0x00000100 , 0, 0 } , /*spi0*/
+ { SPI0_DMA_RX_REQ , 0x00000100 , 0, 0 } , /*spi1*/
+ { SPI1_DMA_TX_REQ , 0x00000100 , 0, 0 } ,
+ { SPI1_DMA_RX_REQ , 0x00000100 , 0, 0 } ,
+ { SPI2_DMA_TX_REQ , 0x00000100 , 0, 0 } ,
+ { SPI2_DMA_RX_REQ , 0x00000100 , 0, 0 } ,
+ /* start from 0, above 5, below 6 */
+ { UART_0_TX_DMA_REQ , 0x00000100, 0, 0 } , /* uart2*/
+ { UART_0_RX_DMA_REQ , 0x00000100, 0, 0 } , /* uart2*/
+ { UART_1_TX_DMA_REQ , 0x00000100, 0, 0 } ,
+ { UART_1_RX_DMA_REQ , 0x00000100, 0, 0 } ,
+ { UART_2_TX_DMA_REQ , 0x00000100, 0, 0 } , /* uart1*/
+ /*start from 0, above 10, below 11 */
+ { UART_2_RX_DMA_REQ , 0x00000100, 0, 0 } , /* uart1*/
+ { UART_3_TX_DMA_REQ , 0x00000100, 0, 0 } ,
+ { UART_3_RX_DMA_REQ , 0x00000100, 0, 0 } ,
+ { I2S_TX_DMA_REQ , 0x00000100, 0, 0 } ,
+ { I2S_RX_DMA_REQ , 0x00000100, 0, 0 } ,
+ /*start from 0, above 15, below 16 */
+ { UART_4_TX_DMA_REQ , 0x00000100, 0, 0} ,
+ { UART_4_RX_DMA_REQ , 0x00000100, 0, 0} ,
+ { AC97_PCM_TX_DMA_REQ , 0x00000100, 0, 0} ,
+ { AC97_PCM_RX_DMA_REQ , 0x00000100, 0, 0} ,
+ { AC97_MIC_DMA_REQ , 0x00000100, 0, 0} ,
+ /*start from 0, above 20, below 21 */
+ { DEVICE_RESERVED , 0x00000100, 0, 0} ,
+ { DEVICE_RESERVED , 0x00000100, 0, 0} ,
+ { DEVICE_RESERVED , 0x00000100, 0, 0} ,
+ { DEVICE_RESERVED , 0x00000100, 0, 0} ,
+ { DEVICE_RESERVED , 0x00000100, 0, 0} ,
+ { DEVICE_RESERVED , 0x00000100, 0, 0} ,
+ { DEVICE_RESERVED , 0x00000100, 0, 0} ,
+ { DEVICE_RESERVED , 0x00000100, 0, 0} ,
+ { UART_5_TX_DMA_REQ , 0x00000100, 0, 0} ,
+ { UART_5_RX_DMA_REQ , 0x00000100, 0, 0} ,
+ /*start from 0, above 30, below 31 */
+ { DEVICE_RESERVED , 0x00000100, 0, 0} ,
+ { MEMORY_DMA_REQ , 0x2a800000, 0x0a200000 , 0x0a220000} ,
+ { DEVICE_RESERVED , 0x00000100, 0, 0} ,
+};
+
+/*
+* [Routine Description]
+* inital DMA
+* 1. init dma_status and DMA_INFO structure for each dma channels
+* 2. init dma channel registers for each channels
+* 3. dma controller enable
+* it is necessary to allocate space to store
+* memory registers and descript register.
+* So we allocate these space while initing at the first time
+*/
+void init_dma(void)
+{
+ int ch;
+ struct DMA_REG *dma_regs ;
+ struct DMA_MEM_REG *dma_mem_regs;
+
+ static unsigned int first_init = 0;
+ static unsigned int dma_mem_regs_base;
+ dma_regs = (struct DMA_REG *)BA_DMA;
+ unsigned long addr;
+
+ printf("DMA INIT\n");
+
+ /*
+ // software initial
+ */
+ dma_status.request_chans = 0 ;
+ dma_status.regs = (struct DMA_REG *) BA_DMA;
+
+ for (ch = 0 ; ch < DMA_CHANNELS ; ++ch) {
+ if (first_init) {
+ free((unsigned long *)dma_chan[ch].DES_ADDR.DES_0);
+ free((unsigned long *)dma_chan[ch].DES_ADDR.DES_1_2);
+ free_descriptstack(ch);
+ }
+ //des_0 = calloc(SIZE_8KB,sizeof(int));
+ //des_1 = calloc(SIZE_8KB,sizeof(int));
+
+
+ dma_chan[ch].DES_ADDR.DES_0 = descript_chan[ch].despstack_0.addr_base;
+ dma_chan[ch].DES_ADDR.DES_1_2 = descript_chan[ch].despstack_1_2.addr_base;
+ dma_chan[ch].channel_no = ch ;
+ dma_chan[ch].regs = (struct DMA_REG *) BA_DMA;
+ dma_chan[ch].device_no = DEVICE_RESERVED ;
+ dma_chan[ch].in_use = 0 ;
+ dma_chan[ch].descript_cnt = 0;
+ }
+ /*
+ * hardware initial
+ */
+
+ dma_status.regs->DMA_GCR |= DMA_SW_RST ;
+ //REG32_VAL(0xD8001000 + 0x40) |= DMA_SW_RST;
+ //REG32_VAL(0xD8001800 + 0x40) |= DMA_GLOBAL_EN;
+ //*(volatile unsigned int *)BA_DMA |= DMA_SW_RST;
+
+
+
+ dma_status.regs->DMA_GCR |= DMA_GLOBAL_EN;
+ dma_status.regs->DMA_ISR = ALL_INT_CLEAR;
+ dma_status.regs->DMA_IER |= ALL_INT_EN;
+ dma_status.regs->DMA_TMR &= ~SCHEDULE_RR_DISABLE; /*use RR schedule*/
+
+
+ if (first_init)
+ free((unsigned int *)dma_mem_regs_base);
+
+
+ dma_mem_regs = (struct DMA_MEM_REG *)malloc((sizeof(struct DMA_MEM_REG)+256));
+ dma_mem_regs_base = (unsigned int)dma_mem_regs;
+
+ addr = (unsigned long)dma_mem_regs;
+ addr &= (unsigned long)0xFFFFFF00;
+ addr += 256;
+ dma_mem_regs = (struct DMA_MEM_REG *) addr;
+ //(unsigned long)dma_mem_regs &= (unsigned long)0xFFFFFF00;
+ //(unsigned long)dma_mem_regs += 256;
+ dma_status.regs->DMA_MRPR = (unsigned long)dma_mem_regs;
+
+
+ for (ch = 0 ; ch < DMA_CHANNELS ; ++ch) {
+ dma_chan[ch].mem_regs = (struct DMA_MEM_REG *)dma_mem_regs;
+ dma_mem_regs->MEM_REG_GROUP[ch].DMA_IF0CPR_CH = 0x0;
+ dma_mem_regs->MEM_REG_GROUP[ch].DMA_IF1CPR_CH = 0x0;
+ dma_status.regs->DMA_CCR_CH[ch] = 0x0;
+ }
+
+
+ if(!first_init)
+ first_init++;
+
+ printf("DMA INIT finish\n");
+
+}
+
+void disable_dma(void)
+{
+ dma_status.regs->DMA_GCR &= (~DMA_GLOBAL_EN);
+}
+
+void enable_dma(void)
+{
+ unsigned int ch = 0;
+ dma_status.regs->DMA_GCR |= DMA_GLOBAL_EN;
+ for (ch = 0; ch < DMA_CHANNELS; ++ch)
+ dma_status.regs->DMA_CCR_CH[ch] |= SYSTEM_DMA_RUN;
+}
+
+
+/*
+* [Routine Description]
+* request a free dma channel
+* 1. search free dma channel,
+* 2. update arguments to specific DMA_INFO structure
+* 3. re-setting dma channel registers according to new configuration
+* [Arguments]
+* channel -> interrupt number
+* device_id -> device id string
+* device -> dma_device structure
+* callback -> device isr function
+* [Return]
+* 0 -> success
+* -1 -> fail
+*/
+int request_dma(unsigned int *channel, const char *device_id, enum dma_device device)
+{
+ int ch;
+ struct DMA_INFO *dma;
+ *channel = -1;
+
+ /*
+ * Ask for Free Channels
+ */
+
+ for (ch = 0 ; ch < DMA_CHANNELS ; ++ch) {
+ dma = &dma_chan[ch];
+ if (dma->in_use == 0)
+ break ;
+ }
+
+ if (ch >= DMA_CHANNELS) {
+ printf("DMA : %s no free DMA channel available\n\r", device_id);
+ return -1; /* EBUSY*/
+ }
+
+ /*
+ * Request IRQ, all DMA Share one IRQ, so we do request only request_chans is zero
+ */
+ //if (!(dma_status.request_chans & (1 << ch))) {
+ //set_irq_handlers(dma_irq_mapping[ch], dma_irq_handler) ;
+ //unmask_interrupt(dma_irq_mapping[ch]) ;
+ //}
+
+ dma_status.request_chans = (1 << ch) ;
+
+ *channel = ch;
+ dma->device_id = device_id;
+ dma->device_no = device ;
+ //dma->callback = callback;
+ dma->in_use = 1;
+ dma->descript_cnt = 0;
+
+ /*
+ * clear status register
+ */
+ dma->regs->DMA_ISR |= 1<<ch;
+ dma->mem_regs->MEM_REG_GROUP[ch].DMA_IF0CPR_CH = 0x0; /*reset descript*/
+ dma->mem_regs->MEM_REG_GROUP[ch].DMA_IF1CPR_CH = 0x0; /*reset descript*/
+ /*set shadow descript addr*/
+ descript_chan[ch].DES_0 = dma->DES_ADDR.DES_0;
+ descript_chan[ch].DES_1_2 = dma->DES_ADDR.DES_1_2;
+ /*
+ * setup default device
+ */
+ dma->device_cfg = dma_device_cfg_table[device] ;
+
+ /*
+ *Critical 3: It should be filled with DefaultCCR
+ */
+ /*Dean:To do*/
+ dma->regs->DMA_CCR_CH[ch] = (dma_device_cfg_table[device].DefaultCCR & DMA_USER_SET_MASK) ;
+ if (device != MEMORY_DMA_REQ)
+ dma->regs->DMA_CCR_CH[ch] |= device << DMA_REQ_ID_SHIFT;
+
+
+ #ifdef CONFIG_EMU
+ printf("DMA : requested dma device %d\n\r", device);
+ #endif /*CONFIG_EMU*/
+ return 0;
+}
+
+/*
+* [Routine Description]
+* clear specific dma channel register
+* [Arguments]
+* ch -> channel number
+*/
+void clear_dma(unsigned int ch)
+{
+ struct DMA_INFO *dma;
+ dma = &dma_chan[ch] ;
+
+ /*
+ * clear status register
+ */
+ dma->regs->DMA_CCR_CH[ch] = 0x0;
+ dma->regs->DMA_ISR |= 0x1<<ch;
+ dma->mem_regs->MEM_REG_GROUP[ch].DMA_IF0CPR_CH = 0x0; /*clear M_0 descript address*/
+ dma->mem_regs->MEM_REG_GROUP[ch].DMA_IF1CPR_CH = 0x0; /*clear M_1/2 descript address*/
+ dma->descript_cnt = 0x0;
+ free((unsigned long *)dma->DES_ADDR.DES_0);
+ free((unsigned long *)dma->DES_ADDR.DES_1_2);
+}
+
+/*
+* [Routine Description]
+* release specific dma channel
+* 1. check whether free correct dma channel
+* 2. clear_dma()
+* 3. clear specific DMA_INFO structure and SCC register setting for dma request source
+* [Arguments]
+* ch -> channel number
+*/
+void free_dma(unsigned int ch)
+{
+ struct DMA_INFO *dma;
+ enum dma_device dev_no ;
+
+ if (ch >= MAX_DMA_CHANNELS) {
+ printf("DMA : bad DMA identifier\n\r");
+ return ;
+ }
+
+ dma = &dma_chan[ch];
+ if (dma->in_use == 0) {
+ #ifdef CONFIG_EMU
+ printf("DMA : trying to free free dma channe %dl\n\r", ch);
+ #endif
+ return;
+ }
+
+ if (dma->device_no == DEVICE_RESERVED) {
+ printf("DMA : trying to free free dma %d\n\r", ch);
+ return ;
+ }
+
+ clear_dma(ch);
+
+ dma_status.request_chans &= ~(1 << ch);
+ //if (dma_status.request_chans == 0)
+ // unset_irq_handlers(dma_irq_mapping[ch]);
+
+
+ dev_no = dma->device_no ;
+ /*if(dev_no != MEMORY_DMA_REQ)
+ dma->scc_regs->DMA_REQ_CSR[ dev_no ] = ( SCC_CSR_DISABLE | SCC_CSR_SYSTEM_DMA | 0 ) ;*/
+ dma->device_no = DEVICE_RESERVED ;
+ dma->device_id = NULL ;
+ dma->in_use = 0;
+}
+
+/*
+* [Routine Description]
+* setup dma configure table with relative dma channel and re-setting dma channel registers
+* 1. check whether setup correct dma channel
+* 2. clear dma relative status register
+* 3. update dma_device_cfg table
+* 4. re-setting dma channel registers
+* [Arguments]
+* ch -> channel number
+* device_cfg -> dma_device_cfg structure
+* [Return]
+* 0 -> success
+* 1 -> fail
+*/
+int setup_dma(unsigned int ch, struct dma_device_cfg device_cfg)
+{
+ struct DMA_INFO *dma;
+ enum dma_device dev_no ;
+
+ dma = &dma_chan[ch];
+
+ if (ch >= MAX_DMA_CHANNELS || (dma_chan[ch].in_use == 0)) {
+ printf("DMA : bad DMA identifier\n\r");
+ return -1 ; /* EINVAL*/
+ }
+
+ if (dma->device_no != device_cfg.DeviceReqType) {
+ printf("DMA : bad Device_NO\n\r");
+ return -1 ;
+ }
+
+ //printf("CCR setting ch%d = %x\n", ch, device_cfg.DefaultCCR);
+
+ dev_no = dma->device_no ;
+ dma_device_cfg_table[dev_no] = device_cfg ;
+ dma->device_cfg = dma_device_cfg_table[dev_no] ;
+
+ /*
+ * clear status register
+ */
+ dma->regs->DMA_ISR |= 1<<ch;
+ dma->mem_regs->MEM_REG_GROUP[ch].DMA_IF0CPR_CH = 0x0; /*reset descript*/
+ dma->mem_regs->MEM_REG_GROUP[ch].DMA_IF1CPR_CH = 0x0; /*reset descript*/
+
+ dma->regs->DMA_CCR_CH[ch] = dma_device_cfg_table[dev_no].DefaultCCR ;
+ if (device_cfg.DeviceReqType != MEMORY_DMA_REQ)
+ dma->regs->DMA_CCR_CH[ch] |= device_cfg.DeviceReqType << DMA_REQ_ID_SHIFT;
+
+ /*Device -> Memory(Read)*/
+ //if (dma->regs->DMA_CCR_CH[ch] & DEVICE_TO_MEM) {
+ /* 0x00010000*/
+ // dma->mem_regs->MEM_REG_GROUP[ch].DMA_IF1CPR_CH = dma->device_cfg.MIF1addr;
+ // dma->mem_regs->MEM_REG_GROUP[ch].DMA_IF0CPR_CH = 0 ;
+ //} else {/* Memory(Write)i-->Device*/
+ // dma->mem_regs->MEM_REG_GROUP[ch].DMA_IF0CPR_CH = 0 ;
+ // dma->mem_regs->MEM_REG_GROUP[ch].DMA_IF1CPR_CH = dma->device_cfg.MIF1addr ;
+ //}
+ //if (dev_no == MEMORY_DMA_REQ) {
+ /*
+ dma->mem_regs->MEM_REG_GROUP[ch].DMA_IF0CPR_CH = dma->device_cfg.MIF0addr;
+ dma->mem_regs->MEM_REG_GROUP[ch].DMA_IF1CPR_CH = dma->device_cfg.MIF1addr;
+ */
+ descript_chan[ch].DES_0 = dma->DES_ADDR.DES_0; /*we set descript size to 2 KB*/
+ descript_chan[ch].DES_1_2 = dma->DES_ADDR.DES_1_2; /*we set descript size to 2 KB*/
+ //}
+ return 0;
+}
+
+
+
+/*===================================================*/
+/* [Routine Description]*/
+/* check relative dma channel whether enable or disable*/
+/* [Arguments]*/
+/* ch -> channel number*/
+/* [Return]*/
+/* 1 -> busy(enable)*/
+/* 0 -> not busy(disable)*/
+/* other -> fail*/
+/*===================================================*/
+int dma_busy(unsigned int ch)
+{
+ struct DMA_INFO *dma;
+ /*
+ unsigned int newtimer = 0;
+ */
+ dma = &dma_chan[ch];
+ if ((ch >= MAX_DMA_CHANNELS) || (dma_chan[ch].in_use == 0)) {
+ printf("DMA : bad DMA identifier\n\r");
+ return -1 ; /* EINVAL*/
+ }
+
+ if (dma->regs->DMA_CCR_CH[ch] & DMA_ACTIVE)
+ return 1 ;
+ else
+ /*
+ newtimer = ReadTimer();
+ printf("time = %d\n",(newtimer-global_timer));
+ */
+ return 0;
+
+}
+
+/*===================================================*/
+/* [Routine Description]*/
+/* check terminal count bit of relative dma channel*/
+/* [Arguments]*/
+/* ch -> channel number*/
+/* [Return]*/
+/* 0 -> complete*/
+/* 1 -> not complete*/
+/* other -> fail*/
+/*===================================================*/
+int dma_complete(unsigned int ch)
+{
+ struct DMA_INFO *dma;
+
+ dma = &dma_chan[ch];
+ if ((ch >= MAX_DMA_CHANNELS) || (dma_chan[ch].in_use == 0)) {
+ printf("DMA : bad DMA identifier\n\r");
+ return -1 ; /* EINVAL*/
+ }
+ /*
+ if ((dma->regs->DMA_CCR_CH[ch]&DMA_EVT_ID_MASK) == DMA_EVT_SUCCESS)
+ return 0 ;
+ */
+ if (dma->regs->DMA_CCR_CH[ch] & DMA_P0_COMPLETE)
+ return 0 ;
+ else
+ return 1;
+
+}
+
+/*===================================================*/
+/* [Routine Description]*/
+/* start specific dma channel transfer*/
+/* 1. check whether data size or buffer usage correctly*/
+/* 2. configure relative dma channel registers*/
+/* 3. dma channel enable*/
+/* [Arguments]*/
+/* ch -> channel number*/
+/* dma_ptr1 -> source/destionation address for memory-to-peripheral/peripheral-to-memory transfer*/
+/* or source address for memory-to-memory transfer*/
+/* dma_ptr2 -> destination address for memory-to-memory transfer*/
+/* size -> transfer data size*/
+/* [Return]*/
+/* 0 -> start transfer*/
+/* -1 -> fail*/
+/*===================================================*/
+int start_dma(unsigned long ch, unsigned long dma_ptr1, unsigned long dma_ptr2, unsigned long size)
+{
+ int count ;
+ int residue_count;
+ int des_cnt;
+ unsigned int current_des0;
+ struct DMA_INFO *dma ;
+ enum dma_device dev_no ;
+
+ /*
+ global_timer = 0
+ SetTimer();
+ */
+ dma = &dma_chan[ch] ;
+
+ if (size == 0)
+ return -1 ;
+
+ dev_no = dma->device_no ;
+ count = size;
+ residue_count = size;
+ current_des0 = descript_chan[ch].DES_0;
+ //if (dev_no == MEMORY_DMA_REQ) {
+ dma->mem_regs->MEM_REG_GROUP[ch].DMA_IF0CPR_CH = descript_chan[ch].DES_0;
+ dma->mem_regs->MEM_REG_GROUP[ch].DMA_IF1CPR_CH = descript_chan[ch].DES_1_2;
+ des_cnt = prepare_dma_descript(current_des0, dma_ptr1, residue_count);
+ dma->descript_cnt += des_cnt;
+ current_des0 += des_cnt*DMA_DES0_SIZE;
+ descript_chan[ch].DES_0 = current_des0;
+ dma->descript_cnt = prepare_dma_descript(descript_chan[ch].DES_1_2, dma_ptr2, count);
+ descript_chan[ch].DES_1_2 += dma->descript_cnt*DMA_DES0_SIZE;
+
+ //} else {
+ // dma->descript_cnt = prepare_dma_descript(descript_chan[ch].DES_0, dma_ptr1, count);
+ // dma->mem_regs->MEM_REG_GROUP[ch].DMA_IF0CPR_CH = descript_chan[ch].DES_0;
+ //}
+ //dma->descript_cnt--;
+ /*
+ global_timer = ReadTimer();
+ */
+ dma->regs->DMA_CCR_CH[ch] &= ~(SYSTEM_DMA_RUN);
+ dma->regs->DMA_CCR_CH[ch] |= SYSTEM_DMA_RUN;
+ printf("IF0CPR ch%d = %x\n", ch, dma->mem_regs->MEM_REG_GROUP[ch].DMA_IF0CPR_CH);
+ printf("IF1CPR ch%d = %x\n", ch, dma->mem_regs->MEM_REG_GROUP[ch].DMA_IF1CPR_CH);
+
+ return 0;
+}
+
+/*===================================================*/
+/* [Routine Description]*/
+/* dma interrupt service routine*/
+/* 1. check which dma channel interrupt event occur*/
+/* 2. clear interrupt event*/
+/* 3. call to relative device isr routine*/
+/*===================================================*/
+void handle_dma_irq(unsigned long ch)
+{
+ unsigned int global_status ;
+ unsigned char chan_status ; /* fix to use 8-bit character, temp comment */
+ struct DMA_INFO *dma ;
+
+ if (ch >= DMA_CHANNELS){
+ printf("DMA : unknown DMA IRQ\n\r") ;
+ return ;
+ }
+ dma = &dma_chan[ch] ;
+
+ //while(1){
+
+ global_status = (dma_status.regs->DMA_ISR & 0xFFFF) ;
+ while(!(global_status & (0x0001 << ch))){
+ global_status = (dma_status.regs->DMA_ISR & 0xFFFF);
+ }
+
+ //while (1) {
+ // if (dma_busy(ch) != 1)
+ // break;
+ //}
+
+ //printf("DMA%d, %x : \n", ch, dma_status.regs->DMA_CCR_CH[ch]);
+
+ if (global_status & (0x0001 << ch)) {
+ chan_status = dma_status.regs->DMA_CCR_CH[ch] ;
+ if ((chan_status & DMA_EVT_ID_MASK) == DMA_EVT_SUCCESS){
+ dma_status.regs->DMA_ISR = 1<<ch; /* Harry@Feb.28.2005*/
+ //break ; /* do one servce, each time*/
+
+ }
+ }
+
+
+ /*
+ * If there is any DMA error flag turned on.
+ */
+ if ((chan_status & DMA_EVT_ID_MASK) != DMA_EVT_SUCCESS) {
+ /* 1. clear error/abort status*/
+ /* 2. re-program src/des/cnt reg 0 and 1*/
+ /* 3. write "1" to csr bit6 to reset the buffer pointer to 0*/
+ /* 4. re-enable dma channle*/
+
+ /*
+ * I hold in here and try to look what is the error.
+ */
+ while (1)
+ ;
+ return ;
+ }
+
+ /*
+ * Decrease the channel buffer usage indicator.
+ */
+ //}
+ return;
+}
+/*===================================================*/
+/* [Routine Description]*/
+/* create dma descript format 0*/
+/* 1. clear the last descript end bit and interrupt bit*/
+/* 2. count how many descripts need to be setting*/
+/* 3. set descript */
+/* [Arguments]*/
+/* start_descript---> the first descript address*/
+/* start_addr----> the first data address*/
+/* size----> the size needing to transfer*/
+/*===================================================*/
+int prepare_dma_descript(unsigned int start_descript, unsigned int start_addr, unsigned int size)
+{
+ unsigned int need_descriptcnt ;
+ unsigned int residue_size;
+ unsigned int i;
+ unsigned des_col0;
+ des_col0 = 0;
+ need_descriptcnt = size/SIZE_32KB;
+ residue_size = size%SIZE_32KB;
+ struct DMA_DES_FMT0 *descript_addr;
+ descript_addr = (struct DMA_DES_FMT0 *)start_descript;
+ --descript_addr;
+ descript_addr->REQCNT &= ~(DMA_DES_END|DMA_INTEN_DES);
+ ++descript_addr;
+ for (i = 0; i < need_descriptcnt; ++i) {
+ des_col0 = 0;
+ des_col0 = SIZE_32KB;
+ descript_addr->REQCNT = des_col0;
+ descript_addr->DATAADDR = start_addr + i*SIZE_32KB;
+ ++descript_addr;
+ }
+ if (residue_size != 0) {
+ need_descriptcnt++;
+ des_col0 = 0;
+ des_col0 = (DMA_DES_END|DMA_INTEN_DES|residue_size);
+ descript_addr->REQCNT = des_col0;
+ descript_addr->DATAADDR = start_addr + i*SIZE_32KB;
+ } else {
+ --descript_addr;
+ descript_addr->REQCNT |= DMA_DES_END|DMA_INTEN_DES;
+ }
+ return need_descriptcnt;
+}
+/*===================================================*/
+/* [Routine Description]*/
+/* create dma descript format 1*/
+/* [Arguments]*/
+/* start_descript---> the first descript address*/
+/* branch_descript---> branch descirpt*/
+/* start_addr----> the first data address*/
+/* size----> the size needing to transfer*/
+/* last--->*/
+/* 0:did not the last descript*/
+/* 1:the last descript*/
+/*===================================================*/
+int prepare_dma_long_descript(unsigned int start_descript, unsigned int branch_descript,
+ unsigned int start_addr, unsigned int size, unsigned int last_des)
+{
+ unsigned int need_descriptcnt ;
+ unsigned des_col0;
+ need_descriptcnt = 1;
+ if (size >= 0x10000) {
+ printf("reqCount too big\n");
+ return 1;
+ }
+ des_col0 = 0;
+ struct DMA_DES_FMT1 *descript_addr;
+ descript_addr = (struct DMA_DES_FMT1 *)start_descript;
+ des_col0 = 0;
+ des_col0 = DMA_FORMAT_DES1|TRAN_SIZE;
+ descript_addr->REQCNT = des_col0;
+ descript_addr->DATAADDR = start_addr ;
+ descript_addr->BRADDR = branch_descript ;
+
+ if (last_des != 0) {
+ need_descriptcnt++;
+ des_col0 = 0;
+ des_col0 |= (DMA_DES_END|DMA_INTEN_DES);
+ }
+ ++descript_addr;
+ return need_descriptcnt;
+}
+
+void wake_dma_channel(unsigned int ch)
+{
+ dma_status.regs->DMA_CCR_CH[ch] |= DMA_WAKE;
+}
+/*===================================================*/
+/* [Routine Description]*/
+/* add descipt from the end of the last transfer descript*/
+/* [Arguments]*/
+/* ch--->dma channel number*/
+/* source_addr--->the source data address */
+/* dest_addr--->the destination data address*/
+/* transfer_size--->the size you want transfer*/
+/*===================================================*/
+void add_descript(unsigned int ch, unsigned int source_addr,
+ unsigned int dest_addr, unsigned int transfer_size)
+{
+ unsigned des_cnt;
+ struct DMA_INFO *dma ;
+ dma = &dma_chan[ch];
+ prepare_dma_descript(descript_chan[ch].DES_0, source_addr, transfer_size);
+ des_cnt = prepare_dma_descript(descript_chan[ch].DES_1_2, dest_addr, transfer_size);
+ dma->descript_cnt += des_cnt ;
+ descript_chan[ch].DES_0 += des_cnt*DMA_DES0_SIZE ;
+ descript_chan[ch].DES_1_2 += des_cnt*DMA_DES0_SIZE;
+}
+
+void init_descriptstack(unsigned int ch)
+{
+ struct DMA_DES_FMT1 *descript_addr;
+ descript_chan[ch].despstack_0.addr_base = (unsigned int)calloc(SIZE_8KB + 8,sizeof(int));
+ descript_chan[ch].despstack_1_2.addr_base = (unsigned int)calloc(SIZE_8KB + 8,sizeof(int));
+ descript_addr = (struct DMA_DES_FMT1 *)(descript_chan[ch].despstack_0.addr_base);
+ descript_addr += (descript_chan[ch].despstack_0.length - 1);
+ descript_addr->BRADDR = descript_chan[ch].despstack_0.addr_base;
+ descript_addr->REQCNT |= DMA_FORMAT_DES1;
+ descript_addr = (struct DMA_DES_FMT1 *)(descript_chan[ch].despstack_1_2.addr_base);
+ descript_addr += (descript_chan[ch].despstack_1_2.length - 1);
+ descript_addr->BRADDR = descript_chan[ch].despstack_1_2.addr_base;
+ descript_addr->REQCNT |= DMA_FORMAT_DES1;
+
+ descript_chan[ch].despstack_0.length = 1024;
+ descript_chan[ch].despstack_1_2.length = 1024;
+ descript_chan[ch].despstack_0.cur_index = 0;
+ descript_chan[ch].despstack_1_2.cur_index = 0;
+ descript_chan[ch].despstack_0.head_index = 0;
+ descript_chan[ch].despstack_1_2.head_index = 0;
+ descript_chan[ch].despstack_0.freedesp_num = 1024;
+ descript_chan[ch].despstack_1_2.freedesp_num = 1024;
+ descript_chan[ch].despstack_0.mem_startaddr = 0;
+ descript_chan[ch].despstack_1_2.mem_startaddr = 0;
+ descript_chan[ch].despstack_0.mem_length = 0;
+ descript_chan[ch].despstack_1_2.mem_length = 0;
+}
+
+void reset_descriptstack(unsigned int ch)
+{
+ //descript_chan[ch].despstack_0.length = 1024;
+ //descript_chan[ch].despstack_1_2.length = 1024;
+ descript_chan[ch].despstack_0.cur_index = 0;
+ descript_chan[ch].despstack_1_2.cur_index = 0;
+ descript_chan[ch].despstack_0.head_index = 0;
+ descript_chan[ch].despstack_1_2.head_index = 0;
+ descript_chan[ch].despstack_0.freedesp_num = 1024;
+ descript_chan[ch].despstack_1_2.freedesp_num = 1024;
+ descript_chan[ch].despstack_0.mem_startaddr = 0;
+ descript_chan[ch].despstack_1_2.mem_startaddr = 0;
+ descript_chan[ch].despstack_0.mem_length = 0;
+ descript_chan[ch].despstack_1_2.mem_length = 0;
+}
+
+void free_descriptstack(unsigned int ch)
+{
+ free((unsigned long *)(descript_chan[ch].despstack_0.addr_base));
+ free((unsigned long *)(descript_chan[ch].despstack_1_2.addr_base));
+}
+
+int set_descript(struct desp_stack * pdesp_stack, unsigned int start_addr, unsigned int size)
+{
+ unsigned int need_descriptcnt;
+ unsigned int residue_size;
+ unsigned int i;
+ struct DMA_DES_FMT0 *descript_addr;
+
+ if(size == 0){
+ printf("ERROR: zero bytes is requested!\n");
+ return 0;
+ }
+
+ need_descriptcnt = size/SIZE_32KB;
+ residue_size = size%SIZE_32KB;
+
+ if(need_descriptcnt >= pdesp_stack->freedesp_num)
+ {
+ need_descriptcnt = pdesp_stack->freedesp_num;
+ }
+ if(size > need_descriptcnt * SIZE_32KB && need_descriptcnt != 0)
+ {
+ pdesp_stack->mem_startaddr = start_addr + need_descriptcnt * SIZE_32KB;
+ pdesp_stack->mem_length = size - need_descriptcnt * SIZE_32KB;
+ }
+ else
+ {
+ pdesp_stack->mem_startaddr = 0;
+ pdesp_stack->mem_length = 0;
+ }
+ //printf("residue = %x\n", pdesp_stack->mem_length);
+ descript_addr = (struct DMA_DES_FMT0 *)(pdesp_stack->addr_base);
+ if(pdesp_stack->cur_index == 0)
+ {
+ descript_addr += (pdesp_stack->length - 1);
+ }
+ else
+ {
+ descript_addr += (pdesp_stack->cur_index - 1);
+ }
+ descript_addr->REQCNT &= ~(DMA_DES_END|DMA_INTEN_DES);
+ if(pdesp_stack->cur_index == 0)
+ {
+ descript_addr -= (pdesp_stack->length - 1);
+ }
+ else
+ {
+ ++descript_addr;;
+ }
+
+ pdesp_stack->head_index = pdesp_stack->cur_index;
+
+ for (i = 0; i < need_descriptcnt; ++i) {
+ descript_addr->REQCNT |= SIZE_32KB;
+ if(pdesp_stack->cur_index == (pdesp_stack->length - 1))
+ {
+ descript_addr->REQCNT |= DMA_FORMAT_DES1;
+ descript_addr = (struct DMA_DES_FMT0 *)(pdesp_stack->addr_base);
+ pdesp_stack->cur_index = 0;
+ }
+ else
+ {
+ ++descript_addr;
+ pdesp_stack->cur_index ++;
+ }
+ descript_addr->DATAADDR = start_addr + i * SIZE_32KB;
+ pdesp_stack->freedesp_num--;
+ }
+
+ if (residue_size != 0 && pdesp_stack->freedesp_num > 0) {
+ descript_addr->REQCNT |= (DMA_DES_END|DMA_INTEN_DES|residue_size);
+ if(pdesp_stack->cur_index == (pdesp_stack->length - 1))
+ {
+ descript_addr->REQCNT |= DMA_FORMAT_DES1;
+ pdesp_stack->cur_index = 0;
+ }
+ else
+ {
+ pdesp_stack->cur_index ++;
+ }
+ descript_addr->DATAADDR = start_addr + i * SIZE_32KB;
+ pdesp_stack->freedesp_num--;
+ need_descriptcnt ++;
+ }
+ else
+ {
+ if(pdesp_stack->cur_index == 0){
+ descript_addr = (struct DMA_DES_FMT0 *)(pdesp_stack->addr_base);
+ descript_addr += (pdesp_stack->length - 1);
+ }
+ else{
+ descript_addr --;
+ }
+ descript_addr->REQCNT |= DMA_DES_END|DMA_INTEN_DES;
+ }
+ return need_descriptcnt;
+}
+
+int handle_transfer(unsigned long ch, unsigned long dma_ptr1, unsigned long dma_ptr2, unsigned long size)
+{
+ int count ;
+ int residue_count;
+ int des_cnt;
+ struct DMA_INFO *dma ;
+ enum dma_device dev_no ;
+ int firststart;
+
+ firststart = 1;
+ dma = &dma_chan[ch] ;
+
+ if (size == 0)
+ return -1 ;
+
+ dev_no = dma->device_no;
+ count = size;
+ residue_count = size;
+ do{
+ des_cnt = set_descript(&(descript_chan[ch].despstack_0), dma_ptr1, residue_count);
+ printf("residue ch%d = %x\n", ch, descript_chan[ch].despstack_0.mem_length);
+ dma->descript_cnt += des_cnt;
+ descript_chan[ch].DES_0 = descript_chan[ch].despstack_0.addr_base + descript_chan[ch].despstack_0.head_index * DMA_DES0_SIZE;
+ dma->mem_regs->MEM_REG_GROUP[ch].DMA_IF0CPR_CH = descript_chan[ch].DES_0;
+ dma->descript_cnt = set_descript(&descript_chan[ch].despstack_1_2, dma_ptr2, count);
+ //printf("Stack 1 Base ch%d = %x\n", ch, descript_chan[ch].despstack_1_2.addr_base);
+ descript_chan[ch].DES_1_2 = descript_chan[ch].despstack_1_2.addr_base + descript_chan[ch].despstack_1_2.head_index * DMA_DES0_SIZE;
+ dma->mem_regs->MEM_REG_GROUP[ch].DMA_IF1CPR_CH = descript_chan[ch].DES_1_2;
+ if(firststart){
+ dma->regs->DMA_CCR_CH[ch] &= ~(SYSTEM_DMA_RUN);
+ dma->regs->DMA_CCR_CH[ch] |= SYSTEM_DMA_RUN;
+ firststart = 0;
+ }
+ else
+ {
+ dma->regs->DMA_CCR_CH[ch] |= DMA_WAKE;
+ }
+ //printf("IF0CPR ch%d = %x\n", ch, dma->mem_regs->MEM_REG_GROUP[ch].DMA_IF0CPR_CH);
+ // printf("IF1CPR ch%d = %x\n", ch, dma->mem_regs->MEM_REG_GROUP[ch].DMA_IF1CPR_CH);
+
+ //printf("DMA%d : handle irq begin\n", ch);
+ handle_dma_irq(ch);
+ descript_chan[ch].despstack_0.head_index += dma->descript_cnt;
+ descript_chan[ch].despstack_0.freedesp_num += dma->descript_cnt;
+ descript_chan[ch].despstack_1_2.head_index += dma->descript_cnt;
+ descript_chan[ch].despstack_1_2.freedesp_num += dma->descript_cnt;
+ //printf("DMA%d : handle irq OK\n", ch);
+ while (1) {
+ if (dma_busy(ch) != 1)
+ break;
+ }
+ //printf("DMA%d : no busy\n", ch);
+ while (1) {
+ if (dma_complete(ch) == 0)
+ break;
+ }
+ }
+ while(descript_chan[ch].despstack_0.mem_length > 0);
+
+ return 0;
+}
diff --git a/cpu/arm920t/wmt/ether.c b/cpu/arm920t/wmt/ether.c
new file mode 100755
index 0000000..aafad9e
--- /dev/null
+++ b/cpu/arm920t/wmt/ether.c
@@ -0,0 +1,85 @@
+/*++
+Copyright (c) 2010 WonderMedia Technologies, Inc.
+
+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, see http://www.gnu.org/licenses/>.
+
+WonderMedia Technologies, Inc.
+10F, 529, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C.
+--*/
+
+#include <common.h>
+#include <asm/io.h>
+#include <net.h>
+#include <miiphy.h>
+#include "macif.h"
+#include "mac.h"
+#include "alloct.h"
+#include <asm/u-boot.h>
+#include <configs/wmt.h>
+
+#ifdef CONFIG_DRIVER_ETHER
+
+#if (CONFIG_COMMANDS & CFG_CMD_NET)
+
+/******************************************************************************
+ *
+ * Public u-boot interface functions below
+ *
+ *****************************************************************************/
+int eth_init(bd_t *bd)
+{
+ return mac_startio(bd);
+ }
+
+int eth_send(volatile void *packet, int length)
+{
+ return mac_send(packet,length);
+}
+
+int eth_rx(void)
+{
+ return mac_receive();
+}
+
+void eth_halt(void)
+{
+ mac_halt();
+ return;
+}
+
+#if defined(CONFIG_MII) || (CONFIG_COMMANDS & CFG_CMD_MII)
+int wmt_miiphy_read(char *devname, unsigned char addr,
+ unsigned char reg, unsigned short *value)
+{
+ mii_read(devname, addr, reg, value);
+ return 0;
+}
+
+int wmt_miiphy_write(char *devname, unsigned char addr,
+ unsigned char reg, unsigned short value)
+{
+ mii_write(devname, addr, reg, value);
+ return 0;
+}
+
+#endif /* defined(CONFIG_MII) || (CONFIG_COMMANDS & CFG_CMD_MII) */
+
+int wmt_miiphy_initialize(bd_t *bis)
+{
+#if defined(CONFIG_MII) || (CONFIG_COMMANDS & CFG_CMD_MII)
+ /* miiphy_register("wmtphy", wmt_miiphy_read, wmt_miiphy_write); */
+#endif
+ return 0;
+}
+
+#endif /* CONFIG_COMMANDS & CFG_CMD_NET */
+
+#endif /* CONFIG_DRIVER_ETHER */
diff --git a/cpu/arm920t/wmt/gadapter.c b/cpu/arm920t/wmt/gadapter.c
new file mode 100755
index 0000000..1615b0b
--- /dev/null
+++ b/cpu/arm920t/wmt/gadapter.c
@@ -0,0 +1,631 @@
+/*++
+Copyright (c) 2010 WonderMedia Technologies, Inc.
+
+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, see http://www.gnu.org/licenses/>.
+
+WonderMedia Technologies, Inc.
+10F, 529, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C.
+--*/
+
+#if !defined(__UPCI_H__)
+#include "upci.h"
+#endif
+#if !defined(__CARD_H__)
+#include "card.h"
+#endif
+#if !defined(__GISR_H__)
+#include "gisr.h"
+#endif
+#if !defined(__VPCI_H__)
+#include "vpci.h"
+#endif
+#if !defined(__TCONVERT_H__)
+#include "tconvert.h"
+#endif
+#if !defined(__ALLOCT_H__)
+#include "alloct.h"
+#endif
+
+#include "macif.h"
+
+/*--------------------- Static Definitions -------------------------*/
+
+/*--------------------- Static Classes ----------------------------*/
+
+/*--------------------- Static Variables --------------------------*/
+
+/*--------------------- Static Functions --------------------------*/
+static void s_vInit(
+ PSAdapterInfo pAdapter,
+ UINT uTotalNum,
+ UINT uIdx,
+ PISR pisrNetIsr,
+ WORD wBusDevFunID
+ );
+/*--------------------- Export Variables --------------------------*/
+PSAdapterInfo sg_aGAdapter;
+SAdapterOpts sOptions = {0, 0, 0, 0, 0, 0};
+PBYTE sg_abyRandomTable;
+
+/*--------------------- Export Functions --------------------------*/
+/* Init all adapter's AdapterInfo data structure */
+UINT GADPuInitAll(void)
+{
+ PISR apisrNetProc[MAX_NET_DEVICE] = {
+ (PISR)ISRvIsrForNetwork_Card0,
+ (PISR)ISRvIsrForNetwork_Card1,
+ (PISR)ISRvIsrForNetwork_Card2,
+ (PISR)ISRvIsrForNetwork_Card3
+ };
+
+ SPciDevice pciDevice3119;
+ SPciDevice pciDevice3286;
+
+ int ii;
+ U16 u16IdxPciDev;
+ U16 u16TotalPciDev;
+
+ /* read pci info */
+ /*
+ NPCIbReadDeviceInfo(NULL, W_VENDOR_ID, W_DEVICE_ID_3119A, &pciDevice3119);
+ NPCIbReadDeviceInfo(NULL, W_VENDOR_ID, 0x3286, &pciDevice3286);
+ */
+ memset(&pciDevice3119, 0, sizeof(SPciDevice));
+ memset(&pciDevice3286, 0, sizeof(SPciDevice));
+ pciDevice3119.wDeviceNum = CB_MAX_NET_DEVICE;
+ pciDevice3286.wDeviceNum = 0;
+
+ u16TotalPciDev = (U16)(pciDevice3119.wDeviceNum + pciDevice3286.wDeviceNum);
+
+ if (u16TotalPciDev == 0)
+ return 0;
+
+ sg_aGAdapter = (PSAdapterInfo)malloc(sizeof(SAdapterInfo)*u16TotalPciDev);
+ if (sg_aGAdapter == NULL) {
+ printf("Memory allocation error %s, %d\n", __FILE__, __LINE__);
+ freemem();
+ return 0;
+ }
+ memset(sg_aGAdapter, 0, sizeof(SAdapterInfo)*u16TotalPciDev);
+
+ /* set adapter info */
+ u16IdxPciDev = 0;
+ for (ii = 0; ii < pciDevice3119.wDeviceNum; ii++, u16IdxPciDev++) {
+ s_vInit(
+ &sg_aGAdapter[u16IdxPciDev],
+ u16TotalPciDev,
+ u16IdxPciDev,
+ apisrNetProc[u16IdxPciDev],
+ pciDevice3119.awBusDevFunID[ii]
+ );
+ }
+
+ for (ii = 0; ii < pciDevice3286.wDeviceNum; ii++, u16IdxPciDev++) {
+ s_vInit(
+ &sg_aGAdapter[u16IdxPciDev],
+ u16TotalPciDev,
+ u16IdxPciDev,
+ apisrNetProc[u16IdxPciDev],
+ pciDevice3286.awBusDevFunID[ii]
+ );
+ }
+
+ return u16TotalPciDev;
+}
+
+/*
+ * Description:
+ *
+ * Parameters:
+ * In:
+ * bySlotNum - specify which slot number to init,
+ * 0xFF means the first one adapter to init.
+ * Out:
+ * pAdapter - pointer of adapter which initialized,
+ * return NULL if init failed.
+ *
+ * Return Value: TRUE if succeeded; FALSE if failed.
+ *
+ */
+BOOL GADPbInitOne(U8 bySlotNum, PSAdapterInfo *ppAdapter)
+{
+ PISR apisrNetProc[MAX_NET_DEVICE] = {
+ (PISR)ISRvIsrForNetwork_Card0,
+ (PISR)ISRvIsrForNetwork_Card1
+ };
+
+ SPciDevice pciDevice3119;
+ /* SPciDevice pciDevice3286; */
+
+ int ii;
+ U16 u16IdxPciDev;
+ U16 u16TotalPciDev;
+
+ *ppAdapter = NULL;
+
+ /* read pci info */
+ NPCIbReadDeviceInfo(NULL, W_VENDOR_ID, W_DEVICE_ID_3119A, &pciDevice3119);
+ /* NPCIbReadDeviceInfo(NULL, W_VENDOR_ID, 0x3286, &pciDevice3286); */
+
+ u16TotalPciDev = (U16)(pciDevice3119.wDeviceNum);
+
+ /* if no adapter */
+ if (u16TotalPciDev == 0)
+ return FALSE;
+
+ sg_aGAdapter = (PSAdapterInfo) malloc(sizeof(SAdapterInfo));
+ if (sg_aGAdapter == NULL) {
+ printf("Memory allocation error %s, %d\n", __FILE__, __LINE__);
+ return FALSE;
+ /* exit(0); */
+ }
+
+ memset(sg_aGAdapter, 0, sizeof(SAdapterInfo));
+
+ /* init first one adapter */
+ if (bySlotNum == 0xFF) {
+ s_vInit(&sg_aGAdapter[0], u16TotalPciDev, 0,
+ apisrNetProc[0], pciDevice3119.awBusDevFunID[0]);
+ *ppAdapter = &sg_aGAdapter[0];
+ return TRUE;
+ } else {
+ /* init adapter by slot number specified */
+ u16IdxPciDev = 0;
+ for (ii = 0; ii < pciDevice3119.wDeviceNum; ii++, u16IdxPciDev++) {
+ if (bySlotNum == GET_DEVID(pciDevice3119.awBusDevFunID[ii])) {
+ s_vInit(
+ &sg_aGAdapter[u16IdxPciDev],
+ u16TotalPciDev,
+ u16IdxPciDev,
+ apisrNetProc[u16IdxPciDev],
+ pciDevice3119.awBusDevFunID[ii]
+ );
+ *ppAdapter = &sg_aGAdapter[u16IdxPciDev];
+ return TRUE;
+ }
+ }
+ }
+
+ return FALSE;
+}
+
+static BOOL s_bDynaAllocBuf(PSAdapterInfo pAdapter)
+{
+ int i;
+
+ /* Allocate RD pointer array */
+ pAdapter->apRD = (PSRxDesc *)malloc(sizeof(PSRxDesc)*pAdapter->cbRD);
+
+ if (pAdapter->apRD == NULL)
+ return FALSE;
+
+ /* Allocate TD pointer array & DescBuf SAllocMap array for every TD ring. */
+ /* we allocate 7 SAllocMap for 7 data buffer pool. */
+ for (i = 0; i < CB_TD_RING_NUM; i++) {
+ pAdapter->aapTD[i] = (PSTxDesc *)malloc(sizeof(PSTxDesc)*pAdapter->cbTD);
+ pAdapter->aaamTxDescBufPool[i] = (PSAllocMap)malloc(sizeof(SAllocMap)*CB_MAX_SEG_PER_PKT);
+
+ if ((pAdapter->aapTD[i] == NULL) || (pAdapter->aaamTxDescBufPool[i] == NULL))
+ return FALSE;
+
+ memset(pAdapter->aaamTxDescBufPool[i], 0, sizeof(SAllocMap)*CB_MAX_SEG_PER_PKT);
+ }
+
+ return TRUE;
+}
+
+/* Init pAdapter data structure */
+static void s_vInit(
+ PSAdapterInfo pAdapter,
+ UINT uTotalNum,
+ UINT uIdx,
+ PISR pisrNetIsr,
+ WORD wBusDevFunID
+)
+{
+ /* allocate new buffer dynamically. */
+ pAdapter->cbTotalAdapterNum = uTotalNum;
+ pAdapter->uAdapterIndex = uIdx;
+ pAdapter->pisrAdapterIsr = pisrNetIsr;
+
+ /* Save Memory Mapped IO base address */
+ switch (uIdx) {
+ case 0:
+ pAdapter->dwIoBase = BA_MAC0;
+ break;
+
+ case 1:
+ pAdapter->dwIoBase = BA_MAC1;
+ break;
+
+ default:
+ break;
+ }
+
+ /* Get Device ID */
+ VPCIvReadW(pAdapter->dwIoBase, PCI_REG_DEVICE_ID, &pAdapter->wDeviceId);
+ /* MacDump( MACDBG_INFO, ("Device ID:%04X\n", pAdapter->wDevId)); */
+
+ /* Get Revision ID */
+ VPCIvReadB(pAdapter->dwIoBase, PCI_REG_REV_ID, &pAdapter->byRevId);
+ /* MacDump( MACDBG_INFO, ("Revision ID:%02X\n", pAdapter->byRevId)); */
+
+ /* Save IRQ number */
+ switch (uIdx) {
+ case 0:
+ pAdapter->byIrqLevel = IRQ_ETH0;
+ break;
+
+ case 1:
+ pAdapter->byIrqLevel = IRQ_ETH0;
+ break;
+
+ default:
+ break;
+ }
+
+ if (sOptions.byRevId != 0)
+ pAdapter->byRevId = sOptions.byRevId;
+
+ pAdapter->cbRD = (sOptions.iRDescNum) ? sOptions.iRDescNum : CB_INIT_RD_NUM;
+ pAdapter->cbTD = (sOptions.iTDescNum) ? sOptions.iTDescNum : CB_INIT_TD_NUM;
+
+ VPCIvReadD(pAdapter->dwIoBase, PCI_REG_EXP_ROM_BAR, &pAdapter->dwBootRomBase);
+
+ /* PCIvReadConfigB(NULL, pAdapter->wBusDevFunID, PCI_REG_INT_LINE, &pAdapter->byIrqLevel); */
+ /* PCIvReadConfigD(NULL, pAdapter->wBusDevFunID, PCI_REG_EXP_ROM_BAR, &pAdapter->dwBootRomBase); */
+
+ pAdapter->byIntNum = (BYTE)((pAdapter->byIrqLevel <= 7) ?
+ (pAdapter->byIrqLevel + 0x08) : (pAdapter->byIrqLevel + 0x68));
+
+ /* Get the offset of PM Capability and save it */
+ VPCIvReadB(pAdapter->dwIoBase, PCI_REG_CAP, &pAdapter->byPMRegOffset);
+
+ /* Get Boot ROM Size */
+ pAdapter->byBootRomSize = GMACbyGetBootRomSize(pAdapter->dwIoBase);
+
+ /* Get PHY ID */
+ pAdapter->byPhyId = GMACbyGetPhyId(pAdapter->dwIoBase);
+
+ /* get Ethernet address and the string */
+ MACvReadEtherAddress(pAdapter->dwIoBase, pAdapter->abyEtherAddr);
+ CVTvBy6ToStr12(pAdapter->abyEtherAddr, pAdapter->aszEtherAddrStr);
+
+ /*
+ * INIT VALUE
+ */
+ /* allocate RD/TD poiter array & DescBuf array data structure */
+ if (!s_bDynaAllocBuf(pAdapter)) {
+ printf("s_bDynaAllocBuf() can'nt allocate buffer");
+ freemem();
+ return ;
+ }
+ /* for TD/RD alignment */
+ pAdapter->dwCacheLineSize = sizeof(DWORD) * 16; /* 64 bytes */
+
+ /* init pAdapter->bSharedIrqSupport */
+ pAdapter->bSharedIrqSupport = TRUE;
+
+ /* set connection type to MEDIA_AUTO by default */
+ pAdapter->uConnectionType = MEDIA_AUTO;
+
+ /* init default data segment number per packet in monitor mode */
+ pAdapter->uTxDataSegsPerPacket = CB_MIN_SEG_PER_PKT;
+
+ /* init default Tx packet size */
+ pAdapter->uTxPktSize = MAX_PACKET_LEN;/* MIN_PACKET_LEN + 4; */
+ pAdapter->cbPktSize = MAX_PACKET_LEN;
+ /* init MIB2 counter */
+ strcpy(pAdapter->mibCounter.ifDescr, " Gigabit Ether");
+
+ pAdapter->mibCounter.ifType = ETHERNETCSMACD;
+ pAdapter->mibCounter.ifMtu = MAX_DATA_LEN;
+ MEMvCopy((PVOID)pAdapter->mibCounter.ifPhysAddress, (PVOID)pAdapter->abyEtherAddr, U_ETHER_ADDR_LEN);
+ pAdapter->mibCounter.ifAdminStatus = UP;
+
+ /* init RMON counter */
+ pAdapter->rmonCounter.etherStatsStatus = VALID;
+
+ /* background timer send as default */
+ pAdapter->bTxContFunTest = TRUE;
+
+ /* init packet driver */
+ pAdapter->wRcvTypeLen = 0;
+ pAdapter->pisrReceiver = NULL;
+}
+
+BOOL GADPbInitialize(PSAdapterInfo pAdapter)
+{
+ int i;
+ /* write-clear PME status bit */
+ BYTE byOrgData, byPMRegOffset;
+ /* fill default value */
+ GALCvSetDefaultRD(pAdapter);
+ GALCvSetDefaultTD(pAdapter, 0); /* initial first data segment */
+ /* init PCI */
+ /* NPCIvInitialize(NULL, pAdapter->wBusDevFunID, pAdapter->byRevId); */
+ VPCIvInitialize(pAdapter->dwIoBase, pAdapter->byRevId);
+
+ VPCIvReadB(pAdapter->dwIoBase, PCI_REG_CAP, &byPMRegOffset);
+ VPCIvReadB(pAdapter->dwIoBase, (BYTE)(byPMRegOffset + PM_PMCSR1), &byOrgData);
+ VPCIvWriteB(pAdapter->dwIoBase, (BYTE)(byPMRegOffset + PM_PMCSR1),
+ (BYTE)(PMCSR1_PME_STATUS | byOrgData));
+ /*
+ PCIvReadConfigB(NULL, pAdapter->wBusDevFunID, PCI_REG_CAP, &byPMRegOffset);
+ PCIvReadConfigB(NULL, pAdapter->wBusDevFunID, (BYTE)(byPMRegOffset + PM_PMCSR1), &byOrgData);
+ PCIvWriteConfigB(NULL, pAdapter->wBusDevFunID, (BYTE)(byPMRegOffset + PM_PMCSR1),
+ (BYTE)(PMCSR1_PME_STATUS | byOrgData));
+ */
+ if (!sOptions.bNoInit) {
+
+ /* init MAC */
+ GMACvInitialize(pAdapter, pAdapter->dwIoBase, pAdapter->byRevId);
+ /* set address filter to accept any packet */
+ /* 2009/4/20 remove it for tftp with checksum bad message */
+ /* GMACvSetPacketFilter(pAdapter->dwIoBase, PKT_TYPE_PROMISCUOUS); */
+
+ /* Eric */
+ /* Turn On RCR_SEP to receive CRC error packet */
+ MACvRegBitsOn(pAdapter->dwIoBase, MAC_REG_RCR, RCR_SEP);
+
+ /* detect PHY is from which company */
+ /* MIIvReadPhyCmrId(pAdapter->dwIoBase, pAdapter->byRevId, &pAdapter->dwPhyCmrId); */
+
+ if (sOptions.ulInitCmds & INIT_CMD_FORCE_PHYRST) {
+ /* if it's cicada PHY, force PHY reset to avoid 2-card test link fail */
+
+ if ((pAdapter->dwPhyCmrId & CID_REV_ID_MASK_OFF) == CID_CICADA_CIS8201 ||
+ (pAdapter->dwPhyCmrId & CID_REV_ID_MASK_OFF) == CID_CICADA_CIS3216I ||
+ (pAdapter->dwPhyCmrId & CID_REV_ID_MASK_OFF) == CID_CICADA_CIS3216I64) {
+ /* force PHY reset on */
+ MACvRegBitsOn(pAdapter->dwIoBase, MAC_REG_CR3_SET, CR3_FPHYRST);
+ /* delay 300ms */
+ GMACvTimer0MiniSDelay(pAdapter->dwIoBase, pAdapter->byRevId, 300);
+ /* force PHY reset off */
+ MACvRegBitsOn(pAdapter->dwIoBase, MAC_REG_CR3_CLR, CR3_FPHYRST);
+ /* delay 50ms */
+ GMACvTimer0MiniSDelay(pAdapter->dwIoBase, pAdapter->byRevId, 50);
+ } else if ((pAdapter->dwPhyCmrId & CID_REV_ID_MASK_OFF) == CID_ICPLAUS_IP1001) {
+ /* force PHY reset on */
+ MACvRegBitsOn(pAdapter->dwIoBase, MAC_REG_CR3_SET, CR3_FPHYRST);
+ /* delay 300ms */
+ GMACvTimer0MiniSDelay(pAdapter->dwIoBase, pAdapter->byRevId, 300);
+ /* force PHY reset off */
+ MACvRegBitsOn(pAdapter->dwIoBase, MAC_REG_CR3_CLR, CR3_FPHYRST);
+ /* delay 50ms */
+ GMACvTimer0MiniSDelay(pAdapter->dwIoBase, pAdapter->byRevId, 50);
+ } else {
+ /* force PHY reset on */
+ MACvRegBitsOn(pAdapter->dwIoBase, MAC_REG_CR3_SET, CR3_FPHYRST);
+ /* delay 300ms */
+ GMACvTimer0MiniSDelay(pAdapter->dwIoBase, pAdapter->byRevId, 300);
+ /* force PHY reset off */
+ MACvRegBitsOn(pAdapter->dwIoBase, MAC_REG_CR3_CLR, CR3_FPHYRST);
+ /* delay 50ms */
+ GMACvTimer0MiniSDelay(pAdapter->dwIoBase, pAdapter->byRevId, 50);
+ }
+ }
+
+ /* init MII */
+ GMIIvInitialize(pAdapter->dwIoBase, pAdapter->byRevId, pAdapter->dwPhyCmrId);
+
+ /* set media mode */
+ GCARDvSetLoopbackMode(pAdapter->dwIoBase, pAdapter->byRevId, CARD_LB_NONE);
+ GCARDvSetMediaLinkMode(pAdapter->dwIoBase, pAdapter->byRevId, pAdapter->uConnectionType);
+
+ /* set up flow-control, MIB counter, and tagging initials */
+ VNSvOutPortB(pAdapter->dwIoBase + MAC_REG_RBRDU, (BYTE)pAdapter->cbRD);
+
+ /* set MIB counter near full condition to 0x00C00000 */
+ MACvRegBitsOn(pAdapter->dwIoBase, MAC_REG_MIBCR, MIBCR_MIBHI);
+
+ GSTAvClearHWMIBCounter(pAdapter->dwIoBase);
+ GSTAvEnableHWMIBCounter(pAdapter->dwIoBase);
+
+ MACvRegBitsOff(pAdapter->dwIoBase, MAC_REG_MCFG0, MCFG0_PQEN);
+ }
+
+ /* set init rx/tx descriptor address into chip */
+ MACvSetDescBaseHi32(pAdapter->dwIoBase, 0UL);
+ MACvSetDbfBaseHi16(pAdapter->dwIoBase, 0U);
+ MACvSetRxDescBaseLo32(pAdapter->dwIoBase, pAdapter->amRxDescRing.dwPAddr);
+ MACvSetRqIndex(pAdapter->dwIoBase, 0);
+ MACvSetRqSize(pAdapter->dwIoBase, (WORD)(pAdapter->cbRD - 1));
+
+ for (i = 0; i < CB_TD_RING_NUM; i++) {
+ MACvSetTxDescBaseLo32(pAdapter->dwIoBase, pAdapter->aamTxDescRing[i].dwPAddr, i);
+ GMACvSetTqIndex(pAdapter->dwIoBase, (BYTE)i, 0);
+ }
+
+ MACvSetTqSize(pAdapter->dwIoBase, (WORD)(pAdapter->cbTD - 1));
+
+ /* set current rx/tx descriptor index to 0 */
+ pAdapter->uRxDequeDescIdx = 0;
+ for (i = 0; i < CB_TD_RING_NUM; i++) {
+ pAdapter->uTxEnqueDescIdx[i] = 0;
+ pAdapter->uTxDequeDescIdx[i] = 0;
+ }
+ pAdapter->idxRxPktStartDesc = 0;
+ /*
+ // Set Random VCAM
+
+ WORD wInitVID;
+ WORD wGetVID;
+ int ii;
+ for (i = 0; i < VCAMSIZE; i++) {
+ while (TRUE) {
+ wInitVID = (WORD)(rand() & 0x0FFF);
+
+ if (i > 0) {
+ for (ii = 0; ii < i; ii++) {
+ GMACvGetVCAM(pAdapter->dwIoBase, (BYTE)ii, &wGetVID);
+ if (wInitVID == wGetVID)
+ break;
+ }
+ if (i == ii)
+ break;
+ } else
+ break;
+ } // end while
+
+ GMACvSetVCAM(pAdapter->dwIoBase, (BYTE)i, wInitVID);
+ }
+ */
+ /* Set Random MCAM */
+ /*
+ BYTE abyInitMCAM[6];
+ BYTE abyGetMCAM[6];
+ UINT uMCamIdx;
+ for (i = 0; i < MCAMSIZE; i++) {
+ while (TRUE) {
+ // Gen One MCAM
+ for (uMCamIdx = 0; uMCamIdx < 6; uMCamIdx++)
+ abyInitMCAM[uMCamIdx] = (BYTE)rand();
+
+ if (i > 0) {
+ for (ii = 0; ii < i; ii++) {
+ GMACvGetMCAM(pAdapter->dwIoBase, (BYTE)ii, abyGetMCAM);
+ // If they are the same??
+ if ( (*(PDWORD)(abyInitMCAM) == *(PDWORD)(abyGetMCAM)) &&
+ (*(PWORD)(abyInitMCAM + 4) == *(PWORD)(abyGetMCAM + 4)) )
+ break;
+ }
+ if (i == ii)
+ break;
+ } else
+ break;
+ } // end while
+
+ GMACvSetMCAM(pAdapter->dwIoBase, (BYTE)i, abyInitMCAM);
+ }
+ */
+ return TRUE;
+}
+
+BOOL GADPbBind(PSAdapterInfo pAdapter)
+{
+ /* build RDR/TDR */
+ if (!GALCbAllocateRdrMemory(pAdapter))
+ return FALSE;
+
+ if (!GALCbAllocateTdrMemory(pAdapter))
+ return FALSE;
+
+ GALCvChainRdrMemory(pAdapter);
+ GALCvChainTdrMemory(pAdapter, 0); /* chain first data segment */
+
+ if (!GADPbInitialize(pAdapter))
+ return FALSE;
+
+ /* Hook Interrupt Service Routine on IRQ */
+ /* set_irq_handlers(pAdapter->byIrqLevel, pAdapter->pisrAdapterIsr); */
+
+ /* enable Interrupt Mask in PIC */
+ /* unmask_interrupt(pAdapter->byIrqLevel); */
+ /* must clear it */
+ MACvClearISR(pAdapter->dwIoBase, pAdapter->byRevId);
+ /* start ISR */
+ MACvIntEnable(pAdapter->dwIoBase, IMR_MASK_VALUE);
+
+ /* wait MAUTO to poll twice, then MIISR_LNKFL will */
+ /* be correct status */
+ PCAvDelayByIO(CB_DELAY_MII_STABLE * 2);
+
+ /* update link status */
+ GMACvTimer0MiniSDelay(pAdapter->dwIoBase, pAdapter->byRevId, 2000);
+ pAdapter->bLinkPass = GMACbIsCableLinkOk(pAdapter->dwIoBase);
+
+ if (pAdapter->bLinkPass) {
+ /* update duplex status */
+ /* NOTE.... here we don't call MIIbIsInFullDuplexMode(), because */
+ /* we won't turn on/off MAUTO */
+ pAdapter->bFullDuplex = GMACbIsInFullDuplexMode(pAdapter->dwIoBase);
+ /* update speed status */
+ pAdapter->bSpeed1G = GMACbIsIn1GMode(pAdapter->dwIoBase, pAdapter->byRevId);
+ pAdapter->bSpeed100M = GMACbIsIn100MMode(pAdapter->dwIoBase, pAdapter->byRevId);
+
+ /* set flow control capability according to PHYSR0 register */
+ if (GMIIbIsAutoNegotiationOn(pAdapter->dwIoBase, pAdapter->byRevId)) {
+ /* enable/disable RX flow control */
+ if (GMACbIsRegBitsOn(pAdapter->dwIoBase, MAC_REG_PHYSR0, PHYSR0_RXFLC))
+ VNSvOutPortB(pAdapter->dwIoBase + MAC_REG_CR2_SET, CR2_FDXRFCEN);
+ else
+ VNSvOutPortB(pAdapter->dwIoBase + MAC_REG_CR2_CLR, CR2_FDXRFCEN);
+
+ /* enable/disable TX flow control */
+ if (GMACbIsRegBitsOn(pAdapter->dwIoBase, MAC_REG_PHYSR0, PHYSR0_TXFLC))
+ VNSvOutPortB(pAdapter->dwIoBase + MAC_REG_CR2_SET, CR2_FDXTFCEN);
+ else
+ VNSvOutPortB(pAdapter->dwIoBase + MAC_REG_CR2_CLR, CR2_FDXTFCEN);
+ }
+
+ /* This is patch for VT3119A1 */
+ /* Use TCR_TB2BDIS to prevent 1c_Reset failure in helf-duplex mode */
+ /* Only use this in 10HD and 100HD */
+ if (pAdapter->byRevId < REV_ID_VT3216_A0) {
+ if (!pAdapter->bSpeed1G) {
+ if (pAdapter->bFullDuplex)
+ MACvRegBitsOff(pAdapter->dwIoBase, MAC_REG_TCR, TCR_TB2BDIS);
+ else
+ MACvRegBitsOn(pAdapter->dwIoBase, MAC_REG_TCR, TCR_TB2BDIS);
+ }
+ }
+
+ /* This is patch for VT3119/VT3216 */
+ /* Patch HW MIB TXSQEErr Bug, this should only function in 10HD */
+ if (pAdapter->byRevId < REV_ID_VT3284_A0) {
+ if ((!pAdapter->bSpeed1G) && (!pAdapter->bSpeed100M) && (!pAdapter->bFullDuplex)) {
+ /* Enable count TXSQEErr in 10HD */
+ MACvRegBitsOff(pAdapter->dwIoBase, MAC_REG_TESTCFG, 0x80);
+ } else {
+ /* Disable count TXSQEErr in 10FD, 100HD, 100FD, 1G */
+ MACvRegBitsOn(pAdapter->dwIoBase, MAC_REG_TESTCFG, 0x80);
+ }
+ }
+
+ }
+
+ /*pAdapter->pbyTmpBuff = (PBYTE)malloc(CB_MAX_BUF_SIZE);*/
+
+#if defined(_RUN_SCRIPT)
+ pAdapter->mempool = malloc(U_STACKSIZE);
+#endif
+
+ return TRUE;
+}
+
+BOOL GADPbShutdown(PSAdapterInfo pAdapter)
+{
+ /* stop chip */
+ if (!GMACbSafeStop(pAdapter->dwIoBase, pAdapter->byRevId))
+ return FALSE;
+
+ /* stop MAC INT */
+ MACvIntDisable(pAdapter->dwIoBase);
+
+ /* stop ISR */
+ /* mask_interrupt(pAdapter->byIrqLevel); */
+
+ /* disconnect irq and restore org ISR */
+ /* unset_irq_handlers(pAdapter->byIrqLevel); */
+
+ /* destroy RDR/TDR */
+ GALCvFreeRdrMemory(pAdapter);
+ GALCvFreeTdrMemory(pAdapter);
+
+ if (pAdapter->pbyTmpBuff != NULL) {
+ MEMvFree(pAdapter->pbyTmpBuff, CB_MAX_BUF_SIZE);
+ pAdapter->pbyTmpBuff = NULL;
+ }
+
+ return TRUE;
+}
diff --git a/cpu/arm920t/wmt/galloct.c b/cpu/arm920t/wmt/galloct.c
new file mode 100755
index 0000000..12ec543
--- /dev/null
+++ b/cpu/arm920t/wmt/galloct.c
@@ -0,0 +1,349 @@
+/*++
+Copyright (c) 2010 WonderMedia Technologies, Inc.
+
+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, see http://www.gnu.org/licenses/>.
+
+WonderMedia Technologies, Inc.
+10F, 529, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C.
+--*/
+
+#if !defined(__ALLOCT_H__)
+#include "alloct.h"
+#endif
+#if !defined(__MAC_H__)
+#include "mac.h"
+#endif
+
+/*--------------------- Static Definitions -------------------------*/
+
+/*--------------------- Static Classes ----------------------------*/
+
+/*--------------------- Static Variables --------------------------*/
+
+/*--------------------- Static Functions --------------------------*/
+
+static BOOL ALCbAllocateTdrBufferPool(PSAdapterInfo pAdapter, SAllocMap asMaps[], UINT cbTD, int iSegNo)
+{
+ /* asMaps[iSegNo].dwRawSize = CB_MAX_BUF_SIZE*cbTD + pAdapter->dwCacheLineSize; */
+ /* asMaps[iSegNo].dwSize = CB_MAX_BUF_SIZE*cbTD; */
+ asMaps[iSegNo].dwRawSize = MAX_PACKET_LEN*cbTD + pAdapter->dwCacheLineSize;
+ asMaps[iSegNo].dwSize = MAX_PACKET_LEN*cbTD;
+ GMEMvAllocateShared(&asMaps[iSegNo]);
+
+ if (asMaps[iSegNo].dwRawVAddr == 0)
+ return FALSE;
+
+ /* make data buf 4 dwords alignment for convenience */
+ /* MEMvAlign(&asMaps[iSegNo], 16); */
+
+ /* Tx buffers, make it byte-alignment */
+ if (asMaps[iSegNo].dwRawVAddr % 2 != 0) {
+ asMaps[iSegNo].dwVAddr = asMaps[iSegNo].dwRawVAddr + 1;
+ asMaps[iSegNo].dwPAddr = LODWORD(asMaps[iSegNo].qwRawPAddr) + 1;
+ } else {
+ asMaps[iSegNo].dwVAddr = asMaps[iSegNo].dwRawVAddr;
+ asMaps[iSegNo].dwPAddr = LODWORD(asMaps[iSegNo].qwRawPAddr);
+ }
+
+ return TRUE;
+}
+
+/*--------------------- Export Variables --------------------------*/
+PVOID
+GMEMvAllocate(
+ UINT uCount
+ )
+{
+ PVOID pvMemAddr;
+
+ pvMemAddr = g_pvGBufferIndex;
+ g_pvGBufferIndex += uCount;
+ return pvMemAddr;
+}
+VOID
+GMEMvAllocateShared(
+ PSAllocMap pamMem
+ )
+{
+ /* printf("pamMem->dwRawVAddr1 = %x\n",pamMem->dwRawVAddr); */
+ pamMem->dwRawVAddr = (DWORD)GMEMvAllocate((size_t)pamMem->dwRawSize * (size_t)sizeof(BYTE));
+ /* If allocation failed, virtual/phisical address == NULL */
+ if ((PVOID)pamMem->dwRawVAddr == NULL) {
+ LODWORD(pamMem->qwRawPAddr) = 0;
+ HIDWORD(pamMem->qwRawPAddr) = 0;
+ return;
+ }
+ /*
+ else {
+ memset((PVOID)pamMem->dwRawVAddr, 0, (size_t)pamMem->dwRawSize * (size_t)sizeof(BYTE));
+ }
+ */
+ LODWORD(pamMem->qwRawPAddr) = pamMem->dwRawVAddr;
+ HIDWORD(pamMem->qwRawPAddr) = 0;
+}
+
+BOOL GALCbAllocateRdrMemory(PSAdapterInfo pAdapter)
+{
+ /* Allocate the Receive Descriptor ring */
+ /* (Physically contiguous and non cached) */
+ pAdapter->amRxDescRing.dwRawSize = sizeof(SRxDesc) * pAdapter->cbRD + pAdapter->dwCacheLineSize;
+ pAdapter->amRxDescRing.dwSize = sizeof(SRxDesc) * pAdapter->cbRD;
+ GMEMvAllocateShared(&pAdapter->amRxDescRing);
+ if (pAdapter->amRxDescRing.dwRawVAddr == 0)
+ return FALSE;
+
+ /* descriptor MUST aligned by 16 dword */
+ MEMvAlign(&pAdapter->amRxDescRing, (UINT)pAdapter->dwCacheLineSize);
+ /* allocate contiguous data buffers for RD ring */
+ pAdapter->amRxDescBuf.dwRawSize = CB_MAX_BUF_SIZE*pAdapter->cbRD + pAdapter->dwCacheLineSize;
+ pAdapter->amRxDescBuf.dwSize = CB_MAX_BUF_SIZE*pAdapter->cbRD;
+
+ GMEMvAllocateShared(&pAdapter->amRxDescBuf);
+
+ if (pAdapter->amRxDescBuf.dwRawVAddr == 0)
+ return FALSE;
+
+ /* make data buf 4 dwords alignment for convenience */
+ MEMvAlign(&pAdapter->amRxDescBuf, 16);
+ /* MEMvAlign(&pAdapter->amRxDescBuf, 1); //byte alignment */
+
+ return TRUE;
+}
+
+BOOL GALCbAllocateTdSegMemory(PSAdapterInfo pAdapter, int iSegNo)
+{
+ int i;
+
+ /* for 4 TD rings */
+ for (i = 0; i < CB_TD_RING_NUM; i++) {
+ if (!ALCbAllocateTdrBufferPool(pAdapter, pAdapter->aaamTxDescBufPool[i],
+ pAdapter->cbTD, iSegNo))
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+BOOL GALCbAllocateTdrMemory(PSAdapterInfo pAdapter)
+{
+ int i;
+
+ /* for 3119 allocating 4 TD rings */
+ for (i = 0; i < CB_TD_RING_NUM; i++) {
+ /* Allocate the transmit descriptor ring */
+ /* (Physically contiguous and non cached) */
+ pAdapter->aamTxDescRing[i].dwRawSize =
+ sizeof(STxDesc) * pAdapter->cbTD + pAdapter->dwCacheLineSize;
+ pAdapter->aamTxDescRing[i].dwSize = sizeof(STxDesc) * pAdapter->cbTD;
+
+ GMEMvAllocateShared(&pAdapter->aamTxDescRing[i]);
+
+ if (pAdapter->aamTxDescRing[i].dwRawVAddr == 0)
+ return FALSE;
+
+ /* descriptor MUST aligned by 16 dword */
+ MEMvAlign(&pAdapter->aamTxDescRing[i], (UINT)pAdapter->dwCacheLineSize);
+
+ /* for 3119, only allocate first data segment buffer pool for each TD queue */
+ if (!GALCbAllocateTdSegMemory(pAdapter, 0))
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+void GALCvChainRdrMemory(PSAdapterInfo pAdapter)
+{
+ int ii;
+ PSRxDesc pRD;
+ DWORD dwBufPAddr;
+
+ /* initialize the receive descriptor poniter array and */
+ /* each individual receive descriptor */
+ pRD = (PSRxDesc)pAdapter->amRxDescRing.dwVAddr;
+ dwBufPAddr = pAdapter->amRxDescBuf.dwPAddr;
+
+ for (ii = 0; ii < pAdapter->cbRD; ii++) {
+ pAdapter->apRD[ii] = pRD;
+
+ /* init descriptor value */
+ pRD->m_rd0RD0.f1Owner = B_OWNED_BY_CHIP;
+ pRD->m_f15RxBufSize = (WORD)CB_MAX_BUF_SIZE;
+ pRD->m_wRxBufAddrHi = LOWORD(HIDWORD(pAdapter->amRxDescBuf.qwRawPAddr));
+ pRD->m_dwRxBufAddrLo = dwBufPAddr;
+ pRD->m_f1IntCtlEn = 1; /* enable RIC */
+
+ /* (PBYTE)pRD += sizeof(SRxDesc); */
+ pRD = (PSRxDesc)(pAdapter->amRxDescRing.dwVAddr + sizeof(SRxDesc)*(ii+1));
+ dwBufPAddr = pAdapter->amRxDescBuf.dwPAddr + CB_MAX_BUF_SIZE*(ii+1);
+ }
+}
+
+void dumprd(PSAdapterInfo pAdapter)
+{
+ return;
+}
+
+void GALCvChainTdrMemory(PSAdapterInfo pAdapter, int iSegNo)
+{
+ int i, ii;
+ PSTxDesc pTD;
+ /* DWORD dwBufPAddr; */
+
+ /* For VT3119 4 TDs */
+ /* Initialize the Transmit Descriptor pointer array & */
+ /* the tx desc ring */
+ for (i = 0; i < CB_TD_RING_NUM; i++) {
+ pTD = (PSTxDesc)pAdapter->aamTxDescRing[i].dwVAddr;
+ /* dwBufPAddr = pAdapter->aaamTxDescBufPool[i][iSegNo].dwPAddr; */
+
+ /* set tx descriptors owner to host(0) */
+ /* set TCPLS_SOF = 1, TCPLS_EOF = 1 (normal packet) */
+ for (ii = 0; ii < pAdapter->cbTD; ii++) {
+ pAdapter->aapTD[i][ii] = pTD;
+
+ /* init descriptor value */
+ /* init Owner & Que bit */
+ pTD->m_td0TD0.f1Owner = B_OWNED_BY_HOST;
+ pTD->m_asTxBufs[0].f1Que = B_TD_LIST_END;
+
+ pTD->m_td1TD1.byTCR0 = TCR0_TIC;
+
+ pTD->m_td0TD0.f14TxPktSize = MAX_PACKET_LEN;
+ pTD->m_td1TD1.f2TCPLS = 0x03;
+
+ /* set up data segment */
+ pTD->m_td1TD1.f4CMDZ = (BYTE)(iSegNo + 2);
+ pTD->m_asTxBufs[iSegNo].f14TxBufSize = MAX_PACKET_LEN;
+ pTD->m_asTxBufs[iSegNo].wTxBufAddrHi =
+ LOWORD(HIDWORD(pAdapter->aaamTxDescBufPool[i][iSegNo].qwRawPAddr));
+ /* pTD->m_asTxBufs[iSegNo].dwTxBufAddrLo =
+ pAdapter->aaamTxDescBufPool[i][iSegNo].dwPAddr + CB_MAX_BUF_SIZE*ii + (ii % 16); */
+ pTD->m_asTxBufs[iSegNo].dwTxBufAddrLo =
+ pAdapter->aaamTxDescBufPool[i][iSegNo].dwPAddr + MAX_PACKET_LEN*ii + (ii % 16);
+
+ /* (PBYTE)pTD += sizeof(STxDesc); */
+ pTD = (PSTxDesc)(pAdapter->aamTxDescRing[i].dwVAddr + sizeof(STxDesc)*(ii+1));
+ }
+ /* printf("addr0 = %x\n",pAdapter->aapTD[0][0]->m_asTxBufs[0].dwTxBufAddrLo); */
+ /* printf("addr1 = %x\n",pAdapter->aapTD[0][1]->m_asTxBufs[0].dwTxBufAddrLo); */
+ }
+
+ /* init adapter's sturcture also, init value = MAX_PACKET_LEN */
+ pAdapter->uTxPktSize = MAX_PACKET_LEN;
+
+}
+
+void dumptd(PSAdapterInfo pAdapter)
+{
+ int data;
+ int i;
+ int ii;
+ for (ii = 0; ii < 32; ii++) {
+ for (i = 0; i < 0x10; i += 4) {
+ VNSvInPortD(pAdapter->aamTxDescRing[0].dwVAddr+i+ii*sizeof(STxDesc), &data);
+ printf("TD %4x:%8x\n", i, data);
+ }
+ }
+ return;
+}
+
+void GALCvFreeRdrMemory(PSAdapterInfo pAdapter)
+{
+ /* Free the receive descriptor ring. */
+ if (pAdapter->amRxDescRing.dwRawVAddr != 0) {
+ MEMvFreeShared(&pAdapter->amRxDescRing);
+ pAdapter->amRxDescRing.dwRawVAddr = 0;
+ }
+
+ /* Free the Receive buffer pool */
+ if (pAdapter->amRxDescBuf.dwRawVAddr != 0) {
+ MEMvFreeShared(&pAdapter->amRxDescBuf);
+ pAdapter->amRxDescBuf.dwRawVAddr = 0;
+ }
+}
+
+void GALCvFreeTdrMemory(PSAdapterInfo pAdapter)
+{
+ int i, ii;
+
+ /* Free all TD Rings */
+ for (i = 0; i < CB_TD_RING_NUM; i++) {
+ if (pAdapter->aamTxDescRing[i].dwRawVAddr != 0) {
+ MEMvFreeShared(&pAdapter->aamTxDescRing[i]);
+ pAdapter->aamTxDescRing[i].dwRawVAddr = 0;
+ }
+ }
+
+ /* Free the Transmit Buffers */
+ for (i = 0; i < CB_TD_RING_NUM; i++) {
+ for (ii = 0; ii < CB_MAX_SEG_PER_PKT; ii++) {
+ if (pAdapter->aaamTxDescBufPool[i][ii].dwRawVAddr != 0) {
+ MEMvFreeShared(&pAdapter->aaamTxDescBufPool[i][ii]);
+ pAdapter->aaamTxDescBufPool[i][ii].dwRawVAddr = 0;
+ }
+ }
+ }
+}
+
+void GALCvFreeTdSegMemory(PSAdapterInfo pAdapter, int iSegNo)
+{
+ int i, ii;
+
+ PSTxDesc pTD;
+
+ /* Free the Transmit Buffers for one segment */
+ for (i = 0; i < CB_TD_RING_NUM; i++) {
+ pTD = (PSTxDesc)pAdapter->aamTxDescRing[i].dwVAddr;
+
+ if (pAdapter->aaamTxDescBufPool[i][iSegNo].dwRawVAddr != 0) {
+ MEMvFreeShared(&pAdapter->aaamTxDescBufPool[i][iSegNo]);
+ pAdapter->aaamTxDescBufPool[i][iSegNo].dwRawVAddr = 0;
+ }
+
+ for (ii = 0; ii < pAdapter->cbTD; ii++) {
+ pTD->m_asTxBufs[iSegNo].f14TxBufSize = 0;
+ pTD->m_asTxBufs[iSegNo].wTxBufAddrHi = 0;
+ pTD->m_asTxBufs[iSegNo].dwTxBufAddrLo = 0;
+ pTD = (PSTxDesc)(pAdapter->aamTxDescRing[i].dwVAddr + sizeof(STxDesc)*(ii+1));
+ }
+ }
+}
+
+void GALCvSetAllRdOwnerToMac(PSAdapterInfo pAdapter)
+{
+ int ii;
+
+ for (ii = pAdapter->cbRD - 1; ii >= 0; ii--)
+ pAdapter->apRD[ii]->m_rd0RD0.f1Owner = B_OWNED_BY_CHIP;
+}
+
+void GALCvSetAllTdOwnerToMac(PSAdapterInfo pAdapter)
+{
+ int i, ii;
+
+ for (i = 0; i < CB_TD_RING_NUM; i++)
+ for (ii = pAdapter->cbTD - 1; ii >= 0; ii--)
+ pAdapter->aapTD[i][ii]->m_td0TD0.f1Owner = B_OWNED_BY_CHIP;
+}
+
+void GALCvSetDefaultRD(PSAdapterInfo pAdapter)
+{
+ /* set init RD value */
+ GALCvChainRdrMemory(pAdapter);
+}
+
+void GALCvSetDefaultTD(PSAdapterInfo pAdapter, int iSegNo)
+{
+ /* set init TD value */
+ GALCvChainTdrMemory(pAdapter, iSegNo); /*chain first data segment */
+}
diff --git a/cpu/arm920t/wmt/gcard.c b/cpu/arm920t/wmt/gcard.c
new file mode 100755
index 0000000..08eeef0
--- /dev/null
+++ b/cpu/arm920t/wmt/gcard.c
@@ -0,0 +1,170 @@
+/*++
+Copyright (c) 2010 WonderMedia Technologies, Inc.
+
+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, see http://www.gnu.org/licenses/>.
+
+WonderMedia Technologies, Inc.
+10F, 529, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C.
+--*/
+
+/* For IO-IO */
+#if defined(__WATCOMC__)
+/* #include <conio.h> */
+#endif
+
+#if !defined(__UASSERT_H__)
+#include "uassert.h"
+#endif
+#if !defined(__TMACRO_H__)
+#include "tmacro.h"
+#endif
+#if !defined(__CARD_H__)
+#include "card.h"
+#endif
+#if !defined(__MAC_H__)
+#include "mac.h"
+#endif
+
+/*--------------------- Static Definitions -------------------------*/
+
+/*--------------------- Static Classes ----------------------------*/
+
+/*--------------------- Static Variables --------------------------*/
+
+/*--------------------- Static Functions --------------------------*/
+
+/*--------------------- Export Variables --------------------------*/
+
+/*--------------------- Export Functions --------------------------*/
+
+void GCARDvSetMediaLinkMode(DWORD dwIoBase, BYTE byRevId, UINT uConnectionType)
+{
+ DWORD dwData;
+
+ /* detect the the brand of PHY */
+ GMIIbReadEmbeded(dwIoBase, byRevId, MII_REG_PHYID2, (PWORD)&dwData);
+ GMIIbReadEmbeded(dwIoBase, byRevId, MII_REG_PHYID1, (PWORD)&dwData + 1);
+
+ if ((dwData & CID_REV_ID_MASK_OFF) == CID_CICADA_CIS8201 ||
+ (dwData & CID_REV_ID_MASK_OFF) == CID_CICADA_CIS3216I ||
+ (dwData & CID_REV_ID_MASK_OFF) == CID_CICADA_CIS3216I64) {
+ /* Patch VT3119/VT3216 speed polling bug of MII Full-Duplex mode */
+ if (uConnectionType == MEDIA_100M_FULL || uConnectionType == MEDIA_10M_FULL)
+ MIIvRegBitsOn(dwIoBase, byRevId, MII_REG_TCSR, TCSR_ECHODIS);
+ else
+ MIIvRegBitsOff(dwIoBase, byRevId, MII_REG_TCSR, TCSR_ECHODIS);
+ }
+
+ /* clear force MAC mode bit */
+ MACvRegBitsOff(dwIoBase, MAC_REG_CHIPGCR, CHIPGCR_FCMODE);
+
+ /* if connection type is AUTO */
+ if (uConnectionType == MEDIA_AUTO) {
+ MIIvRegBitsOn(dwIoBase, byRevId, MII_REG_ANAR, ANAR_100FD|ANAR_100|ANAR_10FD|ANAR_10);
+ MIIvRegBitsOn(dwIoBase, byRevId, MII_REG_GCR, GCR_1000FD|GCR_1000);
+ /* enable AUTO-NEGO mode */
+ MIIvSetAutoNegotiationOn(dwIoBase, byRevId);
+ } else {
+ /* Nway force */
+ WORD wANAR, wGTCR;
+
+ /* In forced mode, always turn-on MAC FCMODE */
+ MACvRegBitsOn(dwIoBase, MAC_REG_CHIPGCR, CHIPGCR_FCMODE);
+
+ MIIvSetAutoNegotiationOff(dwIoBase, byRevId);
+
+ GMIIbReadEmbeded(dwIoBase, byRevId, MII_REG_ANAR, &wANAR);
+ GMIIbReadEmbeded(dwIoBase, byRevId, MII_REG_GCR, &wGTCR);
+
+ wANAR &= (~(ANAR_100FD | ANAR_100 | ANAR_10FD | ANAR_10));
+ wGTCR &= (~(GCR_1000FD | GCR_1000));
+
+ switch (uConnectionType) {
+ case MEDIA_1G_FULL:
+ wGTCR |= GCR_1000FD;
+ /* Turn on the forced mode of MAC */
+ MACvRegBitsOn(dwIoBase, MAC_REG_CHIPGCR, CHIPGCR_FCGMII);
+ MACvRegBitsOn(dwIoBase, MAC_REG_CHIPGCR, CHIPGCR_FCFDX);
+ break;
+ case MEDIA_1G_HALF:
+ wGTCR |= GCR_1000;
+ /* Turn on the forced mode of MAC */
+ MACvRegBitsOn(dwIoBase, MAC_REG_CHIPGCR, CHIPGCR_FCGMII);
+ MACvRegBitsOff(dwIoBase, MAC_REG_CHIPGCR, CHIPGCR_FCFDX);
+ break;
+ case MEDIA_100M_FULL:
+ wANAR |= ANAR_100FD;
+ /* Turn on the forced mode of MAC */
+ MACvRegBitsOff(dwIoBase, MAC_REG_CHIPGCR, CHIPGCR_FCGMII);
+ MACvRegBitsOn(dwIoBase, MAC_REG_CHIPGCR, CHIPGCR_FCFDX);
+ break;
+ case MEDIA_100M_HALF:
+ wANAR |= ANAR_100;
+ /* Turn on the forced mode of MAC */
+ MACvRegBitsOff(dwIoBase, MAC_REG_CHIPGCR, CHIPGCR_FCGMII);
+ MACvRegBitsOff(dwIoBase, MAC_REG_CHIPGCR, CHIPGCR_FCFDX);
+ break;
+ case MEDIA_10M_FULL:
+ wANAR |= ANAR_10FD;
+ /* Turn on the forced mode of MAC */
+ MACvRegBitsOff(dwIoBase, MAC_REG_CHIPGCR, CHIPGCR_FCGMII);
+ MACvRegBitsOn(dwIoBase, MAC_REG_CHIPGCR, CHIPGCR_FCFDX);
+ break;
+ case MEDIA_10M_HALF:
+ wANAR |= ANAR_10;
+ /* Turn on the forced mode of MAC */
+ MACvRegBitsOff(dwIoBase, MAC_REG_CHIPGCR, CHIPGCR_FCGMII);
+ MACvRegBitsOff(dwIoBase, MAC_REG_CHIPGCR, CHIPGCR_FCFDX);
+ break;
+ default:
+ DBG_ASSERT(FALSE);
+ break;
+ }
+
+ GMIIbWriteEmbeded(dwIoBase, byRevId, MII_REG_ANAR, wANAR);
+ GMIIbWriteEmbeded(dwIoBase, byRevId, MII_REG_GCR, wGTCR);
+
+ /* enable AUTO-NEGO mode */
+ MIIvSetAutoNegotiationOn(dwIoBase, byRevId);
+
+ } /* end if */
+}
+
+void GCARDvSetLoopbackMode(DWORD dwIoBase, BYTE byRevId, WORD wLoopbackMode)
+{
+ switch (wLoopbackMode) {
+ case CARD_LB_NONE:
+ case CARD_LB_MAC:
+ case CARD_LB_MII:
+ break;
+ default:
+ DBG_ASSERT(FALSE);
+ break;
+ }
+
+ /* set MAC loopback */
+ GMACvSetLoopbackMode(dwIoBase, LOBYTE(wLoopbackMode));
+ /* set MII loopback */
+ GMIIvSetLoopbackMode(dwIoBase, byRevId, HIBYTE(wLoopbackMode));
+}
+
+BOOL GCARDbSoftwareReset(DWORD dwIoBase, BYTE byRevId)
+{
+ /* reset MAC */
+ if (!GMACbSafeSoftwareReset(dwIoBase, byRevId))
+ return FALSE;
+ /* reset PHY */
+ if (!GMIIbSafeSoftwareReset(dwIoBase, byRevId))
+ return FALSE;
+
+ return TRUE;
+}
diff --git a/cpu/arm920t/wmt/gisr.c b/cpu/arm920t/wmt/gisr.c
new file mode 100755
index 0000000..1543633
--- /dev/null
+++ b/cpu/arm920t/wmt/gisr.c
@@ -0,0 +1,779 @@
+/*++
+Copyright (c) 2010 WonderMedia Technologies, Inc.
+
+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, see http://www.gnu.org/licenses/>.
+
+WonderMedia Technologies, Inc.
+10F, 529, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C.
+--*/
+
+#if !defined(__TBIT_H__)
+#include "tbit.h"
+#endif
+#if !defined(__CARD_H__)
+#include "card.h"
+#endif
+#if !defined(__ADAPTER_H__)
+#include "adapter.h"
+#endif
+#if !defined(__ISR_H__)
+#include "gisr.h"
+#endif
+
+/*--------------------- Static Definitions -------------------------*/
+
+/*--------------------- Static Classes ----------------------------*/
+
+/*--------------------- Static Variables --------------------------*/
+
+/*--------------------- Static Functions --------------------------*/
+
+void static s_ISRvPacketReceive(PSAdapterInfo pAdapter);
+void static s_ISRvPacketTransmit(PSAdapterInfo pAdapter, BYTE byTxQue);
+/*--------------------- Export Variables --------------------------*/
+extern SAdapterOpts sOptions;
+/*--------------------- Export Functions --------------------------*/
+void ISRvIsrForNetwork_Card0(void)
+{
+ GISRvIsrForNetwork(&sg_aGAdapter[0]);
+}
+
+void ISRvIsrForNetwork_Card1(void)
+{
+ GISRvIsrForNetwork(&sg_aGAdapter[1]);
+}
+
+void ISRvIsrForNetwork_Card2(void)
+{
+ GISRvIsrForNetwork(&sg_aGAdapter[2]);
+}
+
+void ISRvIsrForNetwork_Card3(void)
+{
+ GISRvIsrForNetwork(&sg_aGAdapter[3]);
+}
+
+/*
+ * Description: This routine is called when MAC interrupt system
+ *
+ * NOTE : when into this routine something should be aware
+ * 1) interrupt has been disabled.
+ * 2) inside a critical section (time)
+ * 3) stack owned by unknown application
+ *
+ * Parameters:
+ *
+ */
+/* Note:In vpost, irq is not enanle after entering ISR ,so it is so called non-nest interrupt */
+void GISRvIsrForNetwork(PSAdapterInfo pAdapter)
+{
+ DWORD dwOrgIMR;
+ DWORD dwOrgISR;
+ WORD wOrgESR;
+
+ DWORD dwIoBase;
+ BYTE byIrqLevel;
+
+
+ /* led 1 */
+ VNSvOutPortD(0xD811005C, 1);
+ /* get IoBase address and IRQ level */
+ dwIoBase = pAdapter->dwIoBase;
+ byIrqLevel = pAdapter->byIrqLevel;
+
+ /* preserve original IMR value */
+ VNSvInPortD(dwIoBase + MAC_REG_IMR, &dwOrgIMR);
+
+ /* read current ISR */
+ MACvReadISR(dwIoBase, &dwOrgISR);
+
+ /* read RXE_SR, TXE_SR */
+ VNSvInPortW(dwIoBase + MAC_REG_TXE_SR, &wOrgESR);
+
+ /*
+ * (1). if this is not our device's IRQ, then call original ISR and exit.
+ * (2). if this is our device's IRQ, then handle it and exit.
+ * we do not call original ISR. Because if another device also invoke
+ * the IRQ at the same time, then the IRQ will be invoked again after
+ * we had exited this ISR routine.
+ */
+
+ /* if is not our device's interrupt, */
+ if ((dwOrgISR & dwOrgIMR) == 0)
+ return;
+
+ /* mask off IMR, prevent MAC's other interrupt to reentry */
+ MACvIntDisable(dwIoBase);
+
+ /* write 1s to clear TXESR and RXESR */
+ VNSvOutPortW(dwIoBase + MAC_REG_TXE_SR, wOrgESR);
+
+ /* write 1s to clear ISR active interrupts */
+ MACvWriteISR(dwIoBase, dwOrgISR);
+
+ /* prevent All 1's ISR */
+ if (dwOrgISR == 0xFFFFFFFFUL)
+ goto IntDone;
+
+ /* SERVICE RD/TD */
+ /* handle rx */
+ s_ISRvPacketReceive(pAdapter);
+ /* led 2 */
+ VNSvOutPortD(0xD811005C, 2);
+
+ /* handle tx */
+ s_ISRvPacketTransmit(pAdapter, 0);
+ /* led 3 */
+ VNSvOutPortD(0xD811005C, 4);
+
+ /* Must do this after doing rx/tx, cause ISR bit is slower */
+ /* than RD/TD write back */
+ /* update ISR counter */
+ GSTAvUpdateIsrStatCounter(&pAdapter->scStatistic, dwOrgISR, wOrgESR);
+
+ /* Read HWMIBCounter */
+ if (BITbIsBitOn(dwOrgISR, ISR_MIBFI))
+ GSTAvUpdateHWMIBCounter(pAdapter->dwIoBase, &pAdapter->sHWMibCounter);
+
+ /*
+ * ERROR HANDLING
+ */
+
+ /* if link change */
+ if (BITbIsBitOn(dwOrgISR, ISR_SRCI)) {
+ /* Enable MII Auto-Polling */
+ GMACvEnableMiiAutoPoll(dwIoBase);
+
+ /* check the cable link status */
+ /* link OK */
+ pAdapter->bLinkPass = GMACbIsCableLinkOk(dwIoBase);
+
+ if (pAdapter->bLinkPass) {
+ /* each time int invoked, this counter will plus 1 */
+ pAdapter->scStatistic.dwIntLinkUp++;
+
+ /* update duplex status */
+ pAdapter->bFullDuplex = GMACbIsInFullDuplexMode(pAdapter->dwIoBase);
+
+ /* update speed status */
+ pAdapter->bSpeed1G = GMACbIsIn1GMode(pAdapter->dwIoBase, pAdapter->byRevId);
+ pAdapter->bSpeed100M = GMACbIsIn100MMode(dwIoBase, pAdapter->byRevId);
+
+ /* set flow control capability according to PHYSR0 register */
+ if (GMIIbIsAutoNegotiationOn(pAdapter->dwIoBase, pAdapter->byRevId)) {
+ /* enable/disable RX flow control */
+ if (GMACbIsRegBitsOn(pAdapter->dwIoBase, MAC_REG_PHYSR0, PHYSR0_RXFLC))
+ VNSvOutPortB(pAdapter->dwIoBase + MAC_REG_CR2_SET, CR2_FDXRFCEN);
+ else
+ VNSvOutPortB(pAdapter->dwIoBase + MAC_REG_CR2_CLR, CR2_FDXRFCEN);
+
+ /* enable/disable TX flow control */
+ if (GMACbIsRegBitsOn(pAdapter->dwIoBase, MAC_REG_PHYSR0, PHYSR0_TXFLC))
+ VNSvOutPortB(pAdapter->dwIoBase + MAC_REG_CR2_SET, CR2_FDXTFCEN);
+ else
+ VNSvOutPortB(pAdapter->dwIoBase + MAC_REG_CR2_CLR, CR2_FDXTFCEN);
+ }
+
+ /* This is patch for VT3119A1 */
+ /* Use TCR_TB2BDIS to prevent 1c_Reset failure in helf-duplex mode */
+ /* Only use this in 10HD and 100HD */
+ if (pAdapter->byRevId < REV_ID_VT3216_A0) {
+ if (!pAdapter->bSpeed1G) {
+ if (pAdapter->bFullDuplex)
+ MACvRegBitsOff(pAdapter->dwIoBase, MAC_REG_TCR, TCR_TB2BDIS);
+ else
+ MACvRegBitsOn(pAdapter->dwIoBase, MAC_REG_TCR, TCR_TB2BDIS);
+ }
+ }
+
+ /* This is patch for VT3119/VT3216 */
+ /* Patch HW MIB TXSQEErr Bug, this should only function in 10HD */
+ if (pAdapter->byRevId < REV_ID_VT3284_A0) {
+ if ((!pAdapter->bSpeed1G) &&
+ (!pAdapter->bSpeed100M) &&
+ (!pAdapter->bFullDuplex)) {
+ /* Enable count TXSQEErr in 10HD */
+ MACvRegBitsOff(pAdapter->dwIoBase, MAC_REG_TESTCFG, 0x80);
+ } else {
+ /* Disable count TXSQEErr in 10FD, 100HD, 100FD, 1G */
+ MACvRegBitsOn(pAdapter->dwIoBase, MAC_REG_TESTCFG, 0x80);
+ }
+ }
+
+ } else {
+ /* link fail */
+ /* each time int invoked, this counter will plus 1 */
+ pAdapter->scStatistic.dwIntLinkDown++;
+ }
+ }
+
+ if (BITbIsBitOn(dwOrgISR, ISR_LSTEI)) {
+ /*
+ * if Rx no buffer error, don't do software reset
+ * 1. turn on owner bit in all Rx descriptor
+ * 2. point current Rx to first descriptor
+ * 3. Rx on
+ * 4. RX WAK
+ */
+ /*
+ for (ii = 0; ii < pAdapter->cbRD; ii++)
+ pAdapter->apRD[ii]->m_rd0RD0.f1Owner = 1;
+ MACvSetRxDescBaseLo32(pAdapter->dwIoBase, pAdapter->amRxDescRing.dwPAddr);
+ pAdapter->uRxDequeDescIdx = pAdapter->idxRxPktStartDesc = 0;
+ PCAvDelayByIO(200);
+ MACvRxOn(pAdapter->dwIoBase);
+ */
+ }
+
+ /* if Rx/Tx DMA stall */
+ if (BITbIsBitOn(dwOrgISR, ISR_RXSTLI)) {
+ /*
+ // TBD....
+ // rx off -> sw reset -> start
+ // reset the adapter
+ if (pAdapter->byRevId < REV_ID_VT3065_A)
+ MACbSafeSoftwareReset(pAdapter->dwIoBase, pAdapter->byRevId);
+ // rx was shutdowned, turn on rx
+ MACvRxOn(pAdapter->dwIoBase);
+ MACvTransmit(pAdapter->dwIoBase);
+ */
+ }
+
+ if (BITbIsBitOn(dwOrgISR, ISR_TXSTLI)) {
+ /*
+ if (BITbIsBitOn(ptdCurr->m_td0TD0.byTSR1, TSR1_TBUFF)) {
+ // chip may be shutdowned, so re-start it
+ MACvTxOn(pAdapter->dwIoBase);
+ MACvTxQueueWake(pAdapter->dwIoBase,(BYTE)(0x40>>byTxQue));
+ // re-assert TDMD
+ MACvTransmit(pAdapter->dwIoBase);
+ }
+ */
+ }
+
+ /* TXESR */
+ if (BITbIsBitOn((BYTE)(wOrgESR & 0x000F), TXESR_TDSTR))
+ pAdapter->bTxOn = FALSE;
+ if (BITbIsBitOn((BYTE)(wOrgESR & 0x000F), TXESR_TDRBS))
+ pAdapter->bTxOn = FALSE;
+ if (BITbIsBitOn((BYTE)(wOrgESR & 0x000F), TXESR_TDWBS))
+ pAdapter->bTxOn = FALSE;
+ if (BITbIsBitOn((BYTE)(wOrgESR & 0x000F), TXESR_TFDBS))
+ pAdapter->bTxOn = FALSE;
+
+ /* RXESR */
+ if (BITbIsBitOn((BYTE)((wOrgESR & 0x00F0) >> 8), RXESR_RDSTR))
+ ;
+ if (BITbIsBitOn((BYTE)((wOrgESR & 0x00F0) >> 8), RXESR_RDRBS))
+ ;
+ if (BITbIsBitOn((BYTE)((wOrgESR & 0x00F0) >> 8), RXESR_RDWBS))
+ ;
+ if (BITbIsBitOn((BYTE)((wOrgESR & 0x00F0) >> 8), RXESR_RFDBS))
+ ;
+
+IntDone:
+ /*
+ * disable CPU's int to prevent reentry: if next statement enable
+ * MAC's int, and MAC happen to invoke int will cause reentry,
+ * so disable CPU's int here, let RETI to enable CPU's int
+ */
+ /* PCAvIntDisable(); */
+
+ /* restore original IMR value */
+ MACvIntEnable(dwIoBase, dwOrgIMR);
+ /* led off */
+ VNSvOutPortD(0xD811005C, 0);
+}
+
+void static s_ISRvPacketReceive(PSAdapterInfo pAdapter)
+{
+ void (CALLBACK * pisrCallBack)(PSAdapterInfo, PBYTE, UINT);
+
+ UINT uCurrDescIdx;
+ PSRxDesc pCurrRD;
+ int ii;
+ UINT uu;
+
+ BYTE byRsr0, byRsr1;
+ UINT uRxFreeRD = 0;
+ UINT uRxFreeRDIdx = pAdapter->uRxDequeDescIdx;
+ UINT FrameSize;
+
+ DWORD dwRxFifoLength;
+ UINT FrameSizeWithCRC;
+
+ PBYTE pbyRxBufAddr ;
+ PBYTE pbyHwCRC32 ;
+ DWORD dwHwCRC32 ;
+ DWORD dwSwCRC32 ;
+
+ /* added by kevin to not upload to uper layer */
+ pisrCallBack = NULL;
+
+ if (pAdapter->byRevId >= REV_ID_VT3216_A0)
+ dwRxFifoLength = 48896; /* 48*1024 - 32*8 */
+ else
+ dwRxFifoLength = 32512; /* 32*1024 - 32*8 */
+
+ while (TRUE) {
+ uCurrDescIdx = pAdapter->uRxDequeDescIdx;
+ pCurrRD = pAdapter->apRD[uCurrDescIdx];
+ byRsr0 = pCurrRD->m_rd0RD0.byRSR0;
+ byRsr1 = pCurrRD->m_rd0RD0.byRSR1;
+ FrameSizeWithCRC = pCurrRD->m_rd0RD0.f14RMBC;
+
+ /* if the RD is owned by the chip, we are done. */
+ if (pCurrRD->m_rd0RD0.f1Owner == B_OWNED_BY_CHIP)
+ break;
+
+ /* expected both STP and EDP are zero as single RD receive case */
+ /* else it's multiple RD receive case */
+ /* [STP, EDP] = [0,0] single RD received */
+ /* [STP, EDP] = [1,0] first RD in multiple RD received */
+ /* [STP, EDP] = [1,1] middle RD in multiple RD received */
+ /* [STP, EDP] = [0,1] last RD in multiple RD received */
+ if (BITbIsBitOn(byRsr1, (RSR1_STP | RSR1_EDP))) {
+ /* Drop this RD, move to next RD */
+ uRxFreeRD++;
+ ADD_ONE_WITH_WRAP_AROUND(pAdapter->uRxDequeDescIdx, pAdapter->cbRD);
+
+ /* [1.14], Calculate Rx Fifo Address */
+ pAdapter->dwRxFifoAddr += FrameSizeWithCRC;
+ if (pAdapter->dwRxFifoAddr >= dwRxFifoLength)
+ pAdapter->dwRxFifoAddr -= dwRxFifoLength;
+
+ /* branch code to while(TRUE) */
+ continue;
+ }
+
+ /* increase handled rx counter */
+ pAdapter->iRxPktHandled++;
+
+ /* get the frame size */
+ FrameSize = pCurrRD->m_rd0RD0.f14RMBC;
+
+ /* DBG: Get hardware and software-generated CRC32 */
+ pbyRxBufAddr = (PBYTE)pAdapter->amRxDescBuf.dwVAddr + uCurrDescIdx*CB_MAX_BUF_SIZE;
+ pbyHwCRC32 = pbyRxBufAddr + (FrameSize-4);
+ dwHwCRC32 = *((PDWORD)pbyHwCRC32);
+ dwSwCRC32 = 0;
+
+ if (pAdapter->bSoftwareCheckCrc) {
+ /* TBD */
+ /* calculate crc by software */
+ PCAvIntDisable();
+ dwSwCRC32 = CRCdwGetCrc32(pbyRxBufAddr, FrameSize - 4);
+ PCAvIntEnable();
+ } /* end if (pAdapter->bSoftwareCheckCrc) */
+
+
+ /*
+ * handle this RD
+ */
+ /* update receive statistic counter */
+ GSTAvUpdateRDStatCounterEx(
+ &pAdapter->scStatistic,
+ pCurrRD,
+ pbyRxBufAddr,
+ FrameSize,
+ dwHwCRC32,
+ dwSwCRC32
+ );
+
+ if (pAdapter->bWhenRxDataErrOutPort0x80 && GMACbIsInLoopbackMode(pAdapter->dwIoBase)) {
+ if (dwHwCRC32 != dwSwCRC32) {
+ /* Stop TX if CRC32 inconsistent */
+ pAdapter->bTxOn = FALSE;
+ pAdapter->bShowLbPacketComp = TRUE;
+ }
+ }
+
+
+ /*
+ * RX ERROR
+ */
+ if (BITbIsBitOff(byRsr1, RSR1_RXOK)) {
+ if (BITbIsBitOn(byRsr0, RSR0_CRC) && pAdapter->bWhenRxCrcErrNoBuf) {
+ /* goto IPR_NoReleaseOwner; */
+ /* Stop RX */
+ GMACbSafeRxOff(pAdapter->dwIoBase, pAdapter->byRevId);
+ break;
+ }
+
+ /* Drop this RD, move to next RD */
+ uRxFreeRD++;
+ ADD_ONE_WITH_WRAP_AROUND(pAdapter->uRxDequeDescIdx, pAdapter->cbRD);
+
+ /* [1.16], Calculate Rx Fifo Address */
+ pAdapter->dwRxFifoAddr += FrameSizeWithCRC;
+ /*
+ if (pAdapter->dwRxFifoAddr >= pAdapter->dwRxFifoSize)
+ pAdapter->dwRxFifoAddr -= pAdapter->dwRxFifoSize;
+ */
+ if (pAdapter->dwRxFifoAddr >= dwRxFifoLength)
+ pAdapter->dwRxFifoAddr -= dwRxFifoLength;
+
+ /* branch code to while(TRUE) */
+ continue;
+ }
+
+
+ /*
+ * RX OK
+ */
+
+ /* for pingpong: copy buffer to upper layer buffer */
+ /*because we don't need,we mark the function */
+ /*
+ pisrCallBack = (void (CALLBACK *)(PSAdapterInfo, PBYTE, UINT))pAdapter->pisrPptReceiver;
+ if (pisrCallBack != NULL) {
+ (*pisrCallBack)(
+ pAdapter,
+ pbyRxBufAddr,
+ FrameSize
+ );
+ }
+ */
+
+ /* Release this RD */
+ uRxFreeRD++;
+ ADD_ONE_WITH_WRAP_AROUND(pAdapter->uRxDequeDescIdx, pAdapter->cbRD);
+
+ /* [1.16], Calculate Rx Fifo Address */
+ pAdapter->dwRxFifoAddr += FrameSizeWithCRC;
+ /*
+ if (pAdapter->dwRxFifoAddr >= pAdapter->dwRxFifoSize) {
+ pAdapter->dwRxFifoAddr -= pAdapter->dwRxFifoSize;
+ }
+ */
+ if (pAdapter->dwRxFifoAddr >= dwRxFifoLength)
+ pAdapter->dwRxFifoAddr -= dwRxFifoLength;
+ } /* end while (TRUE) */
+
+
+ /* batch append RD here (4X RDs appended each time) */
+ /* count the difference between uRxDequeDescIdx and uRxAppendDescIdx */
+ /* why we should release RD wit 4 multiple */
+ if ((pAdapter->cbToBeFreeRD + uRxFreeRD) >= 4) {
+ /* calculate the number of RD to be free, it must be 4X */
+ ii = (pAdapter->cbToBeFreeRD + uRxFreeRD) - ((pAdapter->cbToBeFreeRD + uRxFreeRD) % 4);
+ /* decrease the RD index */
+ SUB_ONE_WITH_WRAP_AROUND(uRxFreeRDIdx, pAdapter->cbRD);
+ /* calculate the end RD index to be free in this time */
+ ADD_N_WITH_WRAP_AROUND(uRxFreeRDIdx, (ii - pAdapter->cbToBeFreeRD), pAdapter->cbRD);
+
+ for (uu = 0; uu < ii; uu++) {
+ pAdapter->apRD[uRxFreeRDIdx]->m_rd0RD0.f1Owner = B_OWNED_BY_CHIP;
+ SUB_ONE_WITH_WRAP_AROUND(uRxFreeRDIdx, pAdapter->cbRD);
+ }
+
+ /* update RXRDU in FlowCR0 */
+ VNSvOutPortB(pAdapter->dwIoBase + MAC_REG_RBRDU, (BYTE)ii);
+
+ /* calculate to-be-free RD for next time */
+ pAdapter->cbToBeFreeRD = (pAdapter->cbToBeFreeRD + uRxFreeRD) % 4;
+ } else {
+ /* calculate to-be-free RD for next time */
+ pAdapter->cbToBeFreeRD += uRxFreeRD;
+ }
+}
+
+void static s_ISRvPacketTransmit(PSAdapterInfo pAdapter, BYTE byTxQue)
+{
+ PSTxDesc ptdCurr;
+ int ii;
+ WORD wPktSize;
+ BOOL bIsTxISR = FALSE;
+ UINT uCurrTdIdx;
+
+ DWORD dwTxFifoLength;
+ PBYTE pbyBuffer;
+
+ if (pAdapter->byRevId >= REV_ID_VT3216_A0)
+ dwTxFifoLength = 16384; /* 16*1024 */
+ else
+ dwTxFifoLength = 10240; /* 10*1024 */
+
+ while (TRUE) {
+ uCurrTdIdx = pAdapter->uTxDequeDescIdx[byTxQue];
+ ptdCurr = pAdapter->aapTD[byTxQue][uCurrTdIdx];
+
+ /* If the ring is empty or the current descriptor */
+ /* is not owned by the system, we are done. */
+ if (ptdCurr->m_td0TD0.f1Owner == B_OWNED_BY_CHIP)
+ break;
+
+ if (pAdapter->auTxPktPosted[byTxQue] == 0)
+ break;
+
+ /* it's Interrupt for Tx */
+ bIsTxISR = TRUE;
+
+ /* if there is a number limit to tx */
+ /* pAdapter->lTxPacketNum==0 means, tx number is un-limited */
+ if (pAdapter->lTxPacketNum != 0) {
+ /* decrease lTxPacketNumShadow */
+ pAdapter->lTxPacketNumShadow--;
+
+ /* if exceed the tx number */
+ if (pAdapter->lTxPacketNumShadow == 0)
+ pAdapter->bTxOn = FALSE;
+ }
+
+ /* calculate the total buffer size */
+ wPktSize = 0;
+ for (ii = 0; ii < ptdCurr->m_td1TD1.f4CMDZ - 1; ii++)
+ wPktSize += ptdCurr->m_asTxBufs[ii].f14TxBufSize;
+
+ /*
+ * handle this TD
+ */
+
+ /* update transmit statistic counter */
+ GSTAvUpdateTDStatCounterEx(
+ &pAdapter->ascStatistic[byTxQue],
+ &pAdapter->mibCounter,
+ ptdCurr,
+ (PBYTE)(pAdapter->aapTD[byTxQue][uCurrTdIdx]->m_asTxBufs[0].dwTxBufAddrLo),
+ /* wPktSize */
+ ptdCurr->m_asTxBufs[0].f14TxBufSize + ptdCurr->m_asTxBufs[1].f14TxBufSize +
+ ptdCurr->m_asTxBufs[2].f14TxBufSize + ptdCurr->m_asTxBufs[3].f14TxBufSize +
+ ptdCurr->m_asTxBufs[4].f14TxBufSize + ptdCurr->m_asTxBufs[5].f14TxBufSize +
+ ptdCurr->m_asTxBufs[6].f14TxBufSize
+ );
+
+ if (byTxQue == 0) { /* default TD queue */
+ GSTAvUpdateTDStatCounterTq0(
+ &pAdapter->scStatistic, /* for diag tool counter display */
+ ptdCurr,
+ (PBYTE)(pAdapter->aapTD[byTxQue][uCurrTdIdx]->m_asTxBufs[0].dwTxBufAddrLo),
+ /* wPktSize */
+ ptdCurr->m_asTxBufs[0].f14TxBufSize + ptdCurr->m_asTxBufs[1].f14TxBufSize +
+ ptdCurr->m_asTxBufs[2].f14TxBufSize + ptdCurr->m_asTxBufs[3].f14TxBufSize +
+ ptdCurr->m_asTxBufs[4].f14TxBufSize + ptdCurr->m_asTxBufs[5].f14TxBufSize +
+ ptdCurr->m_asTxBufs[6].f14TxBufSize
+ );
+ }
+
+ /*
+ * TX OK
+ */
+ if (BITbIsBitOff(ptdCurr->m_td0TD0.byTSR1, TSR1_TERR)) {
+ /* decrease posted tx packet counter */
+ pAdapter->auTxPktPosted[byTxQue]--;
+ } else {
+ /*
+ * TX ERROR HANDLING
+ */
+
+ if (pAdapter->bWhenTxErrOutPort0x80) {
+ PCBvOutPortB(0x80, 0xAA);
+ /* PCBvOutPortB(0x80, 0x00); */
+
+ pAdapter->bTxOn = FALSE;
+ }
+
+ /* (1). tx abort */
+
+ /* tx abort don't do retry */
+ if (BITbIsBitOn(ptdCurr->m_td0TD0.byTSR0, TSR0_ABT)) {
+ /* chip may be shutdowned, so re-start it */
+ MACvTxOn(pAdapter->dwIoBase);
+ MACvTxQueueRUN(pAdapter->dwIoBase, byTxQue);
+ MACvTxQueueWake(pAdapter->dwIoBase, byTxQue);
+ }
+
+ /* decrease posted tx packet counter */
+ pAdapter->auTxPktPosted[byTxQue]--;
+ } /* end Tx error handling */
+
+ /* clear td status */
+ ptdCurr->m_td0TD0.byTSR0 = 0;
+ ptdCurr->m_td0TD0.byTSR1 = 0;
+ /* VT3119A1 must clear Quebit, MAC doesn't write back QueBit */
+ ptdCurr->m_asTxBufs[0].f1Que = 0;
+
+ /* move DequeTdIdx to next */
+ pAdapter->uTxDequeDescIdx[byTxQue] = (uCurrTdIdx + 1) % pAdapter->cbTD;
+
+ /* [1.14], Calculate Tx Fifo Address */
+ pAdapter->dwTxFifoAddr[byTxQue] += (
+ 8 + ptdCurr->m_asTxBufs[0].f14TxBufSize + ptdCurr->m_asTxBufs[1].f14TxBufSize +
+ ptdCurr->m_asTxBufs[2].f14TxBufSize + ptdCurr->m_asTxBufs[3].f14TxBufSize +
+ ptdCurr->m_asTxBufs[4].f14TxBufSize + ptdCurr->m_asTxBufs[5].f14TxBufSize +
+ ptdCurr->m_asTxBufs[6].f14TxBufSize
+ );
+
+ if (pAdapter->dwTxFifoAddr[byTxQue] >= dwTxFifoLength)
+ pAdapter->dwTxFifoAddr[byTxQue] -= dwTxFifoLength;
+
+ /* for specific purpose we add owner bit automatically */
+ if (pAdapter->bTxContPerfTest &&
+ pAdapter->bTxOn &&
+ !pAdapter->bTxSinglePacket) {
+
+ /* Set this TD */
+ UINT uTxPktSize;
+ if (pAdapter->bRandomPktLength) {
+ /* TBD */
+ UINT uRandomPktSize = MAX_PACKET_LEN ; /* RANDOM(MAX_PACKET_LEN) + 1; */
+
+ /* ??? */
+ /* In loopback test, hardware wouldn't generate 4-byte CRC,
+ * software make the minumum TX buffer size to be 64 bytes
+ * to avoid generating runt packet
+ */
+ /*
+ if (uRandomPktSize < (MIN_PACKET_LEN + 4)) {
+ // TBD.... + CRC 4 bytes
+ uRandomPktSize = MIN_PACKET_LEN + 4;
+ }
+ */
+ if (pAdapter->bSoftwareGenCrc) {
+ if (uRandomPktSize < (MIN_PACKET_LEN + 4))
+ uRandomPktSize = MIN_PACKET_LEN + 4;
+ } else {
+ if (uRandomPktSize < MIN_PACKET_LEN)
+ uRandomPktSize = MIN_PACKET_LEN;
+ }
+ /*
+ if (uRandomPktSize > MAX_PACKET_LEN) {
+ uRandomPktSize = MAX_PACKET_LEN;
+ }
+ */
+ uTxPktSize = uRandomPktSize;
+ } else if (pAdapter->bIncPktLength) {
+ uTxPktSize = pAdapter->uTxPktSize;
+
+ /* increase packet length */
+ pAdapter->uTxPktSize++;
+ if (pAdapter->bSoftwareGenCrc) {
+ if (pAdapter->uTxPktSize > (MAX_PACKET_LEN + 4))
+ pAdapter->uTxPktSize = MIN_PACKET_LEN + 4;
+ } else {
+ if (pAdapter->uTxPktSize > MAX_PACKET_LEN)
+ pAdapter->uTxPktSize = MIN_PACKET_LEN;
+ }
+ } else
+ uTxPktSize = pAdapter->cbPktSize;
+
+ /* [1.12] */
+ pbyBuffer = (PBYTE)(ptdCurr->m_asTxBufs[0].dwTxBufAddrLo);
+
+ if (pAdapter->bRandomPktData) {
+ UINT kk;
+ UINT uPosition;
+
+ /* RANDOM DATA */
+ /* Get random position in Random Table */
+ /* TBD */
+ uPosition = 3072 - uTxPktSize;/* RANDOM((3072 - uTxPktSize)); */
+ for (kk = 0; kk < uTxPktSize; kk++)
+ *(pbyBuffer + kk) = *((PBYTE)sg_abyRandomTable + uPosition + kk);
+ }
+
+ if (pAdapter->bSoftwareGenCrc) {
+ PDWORD pdwCRC = (PDWORD)(pbyBuffer + uTxPktSize - 4);
+ DWORD dwCRC;
+ PCAvIntDisable();
+ dwCRC = CRCdwGetCrc32(pbyBuffer, uTxPktSize - 4);
+ *pdwCRC = dwCRC;
+ PCAvIntEnable();
+ }
+
+ ptdCurr->m_td0TD0.f14TxPktSize = (WORD)uTxPktSize;
+
+ /* Calculate each segment's buffer size */
+ UINT uSegNum;
+ UINT i;
+ if (pAdapter->bRandDatSegsPerPacket) {
+ /* TBD */
+ uSegNum = CB_MAX_SEG_PER_PKT+1 ;/* RANDOM(CB_MAX_SEG_PER_PKT) + 1; */
+ } else
+ uSegNum = pAdapter->uTxDataSegsPerPacket;
+
+ if (uSegNum > 1) {
+ WORD wTempBufSize;
+
+ /* The BufLen of first Buf is 14 */
+ ptdCurr->m_asTxBufs[0].f14TxBufSize = 14;
+
+ /* The rest */
+ /* Equal the buffer length */
+ wTempBufSize = (WORD)((uTxPktSize - 14) / (uSegNum - 1));
+ for (i = 1; i < uSegNum; i++) {
+ if (i == (uSegNum - 1)) {
+ ptdCurr->m_asTxBufs[i].f14TxBufSize =
+ (WORD)((uTxPktSize - 14) -
+ (wTempBufSize*(uSegNum - 2)));
+ } else
+ ptdCurr->m_asTxBufs[i].f14TxBufSize = wTempBufSize;
+ ptdCurr->m_asTxBufs[i].dwTxBufAddrLo =
+ ptdCurr->m_asTxBufs[i-1].dwTxBufAddrLo +
+ ptdCurr->m_asTxBufs[i-1].f14TxBufSize;
+ } /* end for */
+
+ for ( ; i < CB_MAX_SEG_PER_PKT; i++) {
+ ptdCurr->m_asTxBufs[i].f14TxBufSize = 0;
+ ptdCurr->m_asTxBufs[i].dwTxBufAddrLo = 0;
+ }
+ } else {
+ /* uSegNum = 1 */
+ /* only one descriptor; it occupies the whole packet size */
+ ptdCurr->m_asTxBufs[0].f14TxBufSize = (WORD)uTxPktSize;
+ for (i = 1; i < CB_MAX_SEG_PER_PKT; i++) {
+ ptdCurr->m_asTxBufs[i].f14TxBufSize = 0;
+ ptdCurr->m_asTxBufs[i].dwTxBufAddrLo = 0;
+ }
+ } /* end if (uSegNum > 1) */
+ ptdCurr->m_td1TD1.f4CMDZ = (BYTE)(uSegNum + 1);
+ ptdCurr->m_td0TD0.f1Owner = B_OWNED_BY_CHIP;
+
+ pAdapter->auTxPktPosted[byTxQue]++;
+
+ /* Get last TD Idx */
+ UINT uLastTdIdx = (uCurrTdIdx - 1 + pAdapter->cbTD) % pAdapter->cbTD;
+ if (pAdapter->aapTD[byTxQue][uLastTdIdx]->m_td0TD0.f1Owner == B_OWNED_BY_CHIP) {
+ /* VT3119A0 */
+ /* vSetBit((PDWORD)(pAdapter->aapTD[byTxQue][wLastTdIdx])); */
+ /* VT3119A1 */
+ pAdapter->aapTD[byTxQue][uLastTdIdx]->m_asTxBufs[0].f1Que = B_TD_LIST_NOT_END;
+ }
+ } /* end if */
+
+ } /* end while (TRUE) */
+
+ if (pAdapter->bTxContPerfTest &&
+ pAdapter->bTxOn &&
+ !pAdapter->bTxSinglePacket)
+ MACvTxQueueWake(pAdapter->dwIoBase, byTxQue);
+}
+
+VOID
+PCAvIntEnable(
+ void
+ )
+{
+ asm volatile ("MRS r0, CPSR\n");
+ asm volatile ("BIC r0, r0, #0x80\n");
+ asm volatile ("MSR CPSR_c, r0\n");
+}
+
+VOID
+PCAvIntDisable(
+ void
+ )
+{
+ asm volatile ("MRS r0, CPSR\n");
+ asm volatile ("ORR r0, r0, #0x80\n");
+ asm volatile ("MSR CPSR_c, r0\n");
+}
diff --git a/cpu/arm920t/wmt/gisr.h b/cpu/arm920t/wmt/gisr.h
new file mode 100755
index 0000000..23bbe43
--- /dev/null
+++ b/cpu/arm920t/wmt/gisr.h
@@ -0,0 +1,72 @@
+/*++
+Copyright (c) 2010 WonderMedia Technologies, Inc.
+
+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, see http://www.gnu.org/licenses/>.
+
+WonderMedia Technologies, Inc.
+10F, 529, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C.
+--*/
+
+
+#ifndef __GISR_H__
+#define __GISR_H__
+
+#if !defined(__TTYPE_H__)
+#include "ttype.h"
+#endif
+
+#if !defined(__ADAPTER_H__)
+#include "adapter.h"
+#endif
+
+/*--------------------- Export Definitions -------------------------*/
+
+/*--------------------- Export Classes ----------------------------*/
+
+/*--------------------- Export Variables --------------------------*/
+
+/*--------------------- Export Functions --------------------------*/
+#ifdef __cplusplus
+extern "C" { /* Assume C declarations for C++ */
+#endif /* __cplusplus */
+VOID
+PCAvIntEnable(
+ void
+ );
+
+VOID
+PCAvIntDisable(
+ void
+ );
+
+DWORD
+CRCdwGetCrc32(
+ PBYTE pbyData,
+ UINT cbByte
+);
+
+/* supports max 6 cards */
+void ISRvIsrForNetwork_Card0(void);
+void ISRvIsrForNetwork_Card1(void);
+void ISRvIsrForNetwork_Card2(void);
+void ISRvIsrForNetwork_Card3(void);
+
+
+/* interrupt service routine for adapter */
+void GISRvIsrForNetwork(PSAdapterInfo pAdapter);
+
+
+#if defined(__cplusplus)
+} /* End of extern "C" { */
+#endif /* __cplusplus */
+
+#endif /* __ISR_H__ */
diff --git a/cpu/arm920t/wmt/gmac.c b/cpu/arm920t/wmt/gmac.c
new file mode 100755
index 0000000..f7b1282
--- /dev/null
+++ b/cpu/arm920t/wmt/gmac.c
@@ -0,0 +1,1238 @@
+/*++
+Copyright (c) 2010 WonderMedia Technologies, Inc.
+
+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, see http://www.gnu.org/licenses/>.
+
+WonderMedia Technologies, Inc.
+10F, 529, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C.
+--*/
+
+#if !defined(__UASSERT_H__)
+#include "uassert.h"
+#endif
+#if !defined(__TBIT_H__)
+#include "tbit.h"
+#endif
+#if !defined(__MAC_H__)
+#include "mac.h"
+#endif
+#if !defined(_MACIF_H_)
+#include "macif.h"
+#endif
+
+/*--------------------- Static Definitions -------------------------*/
+#define CB_DELAY_NM9346 (10) /* 10ms */
+#define CB_DELAY_SOFT_RESET (50) /* 50ms */
+
+/*--------------------- Static Classes ----------------------------*/
+
+/*--------------------- Static Variables --------------------------*/
+
+/*--------------------- Static Functions --------------------------*/
+
+/*--------------------- Export Variables --------------------------*/
+
+/*--------------------- Export Functions --------------------------*/
+
+VOID GMACvReadAllRegs(DWORD dwIoBase, PSMacReg pMacRegs, BYTE byRevId)
+{
+ int ii;
+ PBYTE pbyData = (PBYTE)pMacRegs;
+
+ for (ii = 0; ii < MAC_REG_DEC_BASE_HI; ii++) {
+ VNSvInPortB(dwIoBase + ii, pbyData);
+ pbyData++;
+ }
+
+ for ( ; ii < MAC_REG_ISR_CTL; ii += sizeof(DWORD), pbyData += sizeof(DWORD))
+ VNSvInPortD(dwIoBase + ii, (PDWORD)pbyData);
+
+ for ( ; ii < MAC_REG_RDBASE_LO; ii++, pbyData++)
+ VNSvInPortB(dwIoBase + ii, pbyData);
+
+ for ( ; ii < MAC_REG_CAMADDR; ii += sizeof(DWORD), pbyData += sizeof(DWORD))
+ VNSvInPortD(dwIoBase + ii, (PDWORD)pbyData);
+
+ for ( ; ii < MAC_REG_MIBREAD; ii++, pbyData++)
+ VNSvInPortB(dwIoBase + ii, pbyData);
+
+ ii += 4;
+ pbyData += 4; /* skip MIB_READ_PORT, because it may have side effect. */
+
+ for ( ; ii < MAC_REG_WOLCR0_SET; ii++, pbyData++)
+ VNSvInPortB(dwIoBase + ii, pbyData);
+
+ for ( ; ii < MAC_REG_BYTEMSK3_3 + 4; ii += sizeof(DWORD), pbyData += sizeof(DWORD))
+ VNSvInPortD(dwIoBase + ii, (PDWORD)pbyData);
+
+ return;
+}
+
+BOOL GMACbIsRegBitsOn(DWORD dwIoBase, BYTE byRegOfs, BYTE byTestBits)
+{
+ BYTE byData;
+ VNSvInPortB(dwIoBase + byRegOfs, &byData);
+ return BITbIsAllBitsOn(byData, byTestBits);
+}
+
+BOOL GMACbIsRegBitsOff(DWORD dwIoBase, BYTE byRegOfs, BYTE byTestBits)
+{
+ BYTE byData;
+ VNSvInPortB(dwIoBase + byRegOfs, &byData);
+ return BITbIsAllBitsOff(byData, byTestBits);
+}
+
+BYTE GMACbyReadEECSR(DWORD dwIoBase)
+{
+ BYTE byData;
+
+ VNSvInPortB(dwIoBase + MAC_REG_EECSR, &byData);
+ /* PCAvDelayByIO(CB_DELAY_NM9346); */
+ return byData;
+}
+
+VOID GMACvWriteEECSR(DWORD dwIoBase, BYTE byValue)
+{
+ VNSvOutPortB(dwIoBase + MAC_REG_EECSR, byValue);
+ /* delay 1 ms using MAC hardware timer */
+ GMACvTimer0MiniSDelay(dwIoBase, REV_ID_VT3119_A0, 1);
+}
+
+/*
+void MACvWriteEECSR (DWORD dwIoBase, BYTE byValue)
+{
+ VNSvOutPortB(dwIoBase + MAC_REG_EECSR, byValue);
+ PCAvDelayByIO(CB_DELAY_NM9346);
+}
+*/
+
+BYTE GMACbyReadMIICR(DWORD dwIoBase)
+{
+ BYTE byData;
+
+ VNSvInPortB(dwIoBase + MAC_REG_MIICR, &byData);
+ return byData;
+}
+
+VOID GMACvWriteMIICR(DWORD dwIoBase, BYTE byValue)
+{
+ VNSvOutPortB(dwIoBase + MAC_REG_MIICR, byValue);
+}
+
+
+BYTE GMACbyReadMultiAddr(DWORD dwIoBase, UINT uByteIdx)
+{
+ BYTE byData;
+
+ VNSvInPortB(dwIoBase + MAC_REG_MAR + uByteIdx, &byData);
+ return byData;
+}
+
+
+VOID GMACvWriteMultiAddr(DWORD dwIoBase, UINT uByteIdx, BYTE byData)
+{
+ VNSvOutPortB(dwIoBase + MAC_REG_MAR + uByteIdx, byData);
+}
+
+
+BOOL GMACbIsIntDisable(DWORD dwIoBase, BYTE byRevId)
+{
+ DWORD dwData;
+
+ VNSvInPortD(dwIoBase + MAC_REG_IMR, &dwData);
+ if (dwData != 0x00000000UL)
+ return FALSE;
+
+ return TRUE;
+}
+
+/*
+ * Description: Set this hash index into multicast address register
+ * bit
+ *
+ * Parameters:
+ *
+ */
+VOID GMACvSetMultiAddrByHash(DWORD dwIoBase, BYTE byHashIdx)
+{
+ UINT uByteIdx;
+ BYTE byBitMask;
+ BYTE byOrgValue;
+ BYTE byOrgCAMCR, byData;
+
+ /* modify CAMCR to select MAR regs */
+ VNSvInPortB(dwIoBase + MAC_REG_CAMCR, &byOrgCAMCR);
+ byData = (BYTE)(byOrgCAMCR & ~(CAMCR_PS1|CAMCR_PS0));
+ VNSvOutPortB(dwIoBase + MAC_REG_CAMCR, byData);
+
+ /* calculate byte position */
+ uByteIdx = byHashIdx / 8;
+ DBG_ASSERT(uByteIdx < 8);
+ /* calculate bit position */
+ byBitMask = 1;
+ byBitMask <<= (byHashIdx % 8);
+ /* turn on the bit */
+ byOrgValue = GMACbyReadMultiAddr(dwIoBase, uByteIdx);
+ GMACvWriteMultiAddr(dwIoBase, uByteIdx, (BYTE)(byOrgValue | byBitMask));
+
+ /* restore to original CAMCR */
+ VNSvOutPortB(dwIoBase + MAC_REG_CAMCR, byOrgCAMCR);
+}
+
+/*
+ * Description: Reset this hash index into multicast address register
+ * bit
+ *
+ * Parameters:
+ *
+ */
+VOID GMACvResetMultiAddrByHash(DWORD dwIoBase, BYTE byHashIdx)
+{
+ UINT uByteIdx;
+ BYTE byBitMask;
+ BYTE byOrgValue;
+ BYTE byOrgCAMCR, byData;
+
+ /* modify CAMCR to select MAR regs */
+ VNSvInPortB(dwIoBase + MAC_REG_CAMCR, &byOrgCAMCR);
+ byData = (BYTE)(byOrgCAMCR & ~(CAMCR_PS1|CAMCR_PS0));
+ VNSvOutPortB(dwIoBase + MAC_REG_CAMCR, byData);
+
+ /* calculate byte position */
+ uByteIdx = byHashIdx / 8;
+ DBG_ASSERT(uByteIdx < 8);
+ /* calculate bit position */
+ byBitMask = 1;
+ byBitMask <<= (byHashIdx % 8);
+ /* turn off the bit */
+ byOrgValue = GMACbyReadMultiAddr(dwIoBase, uByteIdx);
+ GMACvWriteMultiAddr(dwIoBase, uByteIdx, (BYTE)(byOrgValue & (~byBitMask)));
+
+ /* restore to original CAMCR */
+ VNSvOutPortB(dwIoBase + MAC_REG_CAMCR, byOrgCAMCR);
+}
+
+BYTE GMACbyGetBootRomSize(DWORD dwIoBase)
+{
+ BYTE byOrgValue;
+
+ VNSvInPortB(dwIoBase + MAC_REG_CFGC, &byOrgValue);
+ return (BYTE)(byOrgValue & 0x07);
+}
+
+VOID GMACvSetPhyId(DWORD dwIoBase, BYTE byRevId, BYTE byPhyId)
+{
+ BYTE byData;
+
+ /* set PHY address */
+ VNSvInPortB(dwIoBase + MAC_REG_MIICFG, &byData);
+ byData = (BYTE)((byData & 0xE0) | (byPhyId & 0x1F));
+ VNSvOutPortB(dwIoBase + MAC_REG_MIICFG, byData);
+}
+
+BYTE GMACbyGetPhyId(DWORD dwIoBase)
+{
+ BYTE byOrgValue;
+
+ VNSvInPortB(dwIoBase + MAC_REG_MIICFG, &byOrgValue);
+ return (BYTE)(byOrgValue & 0x1F);
+}
+
+VOID GMACvSetRxThreshold(DWORD dwIoBase, BYTE byThreshold)
+{
+ BYTE byOrgValue;
+
+ DBG_ASSERT(byThreshold < 4);
+
+ /* set MCFG0 */
+ VNSvInPortB(dwIoBase + MAC_REG_MCFG0, &byOrgValue);
+ byOrgValue = (BYTE)((byOrgValue & ~(MCFG0_RFT1|MCFG0_RFT0)) | (byThreshold << 4));
+ VNSvOutPortB(dwIoBase + MAC_REG_MCFG0, byOrgValue);
+}
+
+VOID GMACvGetRxThreshold(DWORD dwIoBase, PBYTE pbyThreshold)
+{
+ /* first, get MCFG0 */
+ VNSvInPortB(dwIoBase + MAC_REG_MCFG0, pbyThreshold);
+ *pbyThreshold = (BYTE)((*pbyThreshold >> 4) & 0x03);
+}
+
+VOID GMACvSetDmaLength(DWORD dwIoBase, BYTE byDmaLength)
+{
+ BYTE byOrgValue;
+
+ DBG_ASSERT(byDmaLength < 8);
+
+ /* set DCFG0 */
+ VNSvInPortB(dwIoBase + MAC_REG_DCFG0, &byOrgValue);
+ byOrgValue = (BYTE)((byOrgValue & 0xF8) | byDmaLength);
+ VNSvOutPortB(dwIoBase + MAC_REG_DCFG0, byOrgValue);
+}
+
+VOID GMACvGetDmaLength(DWORD dwIoBase, PBYTE pbyDmaLength)
+{
+ /* get DCFG0 */
+ VNSvInPortB(dwIoBase + MAC_REG_DCFG0, pbyDmaLength);
+ *pbyDmaLength &= 0x07;
+}
+
+VOID GMACvSetLoopbackMode(DWORD dwIoBase, BYTE byLoopbackMode)
+{
+ BYTE byOrgValue;
+
+ DBG_ASSERT(byLoopbackMode < 3);
+
+ /* set TCR */
+ VNSvInPortB(dwIoBase + MAC_REG_TCR, &byOrgValue);
+ byOrgValue = (BYTE)((byOrgValue & 0xFC) | byLoopbackMode);
+ VNSvOutPortB(dwIoBase + MAC_REG_TCR, byOrgValue);
+}
+
+BOOL GMACbIsInLoopbackMode(DWORD dwIoBase)
+{
+ BYTE byOrgValue;
+
+ VNSvInPortB(dwIoBase + MAC_REG_TCR, &byOrgValue);
+ if (BITbIsAnyBitsOn(byOrgValue, TCR_LB1 | TCR_LB0))
+ return TRUE;
+
+ return FALSE;
+}
+
+BOOL GMACbIsIn1GMode(DWORD dwIoBase, BYTE byRevId)
+{
+ UINT ii;
+
+ for (ii = 0; ii < 30; ii++)
+ PCAvDelayByIO(CB_DELAY_LOOP_WAIT);
+
+ /* NOTE.... */
+ /* when link fail, MAC will report in 1G mode, */
+ return GMACbIsRegBitsOn(dwIoBase, MAC_REG_PHYSR0, PHYSR0_SPDG);
+}
+
+BOOL GMACbIsIn100MMode(DWORD dwIoBase, BYTE byRevId)
+{
+ UINT ii;
+
+ for (ii = 0; ii < 30; ii++)
+ PCAvDelayByIO(CB_DELAY_LOOP_WAIT);
+
+ /* NOTE.... */
+ /* when link fail, MAC will report in 1G mode, */
+ return GMACbIsRegBitsOff(dwIoBase, MAC_REG_PHYSR0, PHYSR0_SPDG) &&
+ GMACbIsRegBitsOff(dwIoBase, MAC_REG_PHYSR0, PHYSR0_SPD10);
+}
+
+BOOL GMACbIsInFullDuplexMode(DWORD dwIoBase)
+{
+ return GMACbIsRegBitsOn(dwIoBase, MAC_REG_PHYSR0, PHYSR0_FDPX);
+}
+
+BOOL GMACbIsCableLinkOk(DWORD dwIoBase)
+{
+ return GMACbIsRegBitsOn(dwIoBase, MAC_REG_PHYSR0, PHYSR0_LINKGD);
+}
+
+VOID GMACvDisableMiiAutoPoll(DWORD dwIoBase)
+{
+ WORD ww;
+ BYTE byData;
+
+ /* turn off MAUTO */
+ VNSvOutPortB(dwIoBase + MAC_REG_MIICR, 0);
+
+ /* as soon as MIDLE is on, MAUTO is really stoped */
+ for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
+ udelay(1000);
+ VNSvInPortB(dwIoBase + MAC_REG_MIISR, &byData);
+ if (BITbIsBitOn(byData, MIISR_MIIDL))
+ break;
+ }
+}
+
+/*
+ * NOTE....
+ * first, disable MIICR_MAUTO, then
+ * set MII reg offset to BMSR == 0x01
+ * must set offset before re-enable MIICR_MAUTO
+ */
+VOID GMACvEnableMiiAutoPoll(DWORD dwIoBase)
+{
+ WORD ww;
+ BYTE byData;
+
+ VNSvOutPortB(dwIoBase + MAC_REG_MIICR, 0);
+
+ /* polling once before MAUTO is turned on */
+ VNSvOutPortB(dwIoBase + MAC_REG_MIIADR, MIIADR_SWMPL);
+
+ /* as soon as MIIDL is on, polling is really completed */
+ for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
+ udelay(1000);
+ VNSvInPortB(dwIoBase + MAC_REG_MIISR, &byData);
+ if (BITbIsBitOn(byData, MIISR_MIIDL))
+ break;
+ }
+
+ /* Turn on MAUTO */
+ VNSvOutPortB(dwIoBase + MAC_REG_MIICR, MIICR_MAUTO);
+
+ /* as soon as MIIDL is off, MAUTO is really started */
+ for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
+ VNSvInPortB(dwIoBase + MAC_REG_MIISR, &byData);
+ if (BITbIsBitOff(byData, MIISR_MIIDL))
+ break;
+ }
+}
+
+VOID GMACvSetPacketFilter(DWORD dwIoBase, WORD wFilterType)
+{
+ BYTE byOldRCR;
+ BYTE byNewRCR = 0;
+ BYTE byOrgCAMCR, byData;
+
+
+ /* modify CAMCR to select MAR regs */
+ VNSvInPortB(dwIoBase + MAC_REG_CAMCR, &byOrgCAMCR);
+ byData = (BYTE)(byOrgCAMCR & ~(CAMCR_PS1|CAMCR_PS0));
+ VNSvOutPortB(dwIoBase + MAC_REG_CAMCR, byData);
+
+ /* if only in DIRECTED mode, multicast-address will set to zero, */
+ /* but if other mode exist (e.g. PROMISCUOUS), multicast-address */
+ /* will be open */
+ if (BITbIsBitOn(wFilterType, PKT_TYPE_DIRECTED)) {
+ /* set multicast address to accept none */
+ VNSvOutPortD(dwIoBase + MAC_REG_MAR, 0L);
+ /* PCAvDelayByIO(1); */
+ VNSvOutPortD(dwIoBase + MAC_REG_MAR + sizeof(DWORD), 0L);
+ /* PCAvDelayByIO(1); */
+ }
+
+ if (BITbIsAnyBitsOn(wFilterType, PKT_TYPE_PROMISCUOUS | PKT_TYPE_ALL_MULTICAST)) {
+ /* set multicast address to accept all */
+ VNSvOutPortD(dwIoBase + MAC_REG_MAR, 0xFFFFFFFFL);
+ /* PCAvDelayByIO(1); */
+ VNSvOutPortD(dwIoBase + MAC_REG_MAR + sizeof(DWORD), 0xFFFFFFFFL);
+ /* PCAvDelayByIO(1); */
+ }
+
+ /* restore to original CAMCR */
+ VNSvOutPortB(dwIoBase + MAC_REG_CAMCR, byOrgCAMCR);
+
+
+ if (BITbIsBitOn(wFilterType, PKT_TYPE_PROMISCUOUS))
+ byNewRCR |= (RCR_PROM | RCR_AM | RCR_AB);
+
+ if (BITbIsAnyBitsOn(wFilterType, PKT_TYPE_MULTICAST | PKT_TYPE_ALL_MULTICAST))
+ byNewRCR |= RCR_AM;
+
+ if (BITbIsBitOn(wFilterType, PKT_TYPE_BROADCAST))
+ byNewRCR |= RCR_AB;
+
+ if (BITbIsBitOn(wFilterType, PKT_TYPE_RUNT))
+ byNewRCR |= RCR_AR;
+
+ if (BITbIsBitOn(wFilterType, PKT_TYPE_ERROR))
+ byNewRCR |= RCR_SEP;
+
+ VNSvInPortB(dwIoBase + MAC_REG_RCR, &byOldRCR);
+ if (byNewRCR != (byOldRCR & 0x1F)) {
+ /* Modify the Receive Command Register */
+ byNewRCR |= (BYTE)(byOldRCR & 0xE0);
+ VNSvOutPortB(dwIoBase + MAC_REG_RCR, byNewRCR);
+ }
+}
+
+VOID GMACvSaveContext(DWORD dwIoBase, BYTE byRevId, PBYTE pbyCxtBuf)
+{
+ int ii;
+
+ /* save RCR,TCR,CR,ISR,IMR... */
+ for (ii = MAC_REG_PAR; ii < MAC_REG_DEC_BASE_HI; ii++) {
+ if (ii >= MAC_REG_CR0_CLR && ii <= MAC_REG_CR3_CLR)
+ continue;
+ VNSvInPortB(dwIoBase + ii, (PBYTE)(pbyCxtBuf + ii));
+ }
+
+ /* save MAC_REG_DEC_BASE_HI... */
+ for (ii = MAC_REG_DEC_BASE_HI; ii < MAC_REG_ISR_CTL; ii += 4)
+ VNSvInPortD(dwIoBase + ii, (PDWORD)(pbyCxtBuf + ii));
+
+ /* save ISR_CTL,ISR,IMR,TDCSR,RDCSR.. */
+ for (ii = MAC_REG_ISR_CTL; ii < MAC_REG_TDCSR_CLR; ii++)
+ VNSvInPortB(dwIoBase + ii, (PBYTE)(pbyCxtBuf + ii));
+
+ /* save MAC_REG_RDBASE_LO,MAC_REG_TDBASE_LO... */
+ for (ii = MAC_REG_RDBASE_LO; ii < MAC_REG_FIFO_TEST0; ii += 4)
+ VNSvInPortD(dwIoBase + ii, (PDWORD)(pbyCxtBuf + ii));
+
+ /* save MIICFG... */
+ for (ii = MAC_REG_MIICFG; ii < MAC_REG_TBIST; ii++)
+ VNSvInPortB(dwIoBase + ii, (PBYTE)(pbyCxtBuf + ii));
+
+ /* save GHIPGSR, WOLCR, PWCFG, TestReg, WOLCG ... */
+ for (ii = MAC_REG_CHIPGSR; ii < MAC_REG_WOLCR0_CLR; ii++)
+ VNSvInPortB(dwIoBase + ii, (PBYTE)(pbyCxtBuf + ii));
+
+ /* save pattern, mask */
+ for (ii = MAC_REG_PATRN_CRC0; ii < MAC_REG_BYTEMSK3_3 + 4; ii += 4)
+ VNSvInPortD(dwIoBase + ii, (PDWORD)(pbyCxtBuf + ii));
+}
+
+VOID GMACvRestoreContext(DWORD dwIoBase, BYTE byRevId, PBYTE pbyCxtBuf)
+{
+ int ii;
+
+ /* restore RCR,TCR,CR,ISR,IMR... */
+ for (ii = MAC_REG_PAR; ii < MAC_REG_DEC_BASE_HI; ii++) {
+ if (ii >= MAC_REG_CR0_CLR && ii <= MAC_REG_CR3_CLR)
+ continue;
+ /* except CR0, because we don't want to start chip now */
+ if (ii != MAC_REG_CR0_SET)
+ VNSvOutPortB(dwIoBase + ii, *(pbyCxtBuf + ii));
+ }
+
+ /* restore MAC_REG_DEC_BASE_HI... */
+ for (ii = MAC_REG_DEC_BASE_HI; ii < MAC_REG_ISR_CTL; ii += 4) {
+ VNSvOutPortD(dwIoBase + ii, *(PDWORD)(pbyCxtBuf + ii));
+ /* PCAvDelayByIO(1); */
+ }
+
+ /* restore ISR_CTL,ISR,IMR,TDCSR,RDCSR.. */
+ for (ii = MAC_REG_ISR_CTL; ii < MAC_REG_TDCSR_CLR; ii++)
+ VNSvOutPortB(dwIoBase + ii, *(pbyCxtBuf + ii));
+
+ /* restore MAC_REG_RDBASE_LO,MAC_REG_TDBASE_LO... */
+ for (ii = MAC_REG_RDBASE_LO; ii < MAC_REG_FIFO_TEST0; ii += 4) {
+ VNSvOutPortD(dwIoBase + ii, *(PDWORD)(pbyCxtBuf + ii));
+ /* PCAvDelayByIO(1); */
+ }
+
+ /* restore MIICFG... */
+ for (ii = MAC_REG_MIICFG; ii < MAC_REG_TBIST; ii++)
+ VNSvOutPortB(dwIoBase + ii, *(pbyCxtBuf + ii));
+
+ /* restore GHIPGSR, WOLCR, PWCFG, TestReg, WOLCG ... */
+ for (ii = MAC_REG_CHIPGSR; ii < MAC_REG_WOLCR0_CLR; ii++)
+ VNSvOutPortB(dwIoBase + ii, *(pbyCxtBuf + ii));
+
+ /* restore pattern, mask */
+ for (ii = MAC_REG_PATRN_CRC0; ii < MAC_REG_BYTEMSK3_3 + 4; ii += 4) {
+ VNSvOutPortD(dwIoBase + ii, *(PDWORD)(pbyCxtBuf + ii));
+ /* PCAvDelayByIO(1); */
+ }
+}
+
+VOID GMACvTimer0MiniSDelay(DWORD dwIoBase, BYTE byRevId, UINT udelay)
+{
+ BYTE byData;
+
+ /* Disable Timer0 Interrupt */
+ MACvRegBitsOff(dwIoBase, MAC_REG_IMR + 2, (BYTE)(ISR_TMR0I >> 16));
+
+ /* Set resolution to mini second */
+ MACvRegBitsOff(dwIoBase, MAC_REG_CHIPGCR, CHIPGCR_TM0US);
+
+ /* set delay time to udelay, unit is mini-second */
+ VNSvOutPortW(dwIoBase + MAC_REG_SOFT_TIMER0, (WORD)udelay);
+
+ /* enable timer0 */
+ VNSvOutPortB(dwIoBase + MAC_REG_CR1_SET, CR1_TM0EN);
+
+ /* wait for TM0EN self clear */
+ while (TRUE) {
+ if (GMACbIsRegBitsOff(dwIoBase, MAC_REG_CR1_SET, CR1_TM0EN)) {
+ /* clear TMR0I */
+ VNSvInPortB(dwIoBase + MAC_REG_ISR + 2, &byData);
+ VNSvOutPortB(dwIoBase + MAC_REG_ISR + 2, byData);
+ break;
+ }
+ }
+
+ /* Enable Timer0 Interrupt */
+ MACvRegBitsOn(dwIoBase, MAC_REG_IMR + 2, (BYTE)(ISR_TMR0I >> 16));
+}
+
+VOID GMACvTimer0MicroSDelay(DWORD dwIoBase, BYTE byRevId, UINT udelay)
+{
+ BYTE byData;
+
+ /* Notice!!! */
+ /* Disable Timer0 Interrupt */
+ MACvRegBitsOff(dwIoBase, MAC_REG_IMR + 2, (BYTE)(ISR_TMR0I >> 16));
+
+ /* Set resolution to micro second */
+ MACvRegBitsOn(dwIoBase, MAC_REG_CHIPGCR, CHIPGCR_TM0US);
+
+ /* set delay time to udelay, unit is micro-second */
+ VNSvOutPortW(dwIoBase + MAC_REG_SOFT_TIMER0, (WORD)udelay);
+
+ /* enable timer0 */
+ VNSvOutPortB(dwIoBase + MAC_REG_CR1_SET, CR1_TM0EN);
+
+ /* wait for TM0EN self clear */
+ while (TRUE) {
+ /* Method 1 -> OK, and safe */
+ if (GMACbIsRegBitsOff(dwIoBase, MAC_REG_CR1_SET, CR1_TM0EN)) {
+ /* clear TMR0I */
+ VNSvInPortB(dwIoBase + MAC_REG_ISR + 2, &byData);
+ VNSvOutPortB(dwIoBase + MAC_REG_ISR + 2, byData);
+ break;
+ }
+
+ /*
+ // Method 2 -> OK, but not safe
+ VNSvInPortB(dwIoBase + MAC_REG_ISR + 2, &byData);
+ if (BITbIsBitOn(byData, (BYTE)(ISR_TMR0I >> 16))) {
+ VNSvOutPortB(dwIoBase + MAC_REG_ISR + 2, byData);
+ break;
+ }
+ */
+ /*
+ // Method 3 -> OK, but not safe
+ if (MACbIsRegBitsOn(dwIoBase, MAC_REG_ISR + 2, (BYTE)(ISR_TMR0I >> 16))) {
+ // clear TMR0I
+ VNSvOutPortB(dwIoBase + MAC_REG_ISR + 2, (BYTE)(ISR_TMR0I >> 16));
+ break;
+ }
+ */
+ }
+
+ /* Notice !!! */
+ /* Enable Timer0 Interrupt */
+ MACvRegBitsOn(dwIoBase, MAC_REG_IMR + 2, (BYTE)(ISR_TMR0I >> 16));
+}
+
+BOOL GMACbSoftwareReset(DWORD dwIoBase, BYTE byRevId)
+{
+ WORD ww;
+
+ /* turn on CR1_SFRST */
+ MACvRegBitsOn(dwIoBase, MAC_REG_CR1_SET, CR1_SFRST);
+
+ /* polling till software reset complete */
+ /* W_MAX_TIMEOUT is the timeout period */
+ for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
+ if (GMACbIsRegBitsOff(dwIoBase, MAC_REG_CR1_SET, (BYTE)CR1_SFRST))
+ break;
+ }
+
+ if (ww == W_MAX_TIMEOUT) {
+ /* turn on force reset */
+ MACvRegBitsOn(dwIoBase, MAC_REG_CR3_SET, CR3_FORSRST);
+ /* delay 2ms */
+ GMACvTimer0MiniSDelay(dwIoBase, byRevId, 2);
+ }
+ return TRUE;
+}
+
+BOOL GMACbSafeSoftwareReset(DWORD dwIoBase, BYTE byRevId)
+{
+ BYTE abyTmpRegData[0x100];
+ BOOL bRetVal;
+
+ /* PATCH.... */
+ /* save some important register's value, then do */
+ /* reset, then restore register's value */
+
+ /* save MAC context */
+ GMACvSaveContext(dwIoBase, byRevId, abyTmpRegData);
+ /* do reset */
+ bRetVal = GMACbSoftwareReset(dwIoBase, byRevId);
+ /* restore MAC context, except CR0 */
+ GMACvRestoreContext(dwIoBase, byRevId, abyTmpRegData);
+
+ return bRetVal;
+}
+
+BOOL GMACbSafeRxOff(DWORD dwIoBase, BYTE byRevId)
+{
+ WORD ww;
+
+ /* clear RUN Rx */
+ VNSvOutPortB(dwIoBase + MAC_REG_RDCSR_CLR, TRDCSR_RUN);
+
+ MACvRxOff(dwIoBase);
+
+ /* safe delay time */
+ PCAvDelayByIO(CB_DELAY_SOFT_RESET);
+ /* W_MAX_TIMEOUT is the timeout period */
+ for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
+ if (GMACbIsRegBitsOff(dwIoBase, MAC_REG_CR0_SET, (BYTE)CR0_RXON))
+ break;
+ }
+
+ if (ww == W_MAX_TIMEOUT)
+ return FALSE;
+
+ return TRUE;
+}
+
+BOOL GMACbSafeTxOff(DWORD dwIoBase, BYTE byRevId)
+{
+ WORD ww;
+
+ /* clear RUN Tx */
+ VNSvOutPortW(dwIoBase + MAC_REG_TDCSR_CLR, 0x1111);
+
+ /* try to safe shutdown TX */
+ MACvTxOff(dwIoBase);
+
+ /* safe delay time */
+ PCAvDelayByIO(CB_DELAY_SOFT_RESET);
+ /* W_MAX_TIMEOUT is the timeout period */
+ for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
+ if (GMACbIsRegBitsOff(dwIoBase, MAC_REG_CR0_SET, (BYTE)CR0_TXON))
+ break;
+ }
+ if (ww == W_MAX_TIMEOUT)
+ return FALSE;
+
+ return TRUE;
+}
+
+BOOL GMACbStop(DWORD dwIoBase)
+{
+ WORD ww;
+
+ VNSvOutPortB(dwIoBase + MAC_REG_CR0_SET, CR0_STOP);
+
+ /* W_MAX_TIMEOUT is the timeout period */
+ for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
+ if (GMACbIsRegBitsOff(dwIoBase, MAC_REG_CR0_SET, (BYTE)(CR0_TXON | CR0_RXON)))
+ break;
+ }
+ if (ww == W_MAX_TIMEOUT)
+ return FALSE;
+
+ return TRUE;
+}
+
+BOOL GMACbSafeStop(DWORD dwIoBase, BYTE byRevId)
+{
+ if (!GMACbSafeTxOff(dwIoBase, byRevId))
+ return FALSE;
+ if (!GMACbSafeRxOff(dwIoBase, byRevId))
+ return FALSE;
+ if (!GMACbStop(dwIoBase))
+ return FALSE;
+
+ return TRUE;
+}
+
+BOOL GMACbShutdown(DWORD dwIoBase, BYTE byRevId)
+{
+ /* disable MAC IMR */
+ MACvIntDisable(dwIoBase);
+ /* disable MII auto-poll */
+ GMACvDisableMiiAutoPoll(dwIoBase);
+ /* stop the adapter */
+ if (!GMACbSafeStop(dwIoBase, byRevId))
+ return FALSE;
+
+ return TRUE;
+}
+
+int GMACiWriteVee(DWORD dwIoBase, unsigned char i8Addr, unsigned short i16Data)
+{
+ int i32Data;
+ i8Addr = i8Addr & 0xf;
+ i32Data = i16Data|(i8Addr<<16);
+ VPCIvWriteD(dwIoBase, Gmac_PCI_VEE_WRITE, i32Data);
+ return 1;
+}
+
+VOID GMACLoadVEE(DWORD dwIoBase)
+{
+ unsigned char gmac[32] = {
+ 0, 0x02, 0x2a, 0xdd, 0x44, 0xb0, 0x7, 0x0, 0x10,
+ 0x01, 0x6, 0x11, 0x19, 0x31, 0x6, 0x11, 0x1f, 0x10,
+ 0x0, 0x0, 0x00, 0x01, 0x3, 0x8, 0x01, 0x10, 0x13,
+ 0x10, 0x40, 0x30, 0x73, 0x21
+ };
+ /* unsigned char check; */
+ DWORD i32Data;
+ int ii = 0;
+
+ /* fill virtual eeprom */
+ for (ii = 0; ii < 16; ii++)
+ GMACiWriteVee(dwIoBase, ii, *(((unsigned short *)gmac)+ii));
+
+ /* enable read process */
+ VPCIvReadD(dwIoBase, Gmac_PCI_VEE_READ, &i32Data);
+ i32Data = i32Data | 0x08000000;
+ VPCIvWriteD(dwIoBase, Gmac_PCI_VEE_READ, i32Data);
+ /* set SEEPR */
+ VPCIvReadD(dwIoBase, Gmac_PCI_VEE_READ, &i32Data);
+ i32Data = i32Data|0x01000000;
+ VPCIvWriteD(dwIoBase, Gmac_PCI_VEE_READ, i32Data);
+ MACvRegBitsOn(dwIoBase, MAC_REG_EECSR, EECSR_RELOAD);
+ /* wait SEELD */
+ while (1) {
+ VPCIvReadD(dwIoBase, Gmac_PCI_VEE_READ, &i32Data);
+ if (i32Data & 0x02000000)
+ break;
+ }
+ /* clean SEEPR */
+ VPCIvReadD(dwIoBase, Gmac_PCI_VEE_READ, &i32Data);
+ i32Data = i32Data & ~0x01000000;
+ VPCIvWriteD(dwIoBase, Gmac_PCI_VEE_READ, i32Data);
+ /* disable read process */
+ VPCIvReadD(dwIoBase, Gmac_PCI_VEE_READ, &i32Data);
+ i32Data = i32Data & ~0x08000000;
+ VPCIvWriteD(dwIoBase, Gmac_PCI_VEE_READ, i32Data);
+}
+
+VOID GMACvInitialize(PSAdapterInfo pAdapter, DWORD dwIoBase, BYTE byRevId)
+{
+ BYTE byTemp;
+ BYTE check;
+
+ /* clear sticky bits */
+ MACvClearStckDS(dwIoBase);
+
+ /* disable force PME-enable */
+
+ VNSvOutPortB(dwIoBase + MAC_REG_WOLCFG_CLR, WOLCFG_PMEOVR);
+ /* disable power-event config bit */
+
+ MACvPwrEvntDisable(dwIoBase);
+
+ /* clear power status */
+ VNSvOutPortW(dwIoBase + MAC_REG_WOLSR0_CLR, 0xFFFF);
+
+ /* do reset */
+ GMACbSoftwareReset(dwIoBase, byRevId);
+
+ /* for AUTOLD be effect, safe delay time */
+ PCAvDelayByIO(CB_DELAY_SOFT_RESET);
+
+ VNSvInPortB(dwIoBase + MAC_REG_JMPSR1, &check);
+
+ /* VNSvInPortB(pAdapter->dwIoBase+Gmac_Jumper_Strapping3, &check) */
+ /* if (!(check & JMPSR1_J_VEESEL))
+ GMACLoadVEE(dwIoBase);
+ else { */
+ if (check & JMPSR1_J_VEESEL) {
+ /* issue RELOAD in EECSR to reload eeprom */
+ MACvRegBitsOn(dwIoBase, MAC_REG_EECSR, EECSR_RELOAD);
+
+ /* wait until EEPROM loading complete */
+ while (TRUE) {
+ if (GMACbIsRegBitsOff(dwIoBase, MAC_REG_EECSR, EECSR_RELOAD))
+ break;
+ }
+ }
+
+ /* EEPROM reloaded will cause bit 0 in MAC_REG_CFGA turned on. */
+ /* it makes MAC receive magic packet automatically. So, driver turn it off. */
+ MACvRegBitsOff(dwIoBase, MAC_REG_CFGA, CFGA_PACPI);
+
+ /* set rx-FIFO/DMA threshold */
+ /* set rx threshold, 128 bytes */
+ /*GMACvSetRxThreshold(dwIoBase, 3);*/
+
+ /* set DMA length, 16 DWORDs = 64 bytes */
+ /*GMACvSetDmaLength(dwIoBase, 1);*/
+
+ /* suspend-well accept broadcast, multicast */
+ VNSvOutPortB(dwIoBase + MAC_REG_WOLCFG_SET, WOLCFG_SAM | WOLCFG_SAB);
+
+ /* back off algorithm use original IEEE standard */
+ MACvRegBitsOff(dwIoBase, MAC_REG_CFGB, CFGB_CRANDOM | CFGB_CAP | CFGB_MBA | CFGB_BAKOPT);
+
+ /* set packet filter */
+ /* receive directed and broadcast address */
+ GMACvSetPacketFilter(dwIoBase, PKT_TYPE_DIRECTED | PKT_TYPE_BROADCAST);
+
+ /* Eric */
+#if defined(__USE_GMASK1__)
+ VNSvOutPortD(dwIoBase + MAC_REG_IMR, IMR_MASK_VALUE);
+#else
+ /* Turn on GenIntMask1 */
+ VNSvOutPortB(dwIoBase + MAC_REG_CR3_SET, CR3_GINTMSK1);
+#endif
+#if 0
+ VNSvInPortB(dwIoBase, &byTemp);
+ printf("address0 = %x\n ", byTemp);
+ VNSvInPortB(dwIoBase + 1, &byTemp);
+ printf("address1 = %x\n ", byTemp);
+ VNSvInPortB(dwIoBase + 2, &byTemp);
+ printf("address2 = %x\n ", byTemp);
+ VNSvInPortB(dwIoBase + 3, &byTemp);
+ printf("address3 = %x\n ", byTemp);
+ VNSvInPortB(dwIoBase + 4, &byTemp);
+ printf("address4 = %x\n ", byTemp);
+ VNSvInPortB(dwIoBase + 5, &byTemp);
+ printf("address6 = %x\n ", byTemp);
+#endif
+ /* Adaptive Interrupt: Init is disabled */
+
+ /* Select page to interrupt hold timer */
+ VNSvInPortB(dwIoBase + MAC_REG_CAMCR, &byTemp);
+ byTemp &= ~(CAMCR_PS0 | CAMCR_PS1);
+ VNSvOutPortB(dwIoBase + MAC_REG_CAMCR, byTemp);
+ /* Set Interrupt hold timer = 0 */
+ VNSvOutPortB(dwIoBase + MAC_REG_ISR_HOTMR, 0x00);
+
+ /* Select Page to Tx-sup threshold */
+ VNSvInPortB(dwIoBase + MAC_REG_CAMCR, &byTemp);
+ byTemp = (BYTE)((byTemp | CAMCR_PS0) & ~CAMCR_PS1);
+ VNSvOutPortB(dwIoBase + MAC_REG_CAMCR, byTemp);
+ /* Set Tx interrupt suppression threshold = 0 */
+ VNSvOutPortB(dwIoBase + MAC_REG_ISR_TSUPTHR, 0x00);
+
+ /* Select Page to Rx-sup threshold */
+ VNSvInPortB(dwIoBase + MAC_REG_CAMCR, &byTemp);
+ byTemp = (BYTE)((byTemp | CAMCR_PS1) & ~CAMCR_PS0);
+ VNSvOutPortB(dwIoBase + MAC_REG_CAMCR, byTemp);
+ /* Set Rx interrupt suppression threshold = 0 */
+ VNSvOutPortB(dwIoBase + MAC_REG_ISR_RSUPTHR, 0x00);
+
+ /* Select page to interrupt hold timer */
+ VNSvInPortB(dwIoBase + MAC_REG_CAMCR, &byTemp);
+ byTemp &= ~(CAMCR_PS0 | CAMCR_PS1);
+ VNSvOutPortB(dwIoBase + MAC_REG_CAMCR, byTemp);
+
+ /* enable MIICR_MAUTO */
+ GMACvEnableMiiAutoPoll(dwIoBase);
+}
+
+VOID GMACvSetVCAM(DWORD dwIoBase, BYTE byAddress, WORD wVID)
+{
+ BYTE byOrgCAMCR, byData;
+
+ /* modify CAMCR to select CAM DATA regs */
+ VNSvInPortB(dwIoBase + MAC_REG_CAMCR, &byOrgCAMCR);
+ byData = (BYTE)((byOrgCAMCR | CAMCR_PS1) & ~CAMCR_PS0);
+ VNSvOutPortB(dwIoBase + MAC_REG_CAMCR, byData);
+
+ /* enable/select VCAM */
+ VNSvOutPortB(dwIoBase + MAC_REG_CAMADDR, (BYTE)(CAMADDR_CAMEN | CAMADDR_VCAMSL | byAddress));
+
+ /* set VCAM data */
+ VNSvOutPortW(dwIoBase + MAC_REG_CAM, wVID);
+
+ /* issue write command */
+ MACvRegBitsOn(dwIoBase, MAC_REG_CAMCR, CAMCR_CAMWR);
+
+ /* Wait for CAMWR self clear */
+ while (TRUE) {
+ if (GMACbIsRegBitsOff(dwIoBase, MAC_REG_CAMCR, CAMCR_CAMWR))
+ break;
+ }
+
+ /* disable CAMEN */
+ VNSvOutPortB(dwIoBase + MAC_REG_CAMADDR, 0);
+
+ /* restore to original CAMCR */
+ VNSvOutPortB(dwIoBase + MAC_REG_CAMCR, byOrgCAMCR);
+}
+
+VOID GMACvSetMCAM(DWORD dwIoBase, BYTE byAddress, PBYTE pbyData)
+{
+ BYTE byOrgCAMCR, byData;
+ /* DWORD dwData; */
+
+ /* modify CAMCR to select CAM DATA regs */
+ VNSvInPortB(dwIoBase + MAC_REG_CAMCR, &byOrgCAMCR);
+ byData = (BYTE)((byOrgCAMCR | CAMCR_PS1) & ~CAMCR_PS0);
+ VNSvOutPortB(dwIoBase + MAC_REG_CAMCR, byData);
+
+ /* enable/select MCAM */
+ VNSvOutPortB(dwIoBase + MAC_REG_CAMADDR, (BYTE)(CAMADDR_CAMEN | byAddress));
+
+ /* set MCAM Data */
+ VNSvOutPortD(dwIoBase + MAC_REG_CAM, *(PDWORD)pbyData);
+ /* VNSvInPortD(dwIoBase + MAC_REG_CAM, &dwData); */
+ VNSvOutPortW(dwIoBase + MAC_REG_CAM + 4, *(PWORD)(pbyData + 4));
+ /* VNSvInPortW(dwIoBase + MAC_REG_CAM + 4, (PWORD)(&dwData)); */
+
+ /* issue write command */
+ MACvRegBitsOn(dwIoBase, MAC_REG_CAMCR, CAMCR_CAMWR);
+
+ /* Wait for CAMWR self clear */
+ while (TRUE) {
+ if (GMACbIsRegBitsOff(dwIoBase, MAC_REG_CAMCR, CAMCR_CAMWR))
+ break;
+ }
+
+ /* disable CAMEN */
+ VNSvOutPortB(dwIoBase + MAC_REG_CAMADDR, 0);
+
+ /* restore to original CAMCR */
+ VNSvOutPortB(dwIoBase + MAC_REG_CAMCR, byOrgCAMCR);
+}
+
+VOID GMACvGetVCAM(DWORD dwIoBase, BYTE byAddress, PWORD pwData)
+{
+ BYTE byOrgCAMCR, byData;
+
+ /* modify CAMCR to select CAM DATA regs */
+ VNSvInPortB(dwIoBase + MAC_REG_CAMCR, &byOrgCAMCR);
+ byData = (BYTE)((byOrgCAMCR | CAMCR_PS1) & ~CAMCR_PS0);
+ VNSvOutPortB(dwIoBase + MAC_REG_CAMCR, byData);
+
+ /* enable/select VCAM */
+ VNSvOutPortB(dwIoBase + MAC_REG_CAMADDR, (BYTE)(CAMADDR_CAMEN | CAMADDR_VCAMSL | byAddress));
+
+ /* issue read command */
+ MACvRegBitsOn(dwIoBase, MAC_REG_CAMCR, CAMCR_CAMRD);
+
+ /* Wait for CAMRD self clear */
+ while (TRUE) {
+ if (GMACbIsRegBitsOff(dwIoBase, MAC_REG_CAMCR, CAMCR_CAMRD))
+ break;
+ }
+
+ /* read VID CAM data */
+ VNSvInPortW(dwIoBase + MAC_REG_CAM, pwData);
+
+ /* disable CAMEN */
+ VNSvOutPortB(dwIoBase + MAC_REG_CAMADDR, 0);
+
+ /* restore to original CAMCR */
+ VNSvOutPortB(dwIoBase + MAC_REG_CAMCR, byOrgCAMCR);
+}
+
+VOID GMACvGetMCAM(DWORD dwIoBase, BYTE byAddress, PBYTE pbyData)
+{
+ BYTE byOrgCAMCR, byData;
+
+ /* modify CAMCR to select CAM DATA regs */
+ VNSvInPortB(dwIoBase + MAC_REG_CAMCR, &byOrgCAMCR);
+ byData = (BYTE)((byOrgCAMCR | CAMCR_PS1) & ~CAMCR_PS0);
+ VNSvOutPortB(dwIoBase + MAC_REG_CAMCR, byData);
+
+ /* enable/select MCAM */
+ VNSvOutPortB(dwIoBase + MAC_REG_CAMADDR, (BYTE)(CAMADDR_CAMEN | byAddress));
+
+ /* issue read command */
+ MACvRegBitsOn(dwIoBase, MAC_REG_CAMCR, CAMCR_CAMRD);
+
+ /* Wait for CAMRD self clear */
+ while (TRUE) {
+ if (GMACbIsRegBitsOff(dwIoBase, MAC_REG_CAMCR, CAMCR_CAMRD))
+ break;
+ }
+
+ VNSvInPortD(dwIoBase + MAC_REG_CAM, (PDWORD)pbyData);
+ VNSvInPortW(dwIoBase + MAC_REG_CAM + 4, (PWORD)(pbyData + 4));
+
+ /* disable CAMEN */
+ VNSvOutPortB(dwIoBase + MAC_REG_CAMADDR, 0);
+
+ /* restore to original CAMCR */
+ VNSvOutPortB(dwIoBase + MAC_REG_CAMCR, byOrgCAMCR);
+}
+
+VOID GMACvSetVCAMMask(DWORD dwIoBase, PBYTE pbyMask)
+{
+ BYTE byOrgCAMCR, byData;
+ /* DWORD dwData; */
+
+ /* modify CAMCR to select CAM MASK regs */
+ VNSvInPortB(dwIoBase + MAC_REG_CAMCR, &byOrgCAMCR);
+ byData = (BYTE)((byOrgCAMCR & ~CAMCR_PS1) | CAMCR_PS0);
+ VNSvOutPortB(dwIoBase + MAC_REG_CAMCR, byData);
+
+ /* Select VCAM Mask */
+ VNSvOutPortB(dwIoBase + MAC_REG_CAMADDR, CAMADDR_VCAMSL);
+
+ VNSvOutPortD(dwIoBase + MAC_REG_CAM, *(PDWORD)pbyMask);
+ /* VNSvInPortD(dwIoBase + MAC_REG_CAM, &dwData); */
+ VNSvOutPortD(dwIoBase + MAC_REG_CAM + 4, *(PDWORD)(pbyMask + 4));
+ /* VNSvInPortD(dwIoBase + MAC_REG_CAM + 4, &dwData); */
+
+ /* restore to original CAMCR */
+ VNSvOutPortB(dwIoBase + MAC_REG_CAMCR, byOrgCAMCR);
+}
+
+VOID GMACvSetMCAMMask(DWORD dwIoBase, PBYTE pbyMask)
+{
+ BYTE byOrgCAMCR, byData;
+ /* DWORD dwData; */
+
+ /* modify CAMCR to select CAM MASK regs */
+ VNSvInPortB(dwIoBase + MAC_REG_CAMCR, &byOrgCAMCR);
+ byData = (BYTE)((byOrgCAMCR & ~CAMCR_PS1) | CAMCR_PS0);
+ VNSvOutPortB(dwIoBase + MAC_REG_CAMCR, byData);
+
+ /* Select MCAM Mask */
+ VNSvOutPortB(dwIoBase + MAC_REG_CAMADDR, 0);
+
+ VNSvOutPortD(dwIoBase + MAC_REG_CAM, *(PDWORD)pbyMask);
+ /* VNSvInPortD(dwIoBase + MAC_REG_CAM, &dwData); */
+ VNSvOutPortD(dwIoBase + MAC_REG_CAM + 4, *((PDWORD)(pbyMask + 4)));
+ /* VNSvInPortD(dwIoBase + MAC_REG_CAM + 4, &dwData); */
+
+ /* restore to original CAMCR */
+ VNSvOutPortB(dwIoBase + MAC_REG_CAMCR, byOrgCAMCR);
+}
+
+VOID GMACvGetVCAMMask(DWORD dwIoBase, PBYTE pbyMask)
+{
+ BYTE byOrgCAMCR, byData;
+
+ /* modify CAMCR to select CAM MASK regs */
+ VNSvInPortB(dwIoBase + MAC_REG_CAMCR, &byOrgCAMCR);
+ byData = (BYTE)((byOrgCAMCR & ~CAMCR_PS1) | CAMCR_PS0);
+ VNSvOutPortB(dwIoBase + MAC_REG_CAMCR, byData);
+
+ /* select VCAM Mask */
+ VNSvOutPortB(dwIoBase + MAC_REG_CAMADDR, CAMADDR_VCAMSL);
+
+ VNSvInPortD(dwIoBase + MAC_REG_CAM, (PDWORD)pbyMask);
+ VNSvInPortD(dwIoBase + MAC_REG_CAM + 4, (PDWORD)(pbyMask + 4));
+
+ /* restore to original CAMCR */
+ VNSvOutPortB(dwIoBase + MAC_REG_CAMCR, byOrgCAMCR);
+}
+
+VOID GMACvGetMCAMMask(DWORD dwIoBase, PBYTE pbyMask)
+{
+ BYTE byOrgCAMCR, byData;
+
+ /* modify CAMCR to select CAM MASK regs */
+ VNSvInPortB(dwIoBase + MAC_REG_CAMCR, &byOrgCAMCR);
+ byData = (BYTE)((byOrgCAMCR & ~CAMCR_PS1) | CAMCR_PS0);
+ VNSvOutPortB(dwIoBase + MAC_REG_CAMCR, byData);
+
+ /* Select MCAM Mask */
+ VNSvOutPortB(dwIoBase + MAC_REG_CAMADDR, 0);
+
+ /* select CAM and read CAM mask data (don't need to set CAMEN) */
+ VNSvOutPortB(dwIoBase + MAC_REG_CAMADDR, 0);
+ VNSvInPortD(dwIoBase + MAC_REG_CAM, (PDWORD)pbyMask);
+ VNSvInPortD(dwIoBase + MAC_REG_CAM + 4, (PDWORD)(pbyMask + 4));
+
+ /* restore to original CAMCR */
+ VNSvOutPortB(dwIoBase + MAC_REG_CAMCR, byOrgCAMCR);
+}
+
+VOID GMACvSetVCAMMaskByBR(DWORD dwIoBase, PBYTE pbyMask)
+{
+ BYTE byOrgCAMCR, byData;
+
+ /* modify CAMCR to select CAM MASK regs */
+ VNSvInPortB(dwIoBase + MAC_REG_CAMCR, &byOrgCAMCR);
+ byData = (BYTE)((byOrgCAMCR & ~CAMCR_PS1) | CAMCR_PS0);
+ VNSvOutPortB(dwIoBase + MAC_REG_CAMCR, byData);
+
+ /* Select VCAM Mask */
+ VNSvOutPortB(dwIoBase + MAC_REG_CAMADDR, CAMADDR_VCAMSL);
+
+ UINT uu;
+ for (uu = 0; uu < 8; uu++) {
+ VNSvOutPortB(dwIoBase + MAC_REG_CAM + uu, *(pbyMask + uu));
+ /* PATCH...Read back for daley */
+ /* VNSvInPortB(dwIoBase + MAC_REG_CAM + uu, &byData); */
+ }
+
+ /* restore to original CAMCR */
+ VNSvOutPortB(dwIoBase + MAC_REG_CAMCR, byOrgCAMCR);
+}
+
+VOID GMACvSetMCAMMaskByBR(DWORD dwIoBase, PBYTE pbyMask)
+{
+ BYTE byOrgCAMCR, byData;
+
+ /* modify CAMCR to select CAM MASK regs */
+ VNSvInPortB(dwIoBase + MAC_REG_CAMCR, &byOrgCAMCR);
+ byData = (BYTE)((byOrgCAMCR & ~CAMCR_PS1) | CAMCR_PS0);
+ VNSvOutPortB(dwIoBase + MAC_REG_CAMCR, byData);
+
+ /* Select MCAM Mask */
+ VNSvOutPortB(dwIoBase + MAC_REG_CAMADDR, 0);
+
+ UINT uu;
+ for (uu = 0; uu < 8; uu++) {
+ VNSvOutPortB(dwIoBase + MAC_REG_CAM + uu, *(pbyMask + uu));
+ /* PATCH...Read back for delay */
+ /* VNSvInPortB(dwIoBase + MAC_REG_CAM + uu, &byData); */
+ }
+
+ /* restore to original CAMCR */
+ VNSvOutPortB(dwIoBase + MAC_REG_CAMCR, byOrgCAMCR);
+}
+
+VOID GMACvGetVCAMMaskByBR(DWORD dwIoBase, PBYTE pbyMask)
+{
+ BYTE byOrgCAMCR, byData;
+
+ /* modify CAMCR to select CAM MASK regs */
+ VNSvInPortB(dwIoBase + MAC_REG_CAMCR, &byOrgCAMCR);
+ byData = (BYTE)((byOrgCAMCR & ~CAMCR_PS1) | CAMCR_PS0);
+ VNSvOutPortB(dwIoBase + MAC_REG_CAMCR, byData);
+
+ /* select VCAM Mask */
+ VNSvOutPortB(dwIoBase + MAC_REG_CAMADDR, CAMADDR_VCAMSL);
+
+ UINT uu;
+ for (uu = 0; uu < 8; uu++)
+ VNSvInPortB(dwIoBase + MAC_REG_CAM + uu, (pbyMask + uu));
+
+ /* restore to original CAMCR */
+ VNSvOutPortB(dwIoBase + MAC_REG_CAMCR, byOrgCAMCR);
+}
+
+VOID GMACvGetMCAMMaskByBR(DWORD dwIoBase, PBYTE pbyMask)
+{
+ BYTE byOrgCAMCR, byData;
+
+ /* modify CAMCR to select CAM MASK regs */
+ VNSvInPortB(dwIoBase + MAC_REG_CAMCR, &byOrgCAMCR);
+ byData = (BYTE)((byOrgCAMCR & ~CAMCR_PS1) | CAMCR_PS0);
+ VNSvOutPortB(dwIoBase + MAC_REG_CAMCR, byData);
+
+ /* Select MCAM Mask */
+ VNSvOutPortB(dwIoBase + MAC_REG_CAMADDR, 0);
+
+ UINT uu;
+ for (uu = 0; uu < 8; uu++)
+ VNSvInPortB(dwIoBase + MAC_REG_CAM + uu, (pbyMask + uu));
+
+ /* restore to original CAMCR */
+ VNSvOutPortB(dwIoBase + MAC_REG_CAMCR, byOrgCAMCR);
+}
+
+VOID GMACvSetTqIndex(DWORD dwIoBase, BYTE byTxQue, WORD wTdIdx)
+{
+ BYTE byData;
+
+ /* Clear RUN */
+ VNSvOutPortB(dwIoBase + MAC_REG_TDCSR_CLR + (byTxQue / 2), (BYTE)(TRDCSR_RUN << ((byTxQue % 2)*4)));
+
+ /* Wait for RUN clear */
+ while (TRUE) {
+ VNSvInPortB(dwIoBase + MAC_REG_TDCSR_SET + (byTxQue / 2), &byData);
+ if (BITbIsBitOff(byData, TRDCSR_RUN << ((byTxQue % 2)*4)))
+ break;
+ }
+
+ /* Set TdIdx */
+ VNSvOutPortW(dwIoBase + MAC_REG_TDINDX + byTxQue*2, wTdIdx);
+ /* Set RUN */
+ VNSvOutPortB(dwIoBase + MAC_REG_TDCSR_SET + (byTxQue / 2), (BYTE)(TRDCSR_RUN << ((byTxQue % 2)*4)));
+}
+
+void dumpmac(int iobase)
+{
+ int i = 0;
+ DWORD data;
+ for (i = 0; i < 0x80; i += 4) {
+ VNSvInPortD(iobase+i, &data);
+ printf("mac %8x:%8x\n", i, data);
+ }
+ return;
+}
diff --git a/cpu/arm920t/wmt/gmacif.c b/cpu/arm920t/wmt/gmacif.c
new file mode 100755
index 0000000..c67dfcf
--- /dev/null
+++ b/cpu/arm920t/wmt/gmacif.c
@@ -0,0 +1,409 @@
+/*++
+Copyright (c) 2010 WonderMedia Technologies, Inc.
+
+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, see http://www.gnu.org/licenses/>.
+
+WonderMedia Technologies, Inc.
+10F, 529, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C.
+--*/
+
+#if !defined(__CARD_H__)
+#include "card.h"
+#endif
+#if !defined(__SETUP_H__)
+#include "setup.h"
+#endif
+#if !defined(__ALLOCT_H__)
+#include "alloct.h"
+#endif
+
+#include <net.h>
+
+/* added by kevin */
+BOOL g_bInit = FALSE;
+unsigned int sg_i32GError_status;
+/*--------------------- Static Definitions -------------------------*/
+
+/*--------------------- Static Classes ----------------------------*/
+
+/*--------------------- Static Variables --------------------------*/
+
+/*--------------------- Static Functions --------------------------*/
+
+/* static BOOL s_bFind_ConfigGmac(); */
+/*--------------------- Export Variables --------------------------*/
+PVOID g_pvGBufferIndex = (PVOID)GMEMORY_BUFFER_START;
+
+SCmdParaSet sCmdPara;
+extern SAdapterOpts sOptions;
+/*--------------------- Export Functions --------------------------*/
+
+int
+gmac_startio(bd_t *bd)
+{
+ int ii;
+ UINT uTotalAdapterNum = 0;
+ int i32TotalAdapterNum = 0;
+ UINT uAdapterInWork = 0;
+ PSAdapterInfo apAdapter[MAX_NET_DEVICE];
+ UINT uSTAdapter, uEDAdapter;
+ PSAdapterInfo pAdapter;
+ static int gmac_init = 1;
+ DWORD isr_status;
+ int i;
+ BYTE Data;
+
+ if (gmac_init == 0) {
+ pAdapter = &sg_aGAdapter[0];
+ /* 2009/4/20-s add it for check port status change and re-enable MII auto-polling */
+ if (GMACbIsRegBitsOn(pAdapter->dwIoBase, MAC_REG_ISR1, 0x80))
+ {
+ VNSvOutPortB(0xd8004025, 0x80);
+ VNSvOutPortB(0xd8004070, 0x00);
+ VNSvOutPortB(0xd8004071, 0x80);
+ while(1)
+ {
+ VNSvInPortB(0xd800406d, &Data);
+ if(Data & 0x80)
+ break;
+ }
+ VNSvOutPortB(0xd8004070, 0x80);
+ }
+ /* 2009/4/20-e add it for check port status change and re-enable MII auto-polling */
+ if (GMACbIsRegBitsOn(pAdapter->dwIoBase, MAC_REG_ISR1, 0x20)) {
+ MACvReadISR(pAdapter->dwIoBase, &isr_status);
+ MACvWriteISR(pAdapter->dwIoBase, isr_status);
+ if (!GMACbSafeStop(pAdapter->dwIoBase, pAdapter->byRevId))
+ return FALSE;
+ GALCvChainRdrMemory(pAdapter);
+ GALCvChainTdrMemory(pAdapter, 0); /* chain first data segment */
+ /* set init rx/tx descriptor address into chip */
+ MACvSetDescBaseHi32(pAdapter->dwIoBase, 0UL);
+ MACvSetDbfBaseHi16(pAdapter->dwIoBase, 0U);
+ MACvSetRxDescBaseLo32(pAdapter->dwIoBase, pAdapter->amRxDescRing.dwPAddr);
+ MACvSetRqIndex(pAdapter->dwIoBase, 0);
+ MACvSetRqSize(pAdapter->dwIoBase, (WORD)(pAdapter->cbRD - 1));
+
+ for (i = 0; i < CB_TD_RING_NUM; i++) {
+ MACvSetTxDescBaseLo32(pAdapter->dwIoBase, pAdapter->aamTxDescRing[i].dwPAddr, i);
+ GMACvSetTqIndex(pAdapter->dwIoBase, (BYTE)i, 0);
+ }
+ MACvSetTqSize(pAdapter->dwIoBase, (WORD)(pAdapter->cbTD - 1));
+ /* set current rx/tx descriptor index to 0 */
+ pAdapter->uRxDequeDescIdx = 0;
+ for (i = 0; i < CB_TD_RING_NUM; i++) {
+ pAdapter->uTxEnqueDescIdx[i] = 0;
+ pAdapter->uTxDequeDescIdx[i] = 0;
+ }
+ pAdapter->idxRxPktStartDesc = 0;
+ MACvRxOn(pAdapter->dwIoBase);
+ MACvRxQueueRUN(pAdapter->dwIoBase);
+ MACvRxQueueWake(pAdapter->dwIoBase);
+ MACvTxOn(pAdapter->dwIoBase);
+ MACvTxQueueRUN(pAdapter->dwIoBase, 0);
+ }
+ /* 2009/4/20-s update mac address from ethaddr environment variable */
+ for(ii = 0; ii < U_ETHER_ADDR_LEN; ii++)
+ VNSvOutPortB(pAdapter->dwIoBase+MAC_REG_PAR+ii,bd->bi_enetaddr[ii]);
+ /* 2009/4/20-e update mac address from ethaddr environment variable */
+ return 1;
+ }
+ gmac_init = 0;
+
+ /* 1.Init option & parameter */
+ /*sOptions.ulInitCmds = INIT_CMD_FORCE_PHYRST;*/
+ sOptions.ulInitCmds = 0;
+ sOptions.iRDescNum = 64;
+ sOptions.iTDescNum = 64;
+ sOptions.bNoInit = FALSE;
+ /* set initial value of parameter set */
+ sCmdPara.uCardNum = 0;
+
+ /* 2.Confure PCI device configuration space */
+ /* s_bFind_ConfigGmac(); */
+
+ /* 3.Init adapter(find adapter) */
+ uTotalAdapterNum = GADPuInitAll();
+
+ if (uTotalAdapterNum == 0) {
+ printf("Cannot find the adapter or initialization is failed.\n");
+ freemem();
+ return -1;
+ }
+
+ if (uTotalAdapterNum > MAX_NET_DEVICE) {
+ printf("Cannot support over %d adapters.\n", MAX_NET_DEVICE);
+ freemem();
+ return -1;
+ }
+
+ /* determine if it's a multi-adapter initialization */
+ if (sCmdPara.uCardNum != 0) {
+ uSTAdapter = (sCmdPara.uCardNum-1);
+ uEDAdapter = uSTAdapter + 1;
+ } else {
+ uSTAdapter = 0;
+ uEDAdapter = uTotalAdapterNum;
+ }
+
+ for (ii = uSTAdapter; ii < uEDAdapter; ii++) {
+ /* WORD wEECheckSum; */
+ if (GMACbIsRegBitsOn(sg_aGAdapter[ii].dwIoBase, MAC_REG_CR0_SET, CR0_STRT)) {
+ /* printf("Adapter %d is already running!\n", ii); */
+ /* printf("\n"); */
+ }
+
+ /* Check if EEP-less strapping is wrong */
+ if (sg_aGAdapter[ii].byRevId >= 0x10) {
+ BOOL bEEPless;
+
+ /* check the EEPROM path strapping, 0 => serial EEPROM */
+ /* 1 => EEPROM from shadow */
+
+ if (sg_aGAdapter[ii].byRevId < REV_ID_VT3286_A1) {
+ bEEPless = GMACbIsRegBitsOn(
+ sg_aGAdapter[ii].dwIoBase,
+ MAC_REG_JMPSR1,
+ JMPSR1_J_VEESEL
+ );
+ } else {
+ bEEPless = GMACbIsRegBitsOn(
+ sg_aGAdapter[ii].dwIoBase,
+ MAC_REG_JMPSR1,
+ JMPSR1_J_VEESEL
+ );
+ }
+
+ if ((!bEEPless)) {
+ /* it means either customer do the wrong strapping (serial EEP to EEP-less)
+ or BIOS doesn't copy EEPROM content form persistent storage to shadow */
+ /* printf("Adapter %d EEP-less strapping check failed!\n", ii); */
+ printf("EEP-less strapping = TRUE\n");
+ /* freemem(); */
+ /* return ; */
+ } else {
+ if (GMACbIsRegBitsOff(sg_aGAdapter[ii].dwIoBase, MAC_REG_CHIPGSR, 0x10)) {
+ printf("Adapter %d EEPROM signature is not correct!\n", ii);
+ printf("\n");
+ freemem();
+ return -1;
+ }
+ }
+ } /* if */
+ } /* for */
+
+ /* 4.init MAC, MII, MIB, IRQ */
+ i32TotalAdapterNum = uTotalAdapterNum;
+ uTotalAdapterNum = 0;
+
+ for (ii = 0; ii < i32TotalAdapterNum; ii++) {
+ /* Start driver(create TD/RD and ISR) */
+ if (!GADPbBind(&sg_aGAdapter[ii])) {
+ printf("Initialize adapter fail.\n");
+ freemem();
+ return -1;
+ }
+ apAdapter[uAdapterInWork] = &sg_aGAdapter[ii];
+ uAdapterInWork++;
+ uTotalAdapterNum++;
+ }
+
+ if (uTotalAdapterNum == 0) {
+ printf("Cannot find the adapter or initialization is failed.\n");
+ freemem();
+ return -1;
+ }
+
+ /* Wait 2s for connection is stable... */
+ /* GMACvTimer0MiniSDelay(pAdapter->dwIoBase, pAdapter->byRevId, 3000); */
+ /* set parameter */
+ pAdapter = &sg_aGAdapter[0];
+ /* 2009/4/20-s update mac address from ethaddr environment variable */
+ for(ii = 0; ii < U_ETHER_ADDR_LEN; ii++)
+ VNSvOutPortB(pAdapter->dwIoBase+MAC_REG_PAR+ii,bd->bi_enetaddr[ii]);
+ /* 2009/4/20-e update mac address from ethaddr environment variable */
+ pAdapter->bTxOn = FALSE;
+ pAdapter->bRandomPktLength = FALSE;
+ pAdapter->bRandomPktData = FALSE;
+ pAdapter->bWhenRxCrcErrNoBuf = FALSE;
+ pAdapter->bWhenRxDataErrNoBuf = FALSE;
+ pAdapter->bIncPktLength = FALSE;
+ pAdapter->bSoftwareGenCrc = FALSE;
+ pAdapter->bTxSinglePacket = FALSE;
+ pAdapter->bTxContFunTest = FALSE;
+ /* clear statisic */
+ GSTAvClearAllCounter(&pAdapter->scStatistic);
+ /* set init rx/tx descriptor address into chip, it will return hw rd/td index to 0 */
+ MACvSetRqIndex(pAdapter->dwIoBase, 0);
+ GMACvSetTqIndex(pAdapter->dwIoBase, 0, 0);
+
+ /* start ISR, ISR should has enabled, but we want to make sure */
+ MACvIntEnable(pAdapter->dwIoBase, IMR_MASK_VALUE);
+ MACvStart(pAdapter->dwIoBase);
+ /* start rx */
+ MACvRxOn(pAdapter->dwIoBase);
+ MACvRxQueueRUN(pAdapter->dwIoBase);
+ MACvRxQueueWake(pAdapter->dwIoBase);
+ /* start tx */
+ MACvTxOn(pAdapter->dwIoBase);
+ MACvTxQueueRUN(pAdapter->dwIoBase, 0);
+
+ return 1;
+}
+
+/*
+static BOOL s_bFind_ConfigGmac()
+{
+ SPciDevice pciDevice3119;
+
+ // 1.allocate memory space
+ NPCIbPCIAlloc(NULL,W_VENDOR_ID,W_DEVICE_ID_3119A,&pciDevice3119);
+ return TRUE;
+}
+*/
+
+int gmac_send(volatile void *packet, int length)
+{
+ PBYTE pbyTxDescBuffer;
+ UINT uCurrTdIdx;
+ PSTxDesc pTD;
+ PSAdapterInfo pAdapter = &sg_aGAdapter[0];
+
+
+ uCurrTdIdx = pAdapter->uTxEnqueDescIdx[0];
+ pTD = pAdapter->aapTD[0][uCurrTdIdx];
+
+ /* if tx queue is full */
+ if (pTD->m_td0TD0.f1Owner == B_OWNED_BY_CHIP)
+ return FALSE;
+
+ /* copy buffer */
+ pbyTxDescBuffer = (PBYTE)(pAdapter->aapTD[0][uCurrTdIdx]->m_asTxBufs[0].dwTxBufAddrLo);
+ MEMvSet((PVOID)pbyTxDescBuffer, 0, 60);
+ MEMvCopy((PVOID)pbyTxDescBuffer, (PVOID)packet, length);
+
+ if (length < MIN_PACKET_LEN)
+ length = MIN_PACKET_LEN;
+
+ /* Set TD PktLen */
+ pTD->m_td0TD0.f14TxPktSize = (WORD)length;
+
+ /* set up data segment */
+ pTD->m_td1TD1.f4CMDZ = 2;
+ pTD->m_asTxBufs[0].f14TxBufSize = (WORD)length;
+
+ /*
+ * Set Qwner Bit and Que Bit
+ */
+ /* Get Last TdIdx */
+ UINT uLastTdIdx = (uCurrTdIdx + pAdapter->cbTD - 1) % pAdapter->cbTD;
+
+ /* Set last Td's que bit */
+ if (pAdapter->aapTD[0][uLastTdIdx]->m_td0TD0.f1Owner == B_OWNED_BY_CHIP) {
+ /* VT3119A0 */
+ /* vSetBit((PDWORD)(pAdapter->aapTD[byTxQue][uLastTdIdx])); */
+ /* VT3119A1 */
+ pAdapter->aapTD[0][uLastTdIdx]->m_asTxBufs[0].f1Que = B_TD_LIST_NOT_END;
+ }
+
+ /* set tx descriptors owner to chip */
+ pTD->m_td0TD0.f1Owner = B_OWNED_BY_CHIP;
+
+ /* post one TD */
+ pAdapter->auTxPktPosted[0]++;
+
+ /* Move EnqueTdIdx to next */
+ pAdapter->uTxEnqueDescIdx[0] = (WORD)((uCurrTdIdx + 1) % pAdapter->cbTD);
+
+ /* TX */
+ MACvTxOn(pAdapter->dwIoBase);
+ MACvTxQueueRUN(pAdapter->dwIoBase, 0);
+ MACvTxQueueWake(pAdapter->dwIoBase, 0);
+
+ return 0;
+}
+
+int gmac_receive(void)
+{
+ PSAdapterInfo pAdapter = &sg_aGAdapter[0];
+ int length = 0;
+ DWORD isr_status;
+ UINT uCurrDescIdx;
+ PSRxDesc pCurrRD;
+ BYTE byRsr0, byRsr1;
+
+ /* 1.store ISR */
+ MACvReadISR(pAdapter->dwIoBase, &isr_status);
+
+ /* 2.disable IMR */
+ MACvIntDisable(pAdapter->dwIoBase);
+ /* 3.clear ISR */
+ MACvWriteISR(pAdapter->dwIoBase, isr_status);
+ /* 4.handle received packets until owner==chip */
+ while (TRUE) {
+ uCurrDescIdx = pAdapter->uRxDequeDescIdx;
+ pCurrRD = pAdapter->apRD[uCurrDescIdx];
+ byRsr0 = pCurrRD->m_rd0RD0.byRSR0;
+ byRsr1 = pCurrRD->m_rd0RD0.byRSR1;
+
+ /* if the RD is owned by the chip, we are done. */
+ if (pCurrRD->m_rd0RD0.f1Owner == B_OWNED_BY_CHIP)
+ break;
+
+ if ((pCurrRD->m_rd0RD0.byRSR1 & RSR1_RXOK)) {
+ NetReceive((volatile uchar *)pCurrRD->m_dwRxBufAddrLo, pCurrRD->m_rd0RD0.f14RMBC-4);
+ length += (pCurrRD->m_rd0RD0.f14RMBC-4);
+ } else {
+ printf("receive error status:%02X %02X%\n",
+ pCurrRD->m_rd0RD0.byRSR1, pCurrRD->m_rd0RD0.byRSR0);
+ /* handler will do later */
+ }
+ /* reset RD own bit */
+ pCurrRD->m_rd0RD0.f1Owner = B_OWNED_BY_CHIP;
+
+ /* increase to next RD */
+ pAdapter->uRxDequeDescIdx = (++pAdapter->uRxDequeDescIdx)%pAdapter->cbRD;
+ }
+
+ /* 5.enable IMR */
+ MACvIntEnable(pAdapter->dwIoBase, IMR_MASK_VALUE);
+
+ return length;
+}
+
+void gmac_halt(void)
+{
+ if (g_bInit)
+ GADPbShutdown(&sg_aGAdapter[0]);
+ return;
+}
+
+void mii_read(char *devname, unsigned char addr,
+ unsigned char reg, unsigned short *value)
+{
+ PSAdapterInfo pAdapter;
+ pAdapter = &sg_aGAdapter[0];
+ GMIIbReadEmbeded(pAdapter->dwIoBase, pAdapter->byRevId, addr, value);
+#if MACDBG
+ printf("%02X %02X %04X\n", addr, reg, value);
+#endif
+}
+void mii_write(char *devname, unsigned char addr,
+ unsigned char reg, unsigned short value)
+{
+ PSAdapterInfo pAdapter;
+ pAdapter = &sg_aGAdapter[0];
+ GMIIbWriteEmbeded(pAdapter->dwIoBase, pAdapter->byRevId, addr, value);
+#if MACDBG
+ printf("%02X %02X %04X\n", addr, reg, value);
+#endif
+}
diff --git a/cpu/arm920t/wmt/gmacif.h b/cpu/arm920t/wmt/gmacif.h
new file mode 100755
index 0000000..db1c94e
--- /dev/null
+++ b/cpu/arm920t/wmt/gmacif.h
@@ -0,0 +1,64 @@
+/*++
+Copyright (c) 2010 WonderMedia Technologies, Inc.
+
+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, see http://www.gnu.org/licenses/>.
+
+WonderMedia Technologies, Inc.
+10F, 529, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C.
+--*/
+
+
+#ifndef _GMACIF_H_
+#define _GMACIF_H_
+
+
+/*--------------------- Export Definitions -------------------------*/
+#define BA_MAC0 0xd8004000 /* MAC0 Base Address */
+#define BA_MAC1 0xd8005000 /* MAC1 Base Address */
+#define GMEMORY_BUFFER_START 0x03C00000 /* Start address of allocated memory buffer */
+#define MAX_NET_DEVICE 4 /* max. # of the devices */
+#define W_MAX_TIMEOUT 0x0FFFU
+#define MACDBG 0 /* Switch to control debug message (0/1 = Disable/Enable) */
+
+#define PCI_Configuration_Space_Offset 0x100
+#define VEE 0x5c
+#define VMSTS 0x7c
+#define MaxTimeOut 1000
+
+#define __MMIO__
+/*--------------------- Export Types ------------------------------*/
+
+/*--------------------- Export Macros ------------------------------*/
+
+/*--------------------- Export Classes ----------------------------*/
+
+/*--------------------- Export Variables --------------------------*/
+
+/*--------------------- Export Functions --------------------------*/
+#ifdef __cplusplus
+extern "C" { /* Assume C declarations for C++ */
+#endif /* __cplusplus */
+
+#include <asm/u-boot.h>
+
+int gmac_startio(bd_t *bd);
+int gmac_send(volatile void *packet, int length);
+int gmac_receive(void);
+void gmac_halt(void);
+void mii_read(char *devname, unsigned char addr, unsigned char reg, unsigned short *value);
+void mii_write(char *devname, unsigned char addr, unsigned char reg, unsigned short value) ;
+
+#ifdef __cplusplus
+} /* End of extern "C" { */
+#endif /* __cplusplus */
+
+#endif /* _GMACIF_H_ */
diff --git a/cpu/arm920t/wmt/gmib.c b/cpu/arm920t/wmt/gmib.c
new file mode 100755
index 0000000..27a84a9
--- /dev/null
+++ b/cpu/arm920t/wmt/gmib.c
@@ -0,0 +1,453 @@
+/*++
+Copyright (c) 2010 WonderMedia Technologies, Inc.
+
+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, see http://www.gnu.org/licenses/>.
+
+WonderMedia Technologies, Inc.
+10F, 529, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C.
+--*/
+
+#if !defined(__MAC_H__)
+#include "mac.h"
+#endif
+#if !defined(__TBIT_H__)
+#include "tbit.h"
+#endif
+#if !defined(__MIB_H__)
+#include "mib.h"
+#endif
+
+/*--------------------- Static Definitions -------------------------*/
+
+/*--------------------- Static Classes ----------------------------*/
+
+/*--------------------- Static Variables --------------------------*/
+
+/*--------------------- Static Functions --------------------------*/
+
+/*--------------------- Export Variables --------------------------*/
+
+/*--------------------- Export Functions --------------------------*/
+
+VOID GSTAvClearAllCounter(PSStatCounter pStatistic)
+{
+ /* set memory to zero */
+ MEMvSet(pStatistic, 0, sizeof(SStatCounter));
+}
+
+VOID GSTAvClearAllSwMibCounter(PSMib2Counter pMib2Counter)
+{
+ /* set memory to zero */
+ /* Not work ??? */
+ /*ZERO_MEMORY(pMib2Counter, sizeof(PSMib2Counter)); */
+
+ pMib2Counter->ifOutOctets = 0;
+ pMib2Counter->ifOutNUcastPkts = 0;
+ pMib2Counter->ifOutUcastPkts = 0;
+ pMib2Counter->ifOutDiscards = 0;
+ pMib2Counter->ifOutErrors = 0;
+}
+
+VOID GSTAvUpdateEsrStatCounter(PSStatCounter pStatistic, BYTE byEsr, BOOL bTx)
+{
+ if (bTx) {
+ if (BITbIsBitOn(byEsr, TXESR_TDSTR))
+ pStatistic->dwTxEsrTDStrErr++;
+ if (BITbIsBitOn(byEsr, TXESR_TDRBS))
+ pStatistic->dwTxEsrTDRBusErr++;
+ if (BITbIsBitOn(byEsr, TXESR_TDWBS))
+ pStatistic->dwTxEsrTDWBusErr++;
+ if (BITbIsBitOn(byEsr, TXESR_TFDBS))
+ pStatistic->dwTxEsrDmaBusErr++;
+ } else {
+ if (BITbIsBitOn(byEsr, RXESR_RDSTR))
+ pStatistic->dwRxEsrRDStrErr++;
+ if (BITbIsBitOn(byEsr, RXESR_RDRBS))
+ pStatistic->dwRxEsrRDRBusErr++;
+ if (BITbIsBitOn(byEsr, RXESR_RDWBS))
+ pStatistic->dwRxEsrRDWBusErr++;
+ if (BITbIsBitOn(byEsr, RXESR_RFDBS))
+ pStatistic->dwRxEsrDmaBusErr++;
+ }
+}
+
+VOID GSTAvUpdateIsrStatCounter(PSStatCounter pStatistic, DWORD dwIsr, WORD wEsr)
+{
+ /*
+ * ABNORMAL interrupt
+ * not any IMR bit invoke irq
+ */
+ if (dwIsr == 0) {
+ pStatistic->dwIsrUnknown++;
+ return;
+ }
+
+ if (BITbIsBitOn(dwIsr, ISR_PRXI)) {
+ pStatistic->dwIsrRxOK++;
+ /* PATCH.... */
+ /* if rx OK, reset packet-race counter */
+ pStatistic->dwIsrContinuePktRace = 0;
+ /* if rx OK, reset no-buffer counter */
+ pStatistic->dwIsrContinueNoBuf = 0;
+ }
+ if (BITbIsBitOn(dwIsr, ISR_PTXI))
+ pStatistic->dwIsrTxOK++;
+
+ if (BITbIsBitOn(dwIsr, ISR_PPRXI))
+ pStatistic->dwIsrPRxOK++;
+ if (BITbIsBitOn(dwIsr, ISR_PPTXI))
+ pStatistic->dwIsrPTxOK++;
+
+ if (BITbIsBitOn(dwIsr, ISR_TXWB0I))
+ pStatistic->dwIsrTxWB0I++;
+ if (BITbIsBitOn(dwIsr, ISR_TXWB1I))
+ pStatistic->dwIsrTxWB1I++;
+
+ if (BITbIsBitOn(dwIsr, ISR_RACEI)) {
+ pStatistic->dwIsrRxPktRace++;
+ /* PATCH.... */
+ /* if irq continuous invoked by packet-race, plus counter */
+ pStatistic->dwIsrContinuePktRace++;
+ }
+ if (BITbIsBitOn(dwIsr, ISR_LSTEI)) {
+ pStatistic->dwIsrRxNoBuf++;
+ /* PATCH.... */
+ /* if irq continuous invoked by no-buffer, plus counter */
+ pStatistic->dwIsrContinueNoBuf++;
+ }
+
+ if (BITbIsBitOn(dwIsr, ISR_OVFI))
+ pStatistic->dwIsrRxFifoOvfl++;
+ if (BITbIsBitOn(dwIsr, ISR_FLONI))
+ pStatistic->dwIsrRxFlowOn++;
+
+ if (BITbIsBitOn(dwIsr, ISR_LSTPEI))
+ pStatistic->dwIsrRxNoBufP++;
+ if (BITbIsBitOn(dwIsr, ISR_SRCI))
+ pStatistic->dwIsrLinkStatusChg++;
+
+ /* update counters for MISR */
+ if (BITbIsBitOn(dwIsr, ISR_TMR0I))
+ pStatistic->dwMisrSoftTimer0++;
+ if (BITbIsBitOn(dwIsr, ISR_TMR1I))
+ pStatistic->dwMisrSoftTimer1++;
+ if (BITbIsBitOn(dwIsr, ISR_PWEI))
+ pStatistic->dwMisrPWE++;
+ if (BITbIsBitOn(dwIsr, ISR_PHYI))
+ pStatistic->dwMisrPhyStatChg++;
+ if (BITbIsBitOn(dwIsr, ISR_SHDNI))
+ pStatistic->dwMisrShutDown++;
+ if (BITbIsBitOn(dwIsr, ISR_MIBFI))
+ pStatistic->dwMisrMibOvfl++;
+ if (BITbIsBitOn(dwIsr, ISR_UDPI))
+ pStatistic->dwMisrUserDef++;
+
+ if (BITbIsBitOn(dwIsr, ISR_TXSTLI)) {
+ pStatistic->dwMisrTxDmaErr++;
+ GSTAvUpdateEsrStatCounter(pStatistic, (BYTE)wEsr, TRUE);
+ }
+ if (BITbIsBitOn(dwIsr, ISR_RXSTLI)) {
+ pStatistic->dwMisrRxDmaErr++;
+ GSTAvUpdateEsrStatCounter(pStatistic, (BYTE)(wEsr>>8), FALSE);
+ }
+}
+
+VOID GSTAvUpdateRDStatCounter(
+ PSStatCounter pStatistic,
+ PSRxDesc prdCurr,
+ PBYTE pbyBuffer,
+ UINT cbFrameLength
+ )
+{
+ pbyBuffer = pbyBuffer;
+ BYTE byRSR0 = prdCurr->m_rd0RD0.byRSR0;
+ BYTE byRSR1 = prdCurr->m_rd0RD0.byRSR1;
+
+ /* increase rx packet count */
+ pStatistic->dwRsrRxPacket++;
+ pStatistic->dwRsrRxOctet += cbFrameLength;
+
+ if (BITbIsBitOn(byRSR0, RSR0_CRC))
+ pStatistic->dwRsrCRCErr++;
+ if (BITbIsBitOn(byRSR0, RSR0_FAE))
+ pStatistic->dwRsrFrmAlgnErr++;
+ if (BITbIsBitOn(byRSR0, RSR0_CE))
+ pStatistic->dwRsrCheckSumErr++;
+ if (BITbIsBitOn(byRSR0, RSR0_RL))
+ pStatistic->dwRsrLengthErr++;
+ if (BITbIsBitOn(byRSR0, RSR0_RXER))
+ pStatistic->dwRsrPCSSymErr++;
+ if (BITbIsBitOn(byRSR0, RSR0_SNTAG))
+ pStatistic->dwRsrSNTAG++;
+ if (BITbIsBitOn(byRSR0, RSR0_DETAG))
+ pStatistic->dwRsrDETAG++;
+
+ if (BITbIsBitOn(byRSR1, RSR1_RXOK))
+ pStatistic->dwRsrOK++;
+
+ if (BITbIsBitOn(byRSR1, RSR1_VTAG))
+ pStatistic->dwRsrRxTagFrame = (DWORD)(prdCurr->m_rd1RD1.wPQTAG);
+ else
+ pStatistic->dwRsrRxTagFrame = 0x0;
+
+ if (BITbIsBitOn(byRSR1, RSR0_VIDM))
+ pStatistic->dwRsrVIDMiss++;
+
+ if (BITbIsBitOn(byRSR1, RSR1_VTAG))
+ pStatistic->dwRsrRxTag++;
+
+ if (BITbIsBitOn(byRSR1, RSR1_PFT))
+ pStatistic->dwRsrPerfectMatch++;
+
+ if (cbFrameLength >= U_ETHER_ADDR_LEN) {
+ /*
+ if (IS_BROADCAST_ADDRESS(pbyBuffer))
+ pStatistic->dwRsrBroadcast++;
+ else if (IS_MULTICAST_ADDRESS(pbyBuffer))
+ pStatistic->dwRsrMulticast++;
+ else
+ pStatistic->dwRsrDirected++;
+ */
+ if (BITbIsBitOn(byRSR1, RSR1_BAR))
+ pStatistic->dwRsrBroadcast++;
+ if (BITbIsBitOn(byRSR1, RSR1_MAR))
+ pStatistic->dwRsrMulticast++;
+ if (BITbIsBitOn(byRSR1, RSR1_PHY))
+ pStatistic->dwRsrDirected++;
+ }
+
+ if (cbFrameLength == MIN_PACKET_LEN + 4)
+ pStatistic->dwRsrRxFrmLen64++;
+ else if ((65 <= cbFrameLength) && (cbFrameLength <= 127))
+ pStatistic->dwRsrRxFrmLen65_127++;
+ else if ((128 <= cbFrameLength) && (cbFrameLength <= 255))
+ pStatistic->dwRsrRxFrmLen128_255++;
+ else if ((256 <= cbFrameLength) && (cbFrameLength <= 511))
+ pStatistic->dwRsrRxFrmLen256_511++;
+ else if ((512 <= cbFrameLength) && (cbFrameLength <= 1023))
+ pStatistic->dwRsrRxFrmLen512_1023++;
+ else if ((1024 <= cbFrameLength) && (cbFrameLength <= MAX_PACKET_LEN + 4))
+ pStatistic->dwRsrRxFrmLen1024_1518++;
+}
+
+VOID GSTAvUpdateRDStatCounterEx(
+ PSStatCounter pStatistic,
+ PSRxDesc prdCurr,
+ PBYTE pbyBuffer,
+ UINT cbFrameLength,
+ DWORD dwHwCRC32,
+ DWORD dwSwCRC32
+ )
+{
+ GSTAvUpdateRDStatCounter(pStatistic, prdCurr, pbyBuffer, cbFrameLength);
+
+ /* rx length */
+ pStatistic->dwCntRxFrmLength = cbFrameLength;
+ /* Rx Hardware generate CRC32 */
+ pStatistic->dwHwCRC32 = dwHwCRC32;
+ /* Rx Software generate CRC32 */
+ pStatistic->dwSwCRC32 = dwSwCRC32;
+
+ /* DRV32.LIB [1.05] */
+ if ((dwHwCRC32 != dwSwCRC32) &&
+ (dwSwCRC32 != 0x00000000UL))
+ pStatistic->dwCntRxDataErr++;
+
+ /* rx pattern, we just see 16 bytes for sample */
+ MEMvCopy((PVOID)pStatistic->abyCntRxPattern, (PVOID)pbyBuffer, 16);
+}
+
+VOID GSTAvUpdateTDStatCounter(
+ PSStatCounter pStatistic,
+ PSMib2Counter pMib2Counter,
+ PSTxDesc ptdCurr,
+ PBYTE pbyBuffer,
+ UINT cbFrameLength
+ )
+{
+ BYTE byTSR0 = ptdCurr->m_td0TD0.byTSR0;
+ BYTE byTSR1 = ptdCurr->m_td0TD0.byTSR1;
+
+ /* increase tx packet count */
+ pStatistic->dwTsrTxPacket++;
+ pStatistic->dwTsrTxOctet += cbFrameLength;
+ pMib2Counter->ifOutOctets += cbFrameLength;
+
+ if (BITbIsBitOn(byTSR0, TSR0_COLS)) {
+ pStatistic->dwTsrCollision++;
+ pStatistic->dwTsrTotalColRetry += (byTSR0 & 0x0F);
+
+ if ((byTSR0 & 0x0F) == 1)
+ pStatistic->dwTsrOnceCollision++;
+ else
+ pStatistic->dwTsrMoreThanOnceCollision++;
+ }
+
+ if (BITbIsBitOff(byTSR1, TSR1_TERR | TSR1_LNKFL | TSR1_CRS | TSR1_CDH))
+ pStatistic->dwTsrOK++;
+ else {
+ if (BITbIsBitOn(byTSR0, TSR0_ABT))
+ pStatistic->dwTsrAbort++;
+ if (BITbIsBitOn(byTSR0, TSR0_OWC))
+ pStatistic->dwTsrLateCollision++;
+ if (BITbIsBitOn(byTSR0, TSR0_OWT))
+ pStatistic->dwTsrJumboAbort++;
+
+ if (BITbIsBitOn(byTSR1, TSR1_CDH))
+ pStatistic->dwTsrHeartBeat++;
+ if (BITbIsBitOn(byTSR1, TSR1_CRS))
+ pStatistic->dwTsrCarrierLost++;
+ if (BITbIsBitOn(byTSR1, TSR1_LNKFL))
+ pStatistic->dwTsrLNKFL++;
+ if (BITbIsBitOn(byTSR1, TSR1_SHDN))
+ pStatistic->dwTsrShutDown++;
+ if (BITbIsBitOn(byTSR1, TSR1_TERR))
+ pStatistic->dwTsrErr++;
+ }
+
+ if (cbFrameLength >= U_ETHER_ADDR_LEN) {
+ if (IS_BROADCAST_ADDRESS(pbyBuffer)) {
+ pStatistic->dwTsrBroadcast++;
+ pMib2Counter->ifOutNUcastPkts++;
+ } else if (IS_MULTICAST_ADDRESS(pbyBuffer)) {
+ pStatistic->dwTsrMulticast++;
+ pMib2Counter->ifOutNUcastPkts++;
+ } else {
+ pStatistic->dwTsrDirected++;
+ pMib2Counter->ifOutUcastPkts++;
+ }
+ }
+}
+
+VOID GSTAvUpdateTDStatCounterEx(
+ PSStatCounter pStatistic,
+ PSMib2Counter pMib2Counter,
+ PSTxDesc ptdCurr,
+ PBYTE pbyBuffer,
+ DWORD cbFrameLength
+ )
+{
+ UINT uPktLength = (UINT)cbFrameLength;
+
+ GSTAvUpdateTDStatCounter(pStatistic, pMib2Counter, ptdCurr, pbyBuffer, uPktLength);
+
+ /* tx length */
+ pStatistic->dwCntTxBufLength = uPktLength;
+ /* tx pattern, we just see 16 bytes for sample */
+ MEMvCopy((PVOID)pStatistic->abyCntTxPattern, (PVOID)pbyBuffer, 16);
+}
+
+VOID GSTAvUpdateTDStatCounterTq0(
+ PSStatCounter pStatistic,
+ PSTxDesc ptdCurr,
+ PBYTE pbyBuffer,
+ UINT cbFrameLength
+ )
+{
+ BYTE byTSR0 = ptdCurr->m_td0TD0.byTSR0;
+ BYTE byTSR1 = ptdCurr->m_td0TD0.byTSR1;
+ UINT uPktLength = (UINT)cbFrameLength;
+
+ /* tx length */
+ pStatistic->dwCntTxBufLength = uPktLength;
+ /* tx pattern, we just see 16 bytes for sample */
+ MEMvCopy((PVOID)pStatistic->abyCntTxPattern, (PVOID)pbyBuffer, 16);
+
+ /* increase tx packet count */
+ pStatistic->dwTsrTxPacket++;
+ pStatistic->dwTsrTxOctet += cbFrameLength;
+
+ if (BITbIsBitOn(byTSR0, TSR0_COLS)) {
+ pStatistic->dwTsrCollision++;
+ pStatistic->dwTsrTotalColRetry += (byTSR0 & 0x0F);
+
+ if ((byTSR0 & 0x0F) == 1)
+ pStatistic->dwTsrOnceCollision++;
+ else
+ pStatistic->dwTsrMoreThanOnceCollision++;
+ }
+
+ if (BITbIsBitOff(byTSR1, TSR1_TERR | TSR1_LNKFL | TSR1_CRS | TSR1_CDH))
+ pStatistic->dwTsrOK++;
+ else {
+ if (BITbIsBitOn(byTSR0, TSR0_ABT))
+ pStatistic->dwTsrAbort++;
+ if (BITbIsBitOn(byTSR0, TSR0_OWC))
+ pStatistic->dwTsrLateCollision++;
+ if (BITbIsBitOn(byTSR0, TSR0_OWT))
+ pStatistic->dwTsrJumboAbort++;
+
+ if (BITbIsBitOn(byTSR1, TSR1_CDH))
+ pStatistic->dwTsrHeartBeat++;
+ if (BITbIsBitOn(byTSR1, TSR1_CRS))
+ pStatistic->dwTsrCarrierLost++;
+ if (BITbIsBitOn(byTSR1, TSR1_LNKFL))
+ pStatistic->dwTsrLNKFL++;
+ if (BITbIsBitOn(byTSR1, TSR1_SHDN))
+ pStatistic->dwTsrShutDown++;
+ if (BITbIsBitOn(byTSR1, TSR1_TERR))
+ pStatistic->dwTsrErr++;
+ }
+
+ if (cbFrameLength >= U_ETHER_ADDR_LEN) {
+ if (IS_BROADCAST_ADDRESS(pbyBuffer))
+ pStatistic->dwTsrBroadcast++;
+ else if (IS_MULTICAST_ADDRESS(pbyBuffer))
+ pStatistic->dwTsrMulticast++;
+ else
+ pStatistic->dwTsrDirected++;
+ }
+}
+
+VOID GSTAvClearHWMIBCounter(DWORD dwIoBase)
+{
+ MACvRegBitsOn(dwIoBase, MAC_REG_MIBCR, MIBCR_MIBFRZ);
+ MACvRegBitsOn(dwIoBase, MAC_REG_MIBCR, MIBCR_MIBCLR);
+ /* wait until MIB counter clear done */
+ while (TRUE) {
+ if (GMACbIsRegBitsOff(dwIoBase, MAC_REG_MIBCR, MIBCR_MIBCLR))
+ break;
+ }
+}
+
+VOID GSTAvEnableHWMIBCounter(DWORD dwIoBase)
+{
+ MACvRegBitsOff(dwIoBase, MAC_REG_MIBCR, MIBCR_MIBFRZ);
+}
+
+VOID GSTAvDisableHWMIBCounter(DWORD dwIoBase)
+{
+ MACvRegBitsOn(dwIoBase, MAC_REG_MIBCR, MIBCR_MIBFRZ);
+}
+
+VOID GSTAvUpdateHWMIBCounter(DWORD dwIoBase, PSHWMibCounter psHWCounters)
+{
+ DWORD dwTmp = 0;
+ PDWORD pdwTmp = (PDWORD)psHWCounters;
+ int ii;
+ /* flush real-time counter value to MIB SRAM */
+ MACvRegBitsOn(dwIoBase, MAC_REG_MIBCR, MIBCR_MIBFLSH);
+
+ /* wait until flush done */
+ while (TRUE) {
+ if (GMACbIsRegBitsOff(dwIoBase, MAC_REG_MIBCR, MIBCR_MIBFLSH))
+ break;
+ }
+
+ /* return MIB pointer to 0 */
+ MACvRegBitsOn(dwIoBase, MAC_REG_MIBCR, MIBCR_MPTRINI);
+
+ for (ii = 0; ii < MAX_HW_MIB_COUNTER; ii++, pdwTmp++) {
+ VNSvInPortD(dwIoBase + MAC_REG_MIBREAD, &dwTmp);
+ *pdwTmp += dwTmp & 0x00FFFFFFUL;
+ }
+}
diff --git a/cpu/arm920t/wmt/gmii.c b/cpu/arm920t/wmt/gmii.c
new file mode 100755
index 0000000..10fc27b
--- /dev/null
+++ b/cpu/arm920t/wmt/gmii.c
@@ -0,0 +1,535 @@
+/*++
+Copyright (c) 2010 WonderMedia Technologies, Inc.
+
+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, see http://www.gnu.org/licenses/>.
+
+WonderMedia Technologies, Inc.
+10F, 529, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C.
+--*/
+
+/* #include <conio.h> */
+
+/* #if !defined(__UPC_H__) */
+/* #include "upc.h" */
+/* #endif */
+#if !defined(__UASSERT_H__)
+#include "uassert.h"
+#endif
+/* #if !defined(__TMACRO_H__) */
+/* #include "tmacro.h" */
+/* #endif */
+#if !defined(__TBIT_H__)
+#include "tbit.h"
+#endif
+#if !defined(__MAC_H__)
+#include "mac.h"
+#endif
+#if !defined(__MII_H__)
+#include "mii.h"
+#endif
+
+/*--------------------- Static Definitions -------------------------*/
+#define CB_DELAY_MII_LB_STABLE (1000)
+
+/*--------------------- Static Classes ----------------------------*/
+
+/*--------------------- Static Variables --------------------------*/
+
+/*--------------------- Static Functions --------------------------*/
+
+/*--------------------- Export Variables --------------------------*/
+
+/*--------------------- Export Functions --------------------------*/
+
+/*
+ * Description: Read a word from MII, by embeded programming
+ *
+ * Parameters:
+ * In:
+ * dwIoBase - I/O base address
+ * byRevId - chip revision id
+ * byMiiAddr - address of register in MII
+ * Out:
+ * pwData - data read
+ *
+ * Return Value: TRUE if succeeded; FALSE if failed.
+ *
+ */
+BOOL GMIIbReadEmbeded(DWORD dwIoBase, BYTE byRevId, BYTE byMiiAddr, PWORD pwData)
+{
+ byRevId = byRevId;
+ WORD ww;
+
+ /* disable MIICR_MAUTO, so that mii addr can be set normally */
+ GMACvDisableMiiAutoPoll(dwIoBase);
+
+ /* MII reg offset */
+ VNSvOutPortB(dwIoBase + MAC_REG_MIIADR, byMiiAddr);
+
+ /* turn on MIICR_RCMD */
+ MACvRegBitsOn(dwIoBase, MAC_REG_MIICR, MIICR_RCMD);
+
+ /* W_MAX_TIMEOUT is the timeout period */
+ for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
+ udelay(1000);
+ if (BITbIsBitOff(GMACbyReadMIICR(dwIoBase), MIICR_RCMD))
+ break;
+ }
+
+ /* get MII data */
+ VNSvInPortW(dwIoBase + MAC_REG_MIIDATA, pwData);
+
+ GMACvEnableMiiAutoPoll(dwIoBase);
+
+ if (ww == W_MAX_TIMEOUT)
+ return FALSE;
+
+ return TRUE;
+}
+
+/*
+ * Description: Write a word to MII, by embeded programming
+ *
+ * Parameters:
+ * In:
+ * dwIoBase - I/O base address
+ * byRevId - chip revision id
+ * byMiiAddr - address of register in MII
+ * wData - data to write
+ *
+ * Return Value: TRUE if succeeded; FALSE if failed.
+ *
+ */
+BOOL GMIIbWriteEmbeded(DWORD dwIoBase, BYTE byRevId, BYTE byMiiAddr, WORD wData)
+{
+ byRevId = byRevId;
+ WORD ww;
+
+ /* disable MIICR_MAUTO, so that mii addr can be set normally */
+ GMACvDisableMiiAutoPoll(dwIoBase);
+
+ /* MII reg offset */
+ VNSvOutPortB(dwIoBase + MAC_REG_MIIADR, byMiiAddr);
+
+ /* set MII data */
+ VNSvOutPortW(dwIoBase + MAC_REG_MIIDATA, wData);
+
+ /* turn on MIICR_WCMD */
+ MACvRegBitsOn(dwIoBase, MAC_REG_MIICR, MIICR_WCMD);
+
+ /* W_MAX_TIMEOUT is the timeout period */
+ for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
+ udelay(1000);
+ if (BITbIsBitOff(GMACbyReadMIICR(dwIoBase), MIICR_WCMD))
+ break;
+ }
+
+ GMACvEnableMiiAutoPoll(dwIoBase);
+
+ if (ww == W_MAX_TIMEOUT)
+ return FALSE;
+
+ return TRUE;
+}
+
+BOOL GMIIbIsRegBitsOn(DWORD dwIoBase, BYTE byRevId, BYTE byMiiAddr, WORD wTestBits)
+{
+ static WORD wOrgData;
+
+ GMIIbReadEmbeded(dwIoBase, byRevId, byMiiAddr, &wOrgData);
+ return BITbIsAllBitsOn(wOrgData, wTestBits);
+}
+
+BOOL GMIIbIsRegBitsOff(DWORD dwIoBase, BYTE byRevId, BYTE byMiiAddr, WORD wTestBits)
+{
+ static WORD wOrgData;
+
+ GMIIbReadEmbeded(dwIoBase, byRevId, byMiiAddr, &wOrgData);
+ return BITbIsAllBitsOff(wOrgData, wTestBits);
+}
+
+BOOL GMIIbReadAllRegs(DWORD dwIoBase, BYTE byRevId, PSMiiReg pMiiRegs)
+{
+ UINT ii;
+ PWORD pwData;
+ UINT cbWords;
+
+ pwData = (PWORD)pMiiRegs;
+ cbWords = sizeof(SMiiReg) / sizeof(WORD);
+
+ /* ii = Reg Address */
+ for (ii = 0; ii < cbWords; ii++) {
+ if (!GMIIbReadEmbeded(dwIoBase, byRevId, (BYTE)ii, pwData))
+ return FALSE;
+ pwData++;
+ }
+
+ return TRUE;
+}
+
+VOID GMIIvWaitForNwayCompleted(DWORD dwIoBase, BYTE byRevId)
+{
+ UINT uu;
+
+ /* delay about 8 sec. */
+ /* wait for AUTO-NEGO to complete (may never complete if */
+ /* no link), after that then, we can get correct link status */
+ /* NOTE: because I have no timer, so looping is used, */
+ /* if timer is available in your OS, use timer */
+ /* in stead of looping */
+
+ /* wait for BMSR_AUTOCM to off */
+ for (uu = 0; uu < CB_MAX_COUNT_AUTO_COMPLETE; uu++) {
+ if (GMIIbIsRegBitsOff(dwIoBase, byRevId, MII_REG_BMSR, BMSR_AUTOCM))
+ break;
+ }
+ /* wait for BMSR_AUTOCM to on */
+ /* NOTE.... read BMSR_AUTOCM bit will also clear BMSR_LNK bit */
+ for (uu = 0; uu < CB_MAX_COUNT_AUTO_COMPLETE; uu++) {
+ /* if AUTO-NEGO completed, then go out this loop */
+ /* otherwise, count down to time out */
+ if (GMIIbIsRegBitsOn(dwIoBase, byRevId, MII_REG_BMSR, BMSR_AUTOCM))
+ break;
+ }
+}
+
+VOID GMIIvSetLoopbackMode(DWORD dwIoBase, BYTE byRevId, BYTE byLoopbackMode)
+{
+ /* handle AUTO-NEGO */
+ switch (byLoopbackMode) {
+ case MII_LB_NONE:
+ if(GMIIbIsRegBitsOn(dwIoBase, byRevId, MII_REG_BMCR, BMCR_LBK)) {
+ /* turn off MII loopback */
+ MIIvRegBitsOff(dwIoBase, byRevId, MII_REG_BMCR, BMCR_LBK);
+ /* must turn on AUTO-NEGO after turn off BMCR_LBK, otherwise */
+ /* the AUTO-NEGO process will never end in some PHY (e.g. ESI...) */
+ MIIvSetAutoNegotiationOn(dwIoBase, byRevId);
+ }/* else do not thing */
+ break;
+
+ case MII_LB_INTERNAL:
+ MIIvSetAutoNegotiationOff(dwIoBase, byRevId);
+ MIIvRegBitsOn(dwIoBase, byRevId, MII_REG_BMCR, BMCR_LBK);
+ /* select 1000M */
+ MIIvRegBitsOn(dwIoBase, byRevId, MII_REG_BMCR, BMCR_SPEED1G);
+ MIIvRegBitsOff(dwIoBase, byRevId, MII_REG_BMCR, BMCR_SPEED100);
+ break;
+
+ case MII_LB_ISO:
+ /* we achieve isolation by do loopback in MII not in Transceiver */
+ MIIvSetAutoNegotiationOff(dwIoBase, byRevId);
+ MIIvRegBitsOn(dwIoBase, byRevId, MII_REG_BMCR, BMCR_LBK);
+ /* select 1000M */
+ MIIvRegBitsOn(dwIoBase, byRevId, MII_REG_BMCR, BMCR_SPEED1G);
+ MIIvRegBitsOff(dwIoBase, byRevId, MII_REG_BMCR, BMCR_SPEED100);
+ break;
+
+ default:
+ DBG_ASSERT(FALSE);
+ break;
+ }
+
+ /* wait for MII loopback to stable */
+ PCAvDelayByIO(CB_DELAY_MII_LB_STABLE);
+}
+
+VOID GMIIvSetDuplexMode(DWORD dwIoBase, BYTE byRevId, BOOL bFullDuplexOn)
+{
+ /* when force duplex mode, */
+ /* AUTO-NEGO should off */
+ MIIvSetAutoNegotiationOff(dwIoBase, byRevId);
+
+ if (bFullDuplexOn)
+ MIIvRegBitsOn(dwIoBase, byRevId, MII_REG_BMCR, BMCR_FDX);
+ else
+ MIIvRegBitsOff(dwIoBase, byRevId, MII_REG_BMCR, BMCR_FDX);
+}
+
+VOID GMIIvSetSpeedMode(DWORD dwIoBase, BYTE byRevId, BYTE bySpeed)
+{
+ /* when force speed mode, */
+ /* AUTO-NEGO should off */
+ MIIvSetAutoNegotiationOff(dwIoBase, byRevId);
+
+ switch (bySpeed) {
+ case MII_SPD_1000:
+ MIIvRegBitsOn(dwIoBase, byRevId, MII_REG_BMCR, BMCR_SPEED1G);
+ MIIvRegBitsOff(dwIoBase, byRevId, MII_REG_BMCR, BMCR_SPEED100);
+ break;
+ case MII_SPD_100:
+ MIIvRegBitsOff(dwIoBase, byRevId, MII_REG_BMCR, BMCR_SPEED1G);
+ MIIvRegBitsOn(dwIoBase, byRevId, MII_REG_BMCR, BMCR_SPEED100);
+ break;
+ case MII_SPD_10:
+ MIIvRegBitsOff(dwIoBase, byRevId, MII_REG_BMCR, BMCR_SPEED1G);
+ MIIvRegBitsOff(dwIoBase, byRevId, MII_REG_BMCR, BMCR_SPEED100);
+ break;
+
+ default:
+ DBG_ASSERT(FALSE);
+ break;
+ }
+}
+
+BOOL GMIIbIsAutoNegotiationOn(DWORD dwIoBase, BYTE byRevId)
+{
+ return GMIIbIsRegBitsOn(dwIoBase, byRevId, MII_REG_BMCR, BMCR_AUTO);
+}
+
+/*
+BOOL MIIbIsInFullDuplexMode(DWORD dwIoBase, BYTE byRevId)
+{
+ // if in AUTO-NEGO mode
+ if (byRevId>=REV_ID_VT3106J_A0)
+ return MACbIsRegBitsOn(dwIoBase, MAC_REG_MIISR, MIISR_N_FDX);
+
+ if (MIIbIsAutoNegotiationOn(dwIoBase, byRevId)) {
+
+ // if my TX_FD on, check both TX_FD
+ if (MIIbIsRegBitsOn(dwIoBase, byRevId, MII_REG_ANAR, ANAR_TXFD)) {
+ // partner's TX_FD
+ if (MIIbIsRegBitsOn(dwIoBase, byRevId, MII_REG_ANLPAR, ANLPAR_TXFD))
+ return TRUE;
+ }
+
+ // if my T4 on, check both T4
+ if (MIIbIsRegBitsOn(dwIoBase, byRevId, MII_REG_ANAR, ANAR_T4)) {
+ // partner's T4
+ if (MIIbIsRegBitsOn(dwIoBase, byRevId, MII_REG_ANLPAR, ANLPAR_T4))
+ return FALSE;
+ }
+
+ // if my TX_HD on, check both TX_HD
+ if (MIIbIsRegBitsOn(dwIoBase, byRevId, MII_REG_ANAR, ANAR_TX)) {
+ // partner's TX_HD
+ if (MIIbIsRegBitsOn(dwIoBase, byRevId, MII_REG_ANLPAR, ANLPAR_TX))
+ return FALSE;
+ }
+
+ // if my 10_FD on, check both 10_FD
+ if (MIIbIsRegBitsOn(dwIoBase, byRevId, MII_REG_ANAR, ANAR_10FD)) {
+ // partner's 10_FD
+ if (MIIbIsRegBitsOn(dwIoBase, byRevId, MII_REG_ANLPAR, ANLPAR_10FD))
+ return TRUE;
+ }
+
+ // if all above is not, then it would be 10_HD or no link
+ // both case will be half duplex
+ return FALSE;
+ } else {
+ // if in force mode
+ if (MIIbIsRegBitsOff(dwIoBase, byRevId, MII_REG_BMCR, BMCR_FDX))
+ return FALSE;
+ }
+
+ return TRUE;
+}
+*/
+
+BOOL GMIIbSafeSoftwareReset(DWORD dwIoBase, BYTE byRevId)
+{
+ WORD ww;
+
+ /* turn on reset only, do not write other bits */
+ GMIIbWriteEmbeded(dwIoBase, byRevId, MII_REG_BMCR, BMCR_RESET);
+
+ /* polling till MII reset complete */
+ /* W_MAX_TIMEOUT is the timeout period */
+ for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
+ if (GMIIbIsRegBitsOff(dwIoBase, byRevId, MII_REG_BMCR, BMCR_RESET))
+ break;
+ }
+
+ if (ww == W_MAX_TIMEOUT)
+ return FALSE;
+
+ return TRUE;
+}
+
+/*
+ * Description: Scan how many PHY in MII bus, and put PYH id
+ * in the pbyPhyId array
+ *
+ * Parameters:
+ * In:
+ * dwIoBase - I/O base address
+ * byRevId - chip revision id
+ * Out:
+ * puTotalPhyNum - total # of PHY
+ * pbyPhyId - PHY id array
+ *
+ * NOTE: size of pbyPhyId should larger than MAX_PHY_DEVICE
+ * otherwise, memory will corrupt
+ *
+ * Return Value: TRUE if succeeded; FALSE if failed.
+ *
+ */
+VOID GMIIvScanAllPhy(DWORD dwIoBase, BYTE byRevId, PBYTE pbyPhyId, PUINT puTotalPhyNum)
+{
+ BYTE byOrgMIIADR;
+ BYTE byOrgMIICR;
+ DWORD dwPhyCmrId;
+ UINT uPhyArrayIdx;
+ BYTE byPhyId, byOrgPhyId;
+
+ /* keep original MIICR value */
+ VNSvInPortB(dwIoBase + MAC_REG_MIIADR, &byOrgMIIADR);
+ VNSvInPortB(dwIoBase + MAC_REG_MIICR, &byOrgMIICR);
+
+ /* disable MIICR_MAUTO, so that mii addr can be set normally */
+ GMACvDisableMiiAutoPoll(dwIoBase);
+
+ /* keep original phy ID */
+ byOrgPhyId = GMACbyGetPhyId(dwIoBase);
+
+ /* scan all PHY */
+ uPhyArrayIdx = 0;
+ /* PHI id 0 is not a valid id */
+ for (byPhyId = 1; byPhyId < MAX_PHY_DEVICE; byPhyId++) {
+ GMACvSetPhyId(dwIoBase, byRevId, byPhyId);
+
+ /* detect if PHY exist? */
+ MIIvReadPhyCmrId(dwIoBase, byRevId, &dwPhyCmrId);
+ if ((dwPhyCmrId != 0xFFFFFFFFUL) && (dwPhyCmrId != 0UL)) {
+ pbyPhyId[uPhyArrayIdx] = byPhyId;
+ uPhyArrayIdx++;
+ }
+ }
+ *puTotalPhyNum = uPhyArrayIdx;
+
+ /* restore original phy id */
+ GMACvSetPhyId(dwIoBase, byRevId, byOrgPhyId);
+
+ /* restore MIICR */
+ VNSvOutPortB(dwIoBase + MAC_REG_MIIADR, byOrgMIIADR);
+ VNSvOutPortB(dwIoBase + MAC_REG_MIICR, byOrgMIICR);
+}
+
+VOID GMIIvSetActiveForcedPhy(DWORD dwIoBase, BYTE byRevId, PBYTE pbyPhyId, UINT uTotalPhyNum, BYTE byPhyId)
+{
+ UINT uu;
+ BYTE byOrgMIIADR;
+ BYTE byOrgMIICR;
+
+ /* keep original MIICR value */
+ VNSvInPortB(dwIoBase + MAC_REG_MIIADR, &byOrgMIIADR);
+ VNSvInPortB(dwIoBase + MAC_REG_MIICR, &byOrgMIICR);
+
+ /* disable MIICR_MAUTO, so that mii addr can be set normally */
+ GMACvDisableMiiAutoPoll(dwIoBase);
+
+ /* iso all PHY */
+ for (uu = 0; uu < uTotalPhyNum; uu++) {
+ GMACvSetPhyId(dwIoBase, byRevId, pbyPhyId[uu]);
+ MIIvRegBitsOn(dwIoBase, byRevId, MII_REG_BMCR, BMCR_ISO);
+ }
+
+ /* finally, set correct PHY id */
+ GMACvSetPhyId(dwIoBase, byRevId, byPhyId);
+ /* active this PHY */
+ MIIvRegBitsOff(dwIoBase, byRevId, MII_REG_BMCR, BMCR_ISO);
+
+ /* restore MIICR */
+ VNSvOutPortB(dwIoBase + MAC_REG_MIIADR, byOrgMIIADR);
+ VNSvOutPortB(dwIoBase + MAC_REG_MIICR, byOrgMIICR);
+}
+
+/* if no PHY linked, return FALSE */
+BOOL GMIIbSetActiveLinkedPhy(DWORD dwIoBase, BYTE byRevId, PBYTE pbyPhyId, UINT uTotalPhyNum)
+{
+ BOOL bRetVal = FALSE;
+ UINT uu;
+ BYTE byActPhyId, byOrgPhyId;
+ BYTE byOrgMIIADR;
+ BYTE byOrgMIICR;
+
+ /* keep original MIICR value */
+ VNSvInPortB(dwIoBase + MAC_REG_MIIADR, &byOrgMIIADR);
+ VNSvInPortB(dwIoBase + MAC_REG_MIICR, &byOrgMIICR);
+
+ /* disable MIICR_MAUTO, so that mii addr can be set normally */
+ GMACvDisableMiiAutoPoll(dwIoBase);
+
+ byOrgPhyId = GMACbyGetPhyId(dwIoBase);
+
+ for (uu = 0; uu < uTotalPhyNum; uu++) {
+ GMACvSetPhyId(dwIoBase, byRevId, pbyPhyId[uu]);
+
+ if (GMIIbIsRegBitsOn(dwIoBase, byRevId, MII_REG_BMSR, BMSR_LNK)) {
+
+ byActPhyId = pbyPhyId[uu];
+
+ /* iso all PHY */
+ for (uu = 0; uu < uTotalPhyNum; uu++) {
+ GMACvSetPhyId(dwIoBase, byRevId, pbyPhyId[uu]);
+ MIIvRegBitsOn(dwIoBase, byRevId, MII_REG_BMCR, BMCR_ISO);
+ }
+
+ /* finally, set correct PHY id */
+ GMACvSetPhyId(dwIoBase, byRevId, byActPhyId);
+ /* active this PHY */
+ MIIvRegBitsOff(dwIoBase, byRevId, MII_REG_BMCR, BMCR_ISO);
+ bRetVal = TRUE;
+ break;
+ }
+ }
+
+ if (!bRetVal)
+ /* if no link, set original PHY id */
+ GMACvSetPhyId(dwIoBase, byRevId, byOrgPhyId);
+
+ /* restore MIICR */
+ VNSvOutPortB(dwIoBase + MAC_REG_MIIADR, byOrgMIIADR);
+ VNSvOutPortB(dwIoBase + MAC_REG_MIICR, byOrgMIICR);
+ return bRetVal;
+}
+
+VOID GMIIvInitialize(DWORD dwIoBase, BYTE byRevId, DWORD dwPhyCmrId)
+{
+ WORD wOrgData;
+
+ /* PHY company/module, don't care revision id */
+ dwPhyCmrId &= CID_REV_ID_MASK_OFF;
+
+ switch (dwPhyCmrId) {
+ case CID_CICADA_CIS8201:
+ /* NOTICE!! For CICADA CS8201 PHY */
+ /* Turn on AUX_MODE (bit 2) in MII AUX register (offset 1Ch) */
+ MIIvRegBitsOn(dwIoBase, byRevId, MII_REG_AUXCSR, AUXCSR_MDPPS);
+
+ /* Turn on bit 2 in offset 0x1B, this patch code only adopt to CIS8201,
+ not for integrated PHY in VT3216 */
+ MIIvRegBitsOn(dwIoBase, byRevId, MII_REG_LED, LED_LALBE);
+
+ break;
+
+ case CID_CICADA_CIS3216I:
+ case CID_CICADA_CIS3216I64:
+ break;
+
+ case CID_MARVELL_1000:
+ case CID_MARVELL_1000S:
+ /* Assert CRS on Transmit */
+ MIIvRegBitsOn(dwIoBase, byRevId, MII_REG_PSCR, PSCR_ACRSTX);
+ break;
+
+ default:
+ break;
+ }
+
+ /* if ISO is on, turn it off */
+ GMIIbReadEmbeded(dwIoBase, byRevId, MII_REG_BMCR, &wOrgData);
+ if (BITbIsBitOn(wOrgData, BMCR_ISO)) {
+ wOrgData &= ~BMCR_ISO;
+ GMIIbWriteEmbeded(dwIoBase, byRevId, MII_REG_BMCR, wOrgData);
+ }
+}
diff --git a/cpu/arm920t/wmt/gpio.h b/cpu/arm920t/wmt/gpio.h
new file mode 100755
index 0000000..47ee1ae
--- /dev/null
+++ b/cpu/arm920t/wmt/gpio.h
@@ -0,0 +1,317 @@
+/*++
+Copyright (c) 2010 WonderMedia Technologies, Inc.
+
+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, see http://www.gnu.org/licenses/>.
+
+WonderMedia Technologies, Inc.
+10F, 529, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C.
+--*/
+
+#ifndef _GPIO_H_
+#define _GPIO_H_
+
+typedef struct _GPIO_REG_ {
+ volatile unsigned long CTRL_UR_LPC_SF; /* [Rx00] GPIO Enable Control Register for UARTS,LPC,SF */
+ volatile unsigned long CTRL_SD_IIC_SPI_MS; /* [Rx04] GPIO Enable Control Register for SD,IIC,SPI,MS */
+ volatile unsigned long CTRL_CF; /* [Rx08] GPIO Enable Control Register for CF */
+ volatile unsigned long CTRL_NF; /* [Rx0C] GPIO Enable Control Register for NF */
+ volatile unsigned long CTRL_PCIAD; /* [Rx10] GPIO Enable Control for PCI AD BUS */
+ volatile unsigned long CTRL_PCI; /* [Rx14] GPIO Eanble Control for Non PCI AD BUS */
+ volatile unsigned long CTRL_IDE; /* [Rx18] GPIO Enable Control for IDE */
+ volatile unsigned long RESV_1C; /* [Rx1C] */
+
+ volatile unsigned long OC_UR_LPC_SF; /* [Rx20] GPIO Output Control Register for UARTS,LPC,SF */
+ volatile unsigned long OC_SD_IIC_SPI_MS; /* [Rx24] GPIO Output Control Register for SD,IIC,SPI,MS */
+ volatile unsigned long OC_CF; /* [Rx28] GPIO Output Control Register for CF */
+ volatile unsigned long OC_NF; /* [Rx2C] GPIO Output Control Register for NF */
+ volatile unsigned long OC_PCIAD; /* [Rx30] GPIO Output Control Register for PCI AD BUS */
+ volatile unsigned long OC_PCI; /* [Rx34] GPIO Output Control Register for Non PCI AD BUS */
+ volatile unsigned long OC_IDE; /* [Rx38] GPIO Output Control Register for IDE */
+ volatile unsigned long OC_GPIO; /* [Rx3C] GPIO Output Control Register for GPIO */
+ volatile unsigned long OD_UR_LPC_SF; /* [Rx40] GPIO Output Data Register for UARTS,LPC,SF */
+
+ volatile unsigned long OD_SD_IIC_SPI_MS; /* [Rx44] GPIO Output Data Register for SD,IIC,SPI,MS */
+ volatile unsigned long OD_CF; /* [Rx48] GPIO Output Data Register for CF */
+ volatile unsigned long OD_NF; /* [Rx4C] GPIO Output Data Register for NF */
+ volatile unsigned long OD_PCIAD; /* [Rx50] GPIO Output Data Register for PCIAD */
+ volatile unsigned long OD_PCI; /* [Rx54] GPIO Output Data Register for Non PCI AD BUS */
+ volatile unsigned long OD_IDE; /* [Rx58] GPIO Output Data Register for IDE */
+ volatile unsigned long OD_GPIO; /* [Rx5C] GPIO Output Data Register for GPIO */
+
+ volatile unsigned long ID_UR_LPC_SF; /* [Rx60] GPIO Input Data Register for UARTS,LPC,SF */
+ volatile unsigned long ID_SD_IIC_SPI_MS; /* [Rx64] GPIO Input Data Register for SD,IIC,SPI,MS */
+ volatile unsigned long ID_CF; /* [Rx68] GPIO Input Data Register for CF */
+ volatile unsigned long ID_NF; /* [Rx6C] GPIO Input Data Register for NF */
+ volatile unsigned long ID_PCIAD; /* [Rx70] GPIO Input Data Register for PCIAD */
+ volatile unsigned long ID_PCI; /* [Rx74] GPIO Input Data Register for Non PCI AD BUS */
+ volatile unsigned long ID_IDE; /* [Rx78] GPIO Input Data Register for IDE */
+ volatile unsigned long ID_GPIO; /* [Rx7C] GPIO Input Data Register for GPIO */
+
+ volatile unsigned long RESV_80[0x20]; /* [Rx80-RxFF] */
+
+ volatile unsigned long STRAP_STS; /* [Rx100] Strapping Option Status Register */
+ volatile unsigned long RESV_104; /* [Rx104] */
+ volatile unsigned long AHB_CTRL; /* [Rx108] AHB Control Register */
+ volatile unsigned long RESV_10C[0x3D]; /* [Rx10C-Rx1FF] */
+
+ volatile unsigned long SEL_CF_NF; /* [Rx200] CF/NF Selection Register */
+ volatile unsigned long RESV_204[0x3F]; /* [Rx204-Rx2FF] */
+
+ volatile unsigned long INT_REQ_TYPE; /* [Rx300] GPIO Interrupt Request Type Register */
+ volatile unsigned long INT_REQ_STS; /* [Rx304] GPIO Interrupt Request Status Register */
+ volatile unsigned long RESV_308[0x3E]; /* [Rx308-Rx3FF] */
+
+ volatile unsigned long IDE_IO_DRV; /* [Rx400] IDE I/O Drive Strength Register */
+ volatile unsigned long MS_IO_DRV; /* [Rx404] MS I/O Drive Strength and Slew Rate Register */
+ volatile unsigned long PCI_IO_DRV; /* [Rx408] PCI Bus I/O Drive Strength and Slew */
+ /* Rate Register */
+ volatile unsigned long SD_IO_DRV; /* [Rx40C] SD I/O Drive Strength and Slwe Rate Register */
+ volatile unsigned long SF_IO_DRV; /* [Rx410] Serial Flash Clock I/O Drive Strength */
+ /* and Slew Rate Register */
+ volatile unsigned long SPI_IO_DRV; /* [Rx414] SPI I/O Drive Strength and Slew Rate Register */
+} GPIO_REG, *PGPIO_REG;
+
+/*
+ * volatile unsigned long CTRL_UR_LPC_SF; //[Rx00] GPIO Enable Control Register for UARTS,LPC,SF
+ */
+#define GPIO_UR0_CTS 0x1 /* UART0 CTS signal GPIO Enable */
+#define GPIO_UR0_RTS 0x2 /* UART0 RTS signal GPIO Enable */
+#define GPIO_UR0_RXD 0x4
+#define GPIO_UR0_TXD 0x8
+#define GPIO_UR0_ALL 0xF
+
+#define GPIO_UR1_CTS 0x100 /* UART1 CTS signal GPIO Enable */
+#define GPIO_UR1_RTS 0x200 /* UART1 RTS signal GPIO Enable */
+#define GPIO_UR1_RXD 0x400
+#define GPIO_UR1_TXD 0x800
+#define GPIO_UR1_ALL 0xF00
+
+#define GPIO_LPC_AD4 0xF0000
+#define GPIO_LPC_CLK 0x100000
+#define GPIO_LPC_DRQ 0x200000
+#define GPIO_LPC_FRAME 0x400000
+#define GPIO_LPC_RESET 0x800000
+#define GPIO_LPC_SERIRQ 0x1000000
+
+#define GPIO_SF_CS2 0x6000000
+#define GPIO_SF_CLK 0x8000000
+#define GPIO_SF_DI 0x10000000
+#define GPIO_SF_DO 0x20000000
+
+/*
+ * volatile unsigned long CTRL_SD_IIC_SPI_MS; //[Rx04] GPIO Enable Control Register for SD,IIC,SPI,MS
+ */
+#define GPIO_SD_DATA4 0xF
+
+#define GPIO_MMC_DATA4 0xF0
+
+#define GPIO_SD_CLK 0x100
+#define GPIO_SD_CMD 0x200
+
+#define GPIO_IIC_SCL 0x400
+#define GPIO_IIC_SDA 0x800
+
+#define GPIO_SPI_CLK 0x1000
+#define GPIO_SPI_MISO 0x2000
+#define GPIO_SPI_MOSI 0x4000
+#define GPIO_SPI_SS 0x8000
+
+#define GPIO_MS_ALL 0x7F0000
+#define GPIO_MS_DATA4 0xF0000
+#define GPIO_MS_BS 0x100000
+#define GPIO_MS_CLK 0x200000
+#define GPIO_MS_INS 0x400000
+
+/*
+ * volatile unsigned long CTRL_CF; //[Rx08] GPIO Enable Control Register for CF
+ */
+#define GPIO_CF_DATA16 0xFFFF
+#define GPIO_CF_AD3 0x70000
+#define GPIO_CF_CD2 0x180000
+#define GPIO_CF_CE2 0x600000
+#define GPIO_CF_IOR 0x800000
+#define GPIO_CF_IOW 0x1000000
+#define GPIO_CF_WAIT 0x2000000
+#define GPIO_CF_INTRQ 0x4000000
+
+/*
+ * volatile unsigned long CTRL_NF; //[Rx0C] GPIO Enable Control Register for NF
+ */
+#define GPIO_NF_CE8 0xFF
+#define GPIO_NF_ALE 0x100
+#define GPIO_NF_CLE 0x200
+#define GPIO_NF_RD 0x400
+#define GPIO_NF_RE 0x800
+#define GPIO_NF_WE 0x1000
+#define GPIO_NF_WP 0x2000
+#define GPIO_NF_WPD 0x4000
+
+/*
+ * volatile unsigned long CTRL_PCIAD; //[Rx10] GPIO Enable Control for PCI AD BUS
+ */
+#define GPIO_PCI_ADALL 0xFFFFFFFF
+#define GPIO_PCI_AD32 0xFFFFFFFF
+
+/*
+ * volatile unsigned long CTRL_PCI; //[Rx14] GPIO Eanble Control for Non PCI AD BUS
+ */
+#define GPIO_PCI_NOADALL 0x1FFFFFFF
+#define GPIO_PCI_GNT4 0xF
+#define GPIO_PCI_REQ4 0xF0
+#define GPIO_PCI_BE4 0xF00
+#define GPIO_PCI_INTA 0x1000
+#define GPIO_PCI_INTB 0x2000
+#define GPIO_PCI_INTC 0x4000
+#define GPIO_PCI_INTD 0x8000
+#define GPIO_PCI_DEVSEL 0x10000
+#define GPIO_PCI_FRAME 0x20000
+#define GPIO_PCI_IRDY 0x40000
+#define GPIO_PCI_M66EN 0x80000
+#define GPIO_PCI_PAR 0x100000
+#define GPIO_PCI_PERR 0x200000
+#define GPIO_PCI_SERR 0x400000
+#define GPIO_PCI_STOP 0x800000
+#define GPIO_PCI_TRDY 0x1000000
+
+/*
+ * volatile unsigned long CTRL_IDE; //[Rx18] GPIO Enable Control for IDE
+ */
+#define GPIO_IDE_DD16 0xFFFF
+#define GPIO_IDE_DA3 0x70000
+#define GPIO_IDE_CS1 0x80000
+#define GPIO_IDE_CS3 0x100000
+#define GPIO_IDE_DACK 0x200000
+#define GPIO_IDE_DREQ 0x400000
+#define GPIO_IDE_INTRQ 0x800000
+#define GPIO_IDE_IOR 0x1000000
+#define GPIO_IDE_IORDY 0x2000000
+#define GPIO_IDE_IOW 0x4000000
+
+/*
+ * volatile unsigned long OC_UR_LPC_SF; //[Rx20] GPIO Output Control Register for UARTS,LPC,SF
+ */
+#define GPIO_OE_UR0_CTS 0x1
+#define GPIO_OE_UR0_RTS 0x2
+#define GPIO_OE_UR0_RXD 0x4
+#define GPIO_OE_UR0_TXD 0x8
+#define GPIO_OE_UR1_CTS 0x100
+#define GPIO_OE_UR1_RTS 0x200
+#define GPIO_OE_UR1_RXD 0x400
+#define GPIO_OE_UR1_TXD 0x800
+#define GPIO_OE_LPC_AD4 0xF0000
+#define GPIO_OE_LPC_CLK 0x100000
+#define GPIO_OE_LPC_DRQ 0x200000
+#define GPIO_OE_LPC_FRAME 0x400000
+#define GPIO_OE_LPC_RESET 0x800000
+#define GPIO_OE_LPC_SERIRQ 0x1000000
+#define GPIO_OE_SF_CS2 0x6000000
+#define GPIO_OE_SF_CLK 0x8000000
+#define GPIO_OE_SF_DI 0x10000000
+#define GPIO_OE_SF_DO 0x20000000
+
+/*
+ * volatile unsigned long OC_SD_IIC_SPI_MS; //[Rx24] GPIO Output Control Register for SD,IIC,SPI,MS
+ */
+#define GPIO_OE_SD_DATA4 0xF
+#define GPIO_OE_MMC_DATA4 0xF0
+#define GPIO_OE_SD_CLK 0x100
+#define GPIO_OE_SD_CMD 0x200
+#define GPIO_OE_IIC_SDA 0x400
+#define GPIO_OE_IIC_SCL 0x800
+#define GPIO_OE_SPI_CLK 0x1000
+#define GPIO_OE_SPI_MISO 0x2000
+#define GPIO_OE_SPI_MOSI 0x4000
+#define GPIO_OE_SPI_SS 0x8000
+#define GPIO_OE_MS_DATA0 0x10000
+#define GPIO_OE_MS_DATA1 0x20000
+#define GPIO_OE_MS_DATA2 0x40000
+#define GPIO_OE_MS_DATA3 0x80000
+#define GPIO_OE_MS_BS 0x100000
+#define GPIO_OE_MS_CLK 0x200000
+#define GPIO_OE_MS_INS 0x400000
+
+/*
+ * volatile unsigned long OC_CF; //[Rx28] GPIO Output Control Register for CF
+ */
+#define GPIO_OE_CF_DATA16 0xFFFF
+#define GPIO_OE_CF_ADDR3 0x70000
+#define GPIO_OE_CF_CD2 0x180000
+#define GPIO_OE_CF_CE2 0x600000
+#define GPIO_OE_CF_IORD 0x800000
+#define GPIO_OE_CF_IOW 0x1000000
+#define GPIO_OE_CF_WAIT 0x2000000
+#define GPIO_OE_CF_INTRQ 0x4000000
+
+/*
+ * volatile unsigned long OC_NF; //[Rx2C] GPIO Output Control Register for NF
+ */
+#define GPIO_OE_NF_CE8 0xFF
+#define GPIO_OE_NF_ALE 0x100
+#define GPIO_OE_NF_CLE 0x200
+#define GPIO_OE_NF_RD 0x400
+#define GPIO_OE_NF_RE 0x800
+#define GPIO_OE_NF_WE 0x1000
+#define GPIO_OE_NF_WP 0x2000
+#define GPIO_OE_NF_WPD 0x4000
+
+/*
+ * volatile unsigned long OC_PCIAD; //[Rx30] GPIO Output Control Register for PCI AD BUS
+ */
+#define GPIO_OE_PCI_AD32 0xFFFFFFFF
+
+/*
+ * volatile unsigned long OC_PCI; //[Rx34] GPIO Output Control Register for Non PCI AD BUS
+ */
+#define GPIO_OE_PCI_GNT4 0xF
+#define GPIO_OE_PCI_REQ4 0xF0
+#define GPIO_OE_PCI_BE4 0xF00
+#define GPIO_OE_PCI_INTA 0x1000
+#define GPIO_OE_PCI_INTB 0x2000
+#define GPIO_OE_PCI_INTC 0x4000
+#define GPIO_OE_PCI_INTD 0x8000
+#define GPIO_OE_PCI_DEVSEL 0x10000
+#define GPIO_OE_PCI_FRAME 0x20000
+#define GPIO_OE_PCI_IRDY 0x40000
+#define GPIO_OE_PCI_M66EN 0x80000
+#define GPIO_OE_PCI_PAR 0x100000
+#define GPIO_OE_PCI_PERR 0x200000
+#define GPIO_OE_PCI_SERR 0x400000
+#define GPIO_OE_PCI_STOP 0x800000
+#define GPIO_OE_PCI_TRDY 0x1000000
+
+/*
+ * volatile unsigned long OC_IDE; //[Rx38] GPIO Output Control Register for IDE
+ */
+#define GPIO_OE_IDE_DATA16 0xFFFF
+#define GPIO_OE_IDE_ADDR3 0x70000
+#define GPIO_OE_IDE_CS1 0x80000
+#define GPIO_OE_IDE_CS3 0x100000
+#define GPIO_OE_IDE_DACK 0x200000
+#define GPIO_OE_IDE_DREQ 0x400000
+#define GPIO_OE_IDE_INTRQ 0x800000
+#define GPIO_OE_IDE_IOR 0x1000000
+#define GPIO_OE_IDE_IORDY 0x2000000
+#define GPIO_OE_IDE_IOW 0x4000000
+
+/*
+ * volatile unsigned long OC_GPIO; //[Rx3C] GPIO Output Control Register for GPIO
+ */
+#define GPIO_OE_GPIO_ALL 0xFF
+#define GPIO_OE_GPIO_0 0x1
+#define GPIO_OE_GPIO_1 0x2
+#define GPIO_OE_GPIO_2 0x4
+#define GPIO_OE_GPIO_3 0x8
+#define GPIO_OE_GPIO_4 0x10
+#define GPIO_OE_GPIO_5 0x20
+#define GPIO_OE_GPIO_6 0x40
+#define GPIO_OE_GPIO_7 0x80
+
+#endif /*_GPIO_H_ */
diff --git a/cpu/arm920t/wmt/interrupts.c b/cpu/arm920t/wmt/interrupts.c
new file mode 100755
index 0000000..8663208
--- /dev/null
+++ b/cpu/arm920t/wmt/interrupts.c
@@ -0,0 +1,231 @@
+/*
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Marius Groeger <mgroeger@sysgo.de>
+ *
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Alex Zuepke <azu@sysgo.de>
+ *
+ * (C) Copyright 2002
+ * Gary Jennejohn, DENX Software Engineering, <gj@denx.de>
+ *
+ * Copyright (c) 2008 WonderMedia Technologies, Inc.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ *
+ * WonderMedia Technologies, Inc.
+ * 10F, 529, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C.
+ */
+
+#include <common.h>
+
+#if defined(CONFIG_WMT)
+
+#include <asm/arch/common_def.h>
+#include <asm/arch/hardware.h>
+
+#include "pmc.h"
+
+#define TIMER_LOAD_VAL 0xffffffff
+
+static PMC_REG *pmc_regs = (PMC_REG *) BA_PMC;
+
+/* macro to read the 32 bit timer */
+static inline ulong READ_TIMER(void)
+{
+ if ((pmc_regs->OS_Timer_Ctrl & OSTC_RDREQ) == 0)
+ pmc_regs->OS_Timer_Ctrl |= OSTC_RDREQ;
+
+ while (pmc_regs->OS_Timer_Access_Sts & OSTA_RCA)
+ ;
+
+ return pmc_regs->OS_Timer_Count;
+}
+
+static ulong timestamp;
+static ulong lastdec;
+
+/* nothing really to do with interrupts, just starts up a counter. */
+int interrupt_init(void)
+{
+ /*
+ * Disable all OS Timer Control functions.
+ */
+ pmc_regs->OS_Timer_Ctrl = 0;
+
+ /*
+ * Disable OS Timer Watchdog.
+ */
+ pmc_regs->OS_Timer_WatchDog_Enable = 0;
+
+ /*
+ * Disable all OS Timer Interrupts.
+ */
+ pmc_regs->OS_Timer_Int_Enable = 0;
+
+
+ /*
+ * Clean all active OS Timer Match Status.
+ */
+ pmc_regs->OS_Timer_Sts = (OSTS_M0 | OSTS_M1 | OSTS_M2 | OSTS_M3);
+
+ /*
+ * Enable OS Timer update.
+ */
+ if ((pmc_regs->OS_Timer_Ctrl & OSTC_ENABLE) == 0)
+ pmc_regs->OS_Timer_Ctrl |= OSTC_ENABLE;
+
+ /* init the timestamp and lastdec value */
+ reset_timer_masked();
+
+ return 0;
+}
+
+/*
+ * timer without interrupts
+ */
+
+void reset_timer(void)
+{
+ reset_timer_masked();
+}
+
+ulong get_timer(ulong base)
+{
+ return get_timer_masked() - base;
+}
+
+void set_timer(ulong t)
+{
+ timestamp = t;
+}
+
+/* delay x useconds AND perserve advance timstamp value */
+void udelay(unsigned long usec)
+{
+ ulong tmo, tmp;
+
+ if (usec >= 1000) { /* if "big" number, spread normalization to seconds */
+ tmo = usec / 1000; /* start to normalize for usec to ticks per sec */
+ tmo *= CFG_HZ; /* find number of "ticks" to wait to achieve target */
+ tmo /= 1000; /* finish normalize. */
+ } else { /* else small number, don't kill it prior to HZ multiply */
+ tmo = usec * CFG_HZ;
+ tmo /= (1000*1000);
+ }
+
+ tmp = get_timer(0); /* get current timestamp */
+ if ((tmo + tmp + 1) < tmp) /* if setting this fordward will roll time stamp */
+ reset_timer_masked(); /* reset "advancing" timestamp to 0, set lastdec value */
+ else
+ tmo += tmp; /* else, set advancing stamp wake up time */
+
+ while (get_timer_masked() < tmo) /* loop till event */
+ /* NOP */;
+}
+
+void reset_timer_masked(void)
+{
+ /* reset time */
+ lastdec = READ_TIMER(); /* capure current incrementer value time */
+ timestamp = 0; /* start "advancing" time stamp from 0 */
+}
+
+ulong get_timer_masked(void)
+{
+ ulong now = READ_TIMER(); /* current tick value */
+
+ if (lastdec <= now) { /* normal mode (non roll) */
+ /* normal mode */
+ timestamp += now - lastdec; /* move stamp fordward with absoulte diff ticks */
+ } else {
+ /* we have an overflow ... */
+ timestamp += now + TIMER_LOAD_VAL - lastdec;
+ }
+ lastdec = now;
+
+ return timestamp;
+}
+
+void udelay_masked(unsigned long usec)
+{
+ ulong tmo;
+ ulong endtime;
+ signed long diff;
+
+ if (usec >= 1000) { /* if "big" number, spread normalization to seconds */
+ tmo = usec / 1000; /* start to normalize for usec to ticks per sec */
+ tmo *= CFG_HZ; /* find number of "ticks" to wait to achieve target */
+ tmo /= 1000; /* finish normalize. */
+ } else { /* else small number, don't kill it prior to HZ multiply */
+ tmo = usec * CFG_HZ;
+ tmo /= (1000*1000);
+ }
+
+ endtime = get_timer_masked() + tmo;
+
+ do {
+ ulong now = get_timer_masked();
+ diff = endtime - now;
+ } while (diff >= 0);
+}
+
+/*
+ * This function is derived from PowerPC code (read timebase as long long).
+ * On ARM it just returns the timer value.
+ */
+unsigned long long get_ticks(void)
+{
+ return get_timer(0);
+}
+
+/*
+ * This function is derived from PowerPC code (timebase clock frequency).
+ * On ARM it returns the number of timer ticks per second.
+ */
+ulong get_tbclk(void)
+{
+ ulong tbclk;
+
+ tbclk = CFG_HZ;
+
+ return tbclk;
+}
+
+/*
+ * reset the cpu by setting up the watchdog timer and let him time out
+ */
+void reset_cpu(ulong ignored)
+{
+ /* Clean prevoius reset status */
+ pmc_regs->Reset_Sts = (PMRS_PGR | PMRS_SHR | PMRS_SWR | PMRS_WDR | PMRS_HBR | PMRS_IOR | PMRS_PMR);
+
+ /* set PLLC to default value */
+ while (pmc_regs->PM_Sts2&0x3F0038)
+ ;
+ pmc_regs->PLLC = 0x02270001;
+ while (pmc_regs->PM_Sts2&0x3F0038)
+ ;
+
+ /* Request software reset */
+ pmc_regs->SW_Reset_Req = PMSR_SWR;
+
+ while (1) /* loop forever and wait for reset to happen */
+ ;
+
+ /*NOTREACHED*/
+}
+
+#endif /* defined(CONFIG_WMT) */
diff --git a/cpu/arm920t/wmt/mac.c b/cpu/arm920t/wmt/mac.c
new file mode 100755
index 0000000..2e80ec6
--- /dev/null
+++ b/cpu/arm920t/wmt/mac.c
@@ -0,0 +1,737 @@
+/*++
+Copyright (c) 2010 WonderMedia Technologies, Inc.
+
+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, see http://www.gnu.org/licenses/>.
+
+WonderMedia Technologies, Inc.
+10F, 529, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C.
+--*/
+
+
+#if !defined(__UPC_H__)
+#include "upc.h"
+#endif
+#if !defined(__TBIT_H__)
+#include "tbit.h"
+#endif
+#if !defined(__MII_H__)
+#include "mii.h"
+#endif
+#if !defined(__MAC_H__)
+#include "mac.h"
+#endif
+
+/*--------------------- Static Definitions -------------------------*/
+#define CB_DELAY_NM9346 (10) /* 10ms */
+#define CB_DELAY_SOFT_RESET (50) /* 50ms */
+
+/*--------------------- Static Classes ----------------------------*/
+
+/*--------------------- Static Variables --------------------------*/
+
+/*--------------------- Static Functions --------------------------*/
+
+/*--------------------- Export Variables --------------------------*/
+
+/*--------------------- Export Functions --------------------------*/
+BOOL
+MACbIsCableLinkOk(
+ DWORD dwIoBase
+ )
+{
+ return MACbIsRegBitsOff(dwIoBase, MAC_REG_MIISR, MIISR_LNKFL);
+}
+
+BOOL
+MACbIsIn100MMode(
+ DWORD dwIoBase,
+ BYTE byRevId
+ )
+{
+ UINT ii;
+
+ for (ii = 0; ii < 30; ii++)
+ PCAvDelayByIO(CB_DELAY_LOOP_WAIT);
+
+ /* NOTE.... */
+ /* when link fail, MAC will report in 100M mode, */
+ /* but NS DP83840A will report in 10M mode, DAVICOM DM9101 depends */
+ return MIIbIsIn100MMode(dwIoBase, byRevId);
+}
+
+VOID
+MACvIsInFullDuplexMode(
+ PBOOL pbFullDup,
+ DWORD dwIoBase
+ )
+{
+ *pbFullDup = MACbIsRegBitsOn(dwIoBase, MAC_REG_CR1, CR1_FDX);
+}
+
+BOOL
+MACbIsRegBitsOff(
+ DWORD dwIoBase,
+ BYTE byRegOfs,
+ BYTE byTestBits
+ )
+{
+ BYTE byData;
+
+ VNSvInPortB(dwIoBase + byRegOfs, &byData);
+ return BITbIsAllBitsOff(byData, byTestBits);
+}
+
+BOOL
+MACbIsRegBitsOn(
+ DWORD dwIoBase,
+ BYTE byRegOfs,
+ BYTE byTestBits
+ )
+{
+ BYTE byData;
+
+ VNSvInPortB(dwIoBase + byRegOfs, &byData);
+ return BITbIsAllBitsOn(byData, byTestBits);
+}
+
+BOOL
+MACbSafeSoftwareReset(
+ DWORD dwIoBase,
+ BYTE byRevId
+ )
+{
+ BYTE abyTmpRegData[0x100];
+ BOOL bRetVal;
+
+ /* PATCH.... */
+ /* save some important register's value, then do */
+ /* reset, then restore register's value */
+
+ /* save MAC context */
+ MACvSaveContext(dwIoBase, byRevId, abyTmpRegData);
+ /* do reset */
+ bRetVal = MACbSoftwareReset(dwIoBase, byRevId);
+ /* restore MAC context, except CR0 */
+ MACvRestoreContext(dwIoBase, byRevId, abyTmpRegData);
+
+ return bRetVal;
+}
+
+BOOL
+MACbStop(
+ DWORD dwIoBase
+ )
+{
+ WORD ww;
+ BYTE byData;
+
+ VNSvOutPortB(dwIoBase + MAC_REG_CR0, CR0_STOP);
+
+ /* W_MAX_TIMEOUT is the timeout period */
+ for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
+ VNSvInPortB(dwIoBase + MAC_REG_CR0, &byData);
+ if (BITbIsAllBitsOff(byData, CR0_TXON | CR0_RXON))
+ break;
+ }
+ if (ww == W_MAX_TIMEOUT)
+ return FALSE;
+
+ return TRUE;
+}
+
+BOOL
+MACbSafeStop(
+ DWORD dwIoBase,
+ BYTE byRevId
+ )
+{
+ if (!MACbSafeTxOff(dwIoBase, byRevId))
+ return FALSE;
+ if (!MACbSafeRxOff(dwIoBase, byRevId))
+ return FALSE;
+ if (!MACbStop(dwIoBase))
+ MACbSafeSoftwareReset(dwIoBase, byRevId);
+
+ return TRUE;
+}
+
+BOOL
+MACbSafeRxOff(
+ DWORD dwIoBase,
+ BYTE byRevId
+ )
+{
+ WORD ww;
+ BYTE byData;
+
+ /* try to safe shutdown RX */
+ MACvSetLoopbackMode(dwIoBase, MAC_LB_INTERNAL);
+ MACvRegBitsOff(dwIoBase, MAC_REG_CR0, CR0_RXON);
+ /* safe delay time */
+ PCAvDelayByIO(CB_DELAY_SOFT_RESET);
+ /* W_MAX_TIMEOUT is the timeout period */
+ for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
+ VNSvInPortB(dwIoBase + MAC_REG_CR0, &byData);
+ if (BITbIsBitOff(byData, CR0_RXON))
+ break;
+ }
+ if (ww == W_MAX_TIMEOUT) {
+ /* enter FIFO test mode to issue RX reject */
+ VNSvOutPortB(dwIoBase + MAC_REG_GFTEST, 0x01);
+ VNSvOutPortB(dwIoBase + MAC_REG_RFTCMD, 0x08);
+ PCAvDelayByIO(CB_DELAY_SOFT_RESET);
+ VNSvOutPortB(dwIoBase + MAC_REG_GFTEST, 0x00);
+ }
+
+ MACvSetLoopbackMode(dwIoBase, MAC_LB_NONE);
+ return TRUE;
+}
+
+BOOL
+MACbSafeTxOff(
+ DWORD dwIoBase,
+ BYTE byRevId
+ )
+{
+ WORD ww;
+ BYTE byData;
+
+ /* try to safe shutdown TX */
+ MACvRegBitsOff(dwIoBase, MAC_REG_CR0, CR0_TXON);
+ /* safe delay time */
+ PCAvDelayByIO(CB_DELAY_SOFT_RESET);
+ /* W_MAX_TIMEOUT is the timeout period */
+ for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
+ VNSvInPortB(dwIoBase + MAC_REG_CR0, &byData);
+ if (BITbIsBitOff(byData, CR0_TXON))
+ break;
+ }
+ if (ww == W_MAX_TIMEOUT)
+ return FALSE;
+
+ return TRUE;
+}
+
+BOOL
+MACbSoftwareReset(
+ DWORD dwIoBase,
+ BYTE byRevId
+ )
+{
+ WORD ww;
+ BYTE byData;
+
+ /* turn on CR1_SFRST */
+ MACvRegBitsOn(dwIoBase, MAC_REG_CR1, CR1_SFRST);
+
+ /* polling till software reset complete */
+ /* W_MAX_TIMEOUT is the timeout period */
+ printf("\n");
+ for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
+ VNSvInPortB(dwIoBase + MAC_REG_CR1, &byData);
+ if (BITbIsBitOff(byData, CR1_SFRST))
+ break;
+ }
+ if (ww == W_MAX_TIMEOUT) {
+ /* turn on force reset */
+ MACvRegBitsOn(dwIoBase, MAC_REG_MISC_CR1, MISC_CR1_FORSRST);
+ /* delay 2ms */
+ MACvTimer0MiniSDelay(dwIoBase, byRevId, 2);
+ }
+
+ return TRUE;
+}
+
+BYTE
+MACbyReadEECSR(
+ DWORD dwIoBase
+ )
+{
+ BYTE byData;
+
+ VNSvInPortB(dwIoBase + MAC_REG_EECSR, &byData);
+ return byData;
+}
+
+BYTE
+MACbyReadMIICR(
+ DWORD dwIoBase
+ )
+{
+ BYTE byData;
+
+ VNSvInPortB(dwIoBase + MAC_REG_MIICR, &byData);
+ return byData;
+}
+
+BYTE
+MACbyReadMultiAddr(
+ DWORD dwIoBase,
+ UINT uByteIdx
+ )
+{
+ BYTE byData;
+
+ VNSvInPortB(dwIoBase + MAC_REG_MAR + uByteIdx, &byData);
+ return byData;
+}
+
+VOID
+MACvWriteMultiAddr(
+ DWORD dwIoBase,
+ UINT uByteIdx,
+ BYTE byData
+ )
+{
+ VNSvOutPortB(dwIoBase + MAC_REG_MAR + uByteIdx, byData);
+}
+
+VOID
+MACvInitialize(
+ DWORD dwIoBase,
+ BYTE byRevId
+ )
+{
+ /* Clear sticky bits */
+ MACvClearStckDS(dwIoBase);
+ /* Disable force PME-enable */
+ VNSvOutPortB(dwIoBase + MAC_REG_WOLCG_CLR, WOLCFG_PME_OVR);
+ /* Disable power-event config bit */
+ MACvPwrEvntDisable(dwIoBase);
+ /* Clear power status */
+ VNSvOutPortB(dwIoBase + MAC_REG_PWRCSR_CLR, 0xFF);
+ VNSvOutPortB(dwIoBase + MAC_REG_PWRCSR1_CLR, 0x03);
+
+ /* Do reset */
+ MACbSoftwareReset(dwIoBase, byRevId);
+ /* For AUTOLD be effect in VT3043, safe delay time */
+ PCAvDelayByIO(CB_DELAY_SOFT_RESET);
+
+ /*
+ // Issue AUTOLD in EECSR to reload eeprom
+ MACvRegBitsOn(dwIoBase, MAC_REG_EECSR, EECSR_AUTOLD);
+
+ // Wait until EEPROM loading complete
+ while (TRUE) {
+ BYTE byData;
+
+ VNSvInPortB(dwIoBase + MAC_REG_EECSR, &byData);
+ if (BITbIsBitOff(byData, EECSR_AUTOLD))
+ break;
+ }
+ */
+
+ /* For 3065D, EEPROM reloaded will cause bit 0 in MAC_REG_CFGA turned on. */
+ /* It makes MAC receive magic packet automatically. So, driver turn it off. */
+ MACvRegBitsOff(dwIoBase, MAC_REG_CFGA, CFGA_LED0S0);
+
+ /* Set rx-FIFO/tx-FIFO/DMA threshold */
+ /* Set rx threshold, 64 bytes */
+ MACvSetRxThreshold(dwIoBase, 0);
+ /* Set tx threshold, 128 bytes */
+ MACvSetTxThreshold(dwIoBase, 0);
+ /* Set DMA length, 16 DWORDs = 64 bytes */
+ MACvSetDmaLength(dwIoBase, 0);
+
+ /* kevin wonder:Enable queue packet? or disable? */
+ MACvRegBitsOff(dwIoBase, MAC_REG_CFGB, CFGB_QPKTDIS);
+ /* kevin wonder:Suspend-well accept broadcast, multicast */
+ VNSvOutPortB(dwIoBase + MAC_REG_WOLCG_SET, WOLCFG_SAM | WOLCFG_SAB);
+
+ /* kevin wonder :Back off algorithm use original IEEE standard */
+ MACvRegBitsOff(dwIoBase, MAC_REG_CFGD, CFGD_CRADOM | CFGD_CAP | CFGD_MBA | CFGD_BAKOPT);
+
+ /* Set packet filter */
+ /* Receive directed and broadcast address */
+ MACvSetPacketFilter(dwIoBase, PKT_TYPE_DIRECTED | PKT_TYPE_BROADCAST);
+
+ /* enable MIICR_MAUTO */
+ MACvEnableMiiAutoPoll(dwIoBase);
+ /* macinit */
+
+ /* printf("mac init ok!\n"); */
+}
+
+VOID
+MACvIntDisable(
+ DWORD dwIoBase,
+ BYTE byRevId
+ )
+{
+ VNSvOutPortW(dwIoBase + MAC_REG_IMR, 0x0000);
+ VNSvOutPortB(dwIoBase + MAC_REG_MIMR, 0x00);
+}
+
+VOID
+MACvIntEnable(
+ DWORD dwIoBase,
+ BYTE byRevId,
+ DWORD dwMask
+ )
+{
+ VNSvOutPortW(dwIoBase + MAC_REG_IMR, LOWORD(dwMask));
+ VNSvOutPortB(dwIoBase + MAC_REG_MIMR, (BYTE)(HIWORD(dwMask)));
+}
+
+VOID
+MACvEnableMiiAutoPoll(
+ DWORD dwIoBase
+ )
+{
+ WORD ww;
+ BYTE byData;
+
+ VNSvOutPortB(dwIoBase + MAC_REG_MIICR, 0);
+ VNSvOutPortB(dwIoBase + MAC_REG_MIIAD, 0x01);
+ VNSvOutPortB(dwIoBase + MAC_REG_MIICR, MIICR_MAUTO);
+
+ /* as soon as MDONE is on, MAUTO is really started */
+ for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
+ VNSvInPortB(dwIoBase + MAC_REG_MIIAD, &byData);
+ if (BITbIsBitOn(byData, MIIAD_MDONE))
+ break;
+ }
+
+ MACvRegBitsOn(dwIoBase, MAC_REG_MIIAD, MIIAD_MSRCEN);
+}
+
+VOID
+MACvSafeDisableMiiAutoPoll(
+ DWORD dwIoBase,
+ BYTE byRevId
+ )
+{
+ WORD ww;
+ BYTE byData;
+
+ /* turn off MAUTO */
+ VNSvOutPortB(dwIoBase + MAC_REG_MIICR, 0);
+
+ /* as soon as MIDLE is on, MAUTO is really stoped */
+ for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
+ VNSvInPortB(dwIoBase + MAC_REG_MIIAD, &byData);
+ if (BITbIsBitOn(byData, MIIAD_MIDLE))
+ break;
+ }
+}
+
+VOID
+MACvReadISR(
+ DWORD dwIoBase,
+ BYTE byRevId,
+ PDWORD pdwValue
+ )
+{
+ WORD wData;
+ BYTE byData;
+
+ VNSvInPortW(dwIoBase + MAC_REG_ISR, &wData);
+ VNSvInPortB(dwIoBase + MAC_REG_MISR, &byData);
+ *pdwValue = MAKEDWORD(wData, MAKEWORD(byData, 0x00));
+}
+
+VOID
+MACvWriteISR(
+ DWORD dwIoBase,
+ BYTE byRevId,
+ DWORD dwValue
+ )
+{
+ /* NOTE.... must write MISR before ISR, otherwise GENI will not */
+ /* be cleared */
+ VNSvOutPortB(dwIoBase + MAC_REG_MISR, (BYTE)(HIWORD(dwValue)));
+ VNSvOutPortW(dwIoBase + MAC_REG_ISR, LOWORD(dwValue));
+}
+
+VOID
+MACvRestoreContext(
+ DWORD dwIoBase,
+ BYTE byRevId,
+ PBYTE pbyCxtBuf
+ )
+{
+ int ii;
+
+ /* restore RCR,TCR,CR,ISR,IMR... */
+ for (ii = MAC_REG_PAR; ii < MAC_REG_CUR_RD_ADDR; ii++) {
+ /* except CR0, because we don't want to start chip now */
+ if (ii != MAC_REG_CR0)
+ VNSvOutPortB(dwIoBase + ii, *(pbyCxtBuf + ii));
+ }
+
+ /* restore CURR_RX_DESC_ADDR, CURR_TX_DESC_ADDR */
+ for (ii = MAC_REG_CUR_RD_ADDR; ii < MAC_REG_CUR_TD_ADDR + 4; ii += 4)
+ VNSvOutPortD(dwIoBase + ii, *(PDWORD)(pbyCxtBuf + ii));
+
+ /* restore MIIAD... */
+ for (ii = MAC_REG_MPHY; ii < MAC_REG_CNTR_MPA; ii++)
+ VNSvOutPortB(dwIoBase + ii, *(pbyCxtBuf + ii));
+
+ /* restore WOLCR, PWCFG, TestReg, WOLCG */
+ for (ii = MAC_REG_WOLCR_SET; ii < MAC_REG_WOLCR_CLR; ii++)
+ VNSvOutPortB(dwIoBase + ii, *(pbyCxtBuf + ii));
+ /* restore pattern, mask */
+ for (ii = MAC_REG_PATRN_CRC0; ii < MAC_REG_BYTEMSK3_3 + 4; ii += 4)
+ VNSvOutPortD(dwIoBase + ii, *((PDWORD)(pbyCxtBuf + ii)));
+}
+
+VOID
+MACvSaveContext(
+ DWORD dwIoBase,
+ BYTE byRevId,
+ PBYTE pbyCxtBuf
+ )
+{
+ int ii;
+
+ /* save RCR,TCR,CR,ISR,IMR... */
+ for (ii = MAC_REG_PAR; ii < MAC_REG_CUR_RD_ADDR; ii++)
+ VNSvInPortB(dwIoBase + ii, (PBYTE)(pbyCxtBuf + ii));
+
+ /* save CURR_RX_DESC_ADDR, CURR_TX_DESC_ADDR */
+ for (ii = MAC_REG_CUR_RD_ADDR; ii < MAC_REG_CUR_TD_ADDR + 4; ii += 4)
+ VNSvInPortD(dwIoBase + ii, (PDWORD)(pbyCxtBuf + ii));
+
+ /* save MIIAD... */
+ for (ii = MAC_REG_MPHY; ii < MAC_REG_CNTR_MPA; ii++)
+ VNSvInPortB(dwIoBase + ii, (PBYTE)(pbyCxtBuf + ii));
+
+ /* save WOLCR, PWCFG, TestReg, WOLCG */
+ for (ii = MAC_REG_WOLCR_SET; ii < MAC_REG_WOLCR_CLR; ii++)
+ VNSvInPortB(dwIoBase + ii, (PBYTE)(pbyCxtBuf + ii));
+ /* save pattern, mask */
+ for (ii = MAC_REG_PATRN_CRC0; ii < MAC_REG_BYTEMSK3_3 + 4; ii += 4)
+ VNSvInPortD(dwIoBase + ii, (PDWORD)(pbyCxtBuf + ii));
+}
+
+VOID
+MACvSetDmaLength(
+ DWORD dwIoBase,
+ BYTE byDmaLength
+ )
+{
+ BYTE byOrgValue;
+
+ /* set BCR0 */
+ VNSvInPortB(dwIoBase + MAC_REG_BCR0, &byOrgValue);
+ byOrgValue = (BYTE)((byOrgValue & 0xF8) | byDmaLength);
+ VNSvOutPortB(dwIoBase + MAC_REG_BCR0, byOrgValue);
+}
+
+VOID
+MACvSetDuplexMode(
+ DWORD dwIoBase,
+ BYTE byRevId,
+ BOOL bFullDuplexOn
+ )
+{
+ if (bFullDuplexOn) {
+ MACvRegBitsOn(dwIoBase, MAC_REG_CR1, CR1_FDX);
+ }
+ else {
+ MACvRegBitsOff(dwIoBase, MAC_REG_CR1, CR1_FDX);
+ }
+
+ if (bFullDuplexOn) {
+ VNSvOutPortB(dwIoBase + MAC_REG_WOLCG_SET, WOLCFG_SFDX);
+ }
+ else {
+ VNSvOutPortB(dwIoBase + MAC_REG_WOLCG_CLR, WOLCFG_SFDX);
+ }
+}
+
+
+VOID
+MACvSetLoopbackMode(
+ DWORD dwIoBase,
+ BYTE byLoopbackMode
+ )
+{
+ BYTE byOrgValue;
+
+ /* set TCR */
+ VNSvInPortB(dwIoBase + MAC_REG_TCR, &byOrgValue);
+ byOrgValue = (BYTE)((byOrgValue & 0xF9) | (byLoopbackMode << 1));
+ VNSvOutPortB(dwIoBase + MAC_REG_TCR, byOrgValue);
+}
+
+VOID
+MACvSetPacketFilter(
+ DWORD dwIoBase,
+ WORD wFilterType
+ )
+{
+ BYTE byOldRCR;
+ BYTE byNewRCR = 0;
+
+ /* if only in DIRECTED mode, multicast-address will set to zero, */
+ /* but if other mode exist (e.g. PROMISCUOUS), multicast-address */
+ /* will be open */
+ if (BITbIsBitOn(wFilterType, PKT_TYPE_DIRECTED)) {
+ /* set multicast address to accept none */
+ VNSvOutPortD(dwIoBase + MAC_REG_MAR, 0L);
+ VNSvOutPortD(dwIoBase + MAC_REG_MAR + sizeof(DWORD), 0L);
+ }
+
+ if (BITbIsAnyBitsOn(wFilterType, PKT_TYPE_PROMISCUOUS | PKT_TYPE_ALL_MULTICAST)) {
+ /* set multicast address to accept all */
+ VNSvOutPortD(dwIoBase + MAC_REG_MAR, 0xFFFFFFFFL);
+ VNSvOutPortD(dwIoBase + MAC_REG_MAR + sizeof(DWORD), 0xFFFFFFFFL);
+ }
+
+ if (BITbIsBitOn(wFilterType, PKT_TYPE_PROMISCUOUS))
+ byNewRCR |= (RCR_PROM | RCR_AM | RCR_AB);
+
+ if (BITbIsAnyBitsOn(wFilterType, PKT_TYPE_MULTICAST | PKT_TYPE_ALL_MULTICAST))
+ byNewRCR |= RCR_AM;
+
+ if (BITbIsBitOn(wFilterType, PKT_TYPE_BROADCAST))
+ byNewRCR |= RCR_AB;
+
+ if (BITbIsBitOn(wFilterType, PKT_TYPE_RUNT))
+ byNewRCR |= RCR_AR;
+
+ if (BITbIsBitOn(wFilterType, PKT_TYPE_ERROR))
+ byNewRCR |= RCR_SEP;
+
+ VNSvInPortB(dwIoBase + MAC_REG_RCR, &byOldRCR);
+ if (byNewRCR != (byOldRCR & 0x1F)) {
+ /* Modify the Receive Command Register */
+ byNewRCR |= (BYTE)(byOldRCR & 0xE0);
+ VNSvOutPortB(dwIoBase + MAC_REG_RCR, byNewRCR);
+ }
+}
+
+VOID
+MACvSetRxThreshold(
+ DWORD dwIoBase,
+ BYTE byThreshold
+ )
+{
+ BYTE byOrgValue;
+
+ /* set BCR0 */
+ VNSvInPortB(dwIoBase + MAC_REG_BCR0, &byOrgValue);
+ byOrgValue = (BYTE)((byOrgValue & 0xC7) | (byThreshold << 3));
+ VNSvOutPortB(dwIoBase + MAC_REG_BCR0, byOrgValue);
+ /* set RCR */
+ VNSvInPortB(dwIoBase + MAC_REG_RCR, &byOrgValue);
+ byOrgValue = (BYTE)((byOrgValue & 0x1F) | (byThreshold << 5));
+ VNSvOutPortB(dwIoBase + MAC_REG_RCR, byOrgValue);
+}
+
+VOID
+MACvGetTxThreshold(
+ DWORD dwIoBase,
+ PBYTE pbyThreshold
+ )
+{
+ /* first, get BCR1 */
+ VNSvInPortB(dwIoBase + MAC_REG_BCR1, pbyThreshold);
+ *pbyThreshold = (BYTE)((*pbyThreshold >> 3) & 0x07);
+
+ /* second, if BCR1 is zero, we get TCR */
+ if (*pbyThreshold == 0) {
+ VNSvInPortB(dwIoBase + MAC_REG_TCR, pbyThreshold);
+ *pbyThreshold >>= 5;
+ }
+}
+
+VOID
+MACvSetTxThreshold(
+ DWORD dwIoBase,
+ BYTE byThreshold
+ )
+{
+ BYTE byOrgValue;
+
+ /* set BCR1 */
+ VNSvInPortB(dwIoBase + MAC_REG_BCR1, &byOrgValue);
+ byOrgValue = (BYTE)((byOrgValue & 0xC7) | (byThreshold << 3));
+ VNSvOutPortB(dwIoBase + MAC_REG_BCR1, byOrgValue);
+ /* set TCR */
+ VNSvInPortB(dwIoBase + MAC_REG_TCR, &byOrgValue);
+ byOrgValue = (BYTE)((byOrgValue & 0x1F) | (byThreshold << 5));
+ VNSvOutPortB(dwIoBase + MAC_REG_TCR, byOrgValue);
+}
+
+VOID
+MACvTimer0MicroSDelay(
+ DWORD dwIoBase,
+ BYTE byRevId,
+ UINT udelay
+ )
+{
+ BYTE byData;
+
+ MACvRegBitsOn(dwIoBase, MAC_REG_MISC_CR0, MISC_CR0_TM0US);
+
+ /* set delay time to udelay, unit is micro-second */
+ VNSvOutPortW(dwIoBase + MAC_REG_SOFT_TIMER0, (WORD)udelay);
+ /* delay time */
+ MACvRegBitsOn(dwIoBase, MAC_REG_MISC_CR0, MISC_CR0_TIMER0_EN);
+ MACvRegBitsOff(dwIoBase, MAC_REG_MISC_CR0, MISC_CR0_TIMER0_SUSPEND);
+
+ while (TRUE) {
+ VNSvInPortB(dwIoBase + MAC_REG_MISC_CR0, &byData);
+ if (BITbIsBitOn(byData, MISC_CR0_TIMER0_SUSPEND))
+ break;
+ }
+}
+
+VOID
+MACvTimer0MiniSDelay(
+ DWORD dwIoBase,
+ BYTE byRevId,
+ UINT udelay
+ )
+{
+ BYTE byData;
+
+ MACvRegBitsOff(dwIoBase, MAC_REG_MISC_CR0, MISC_CR0_TM0US);
+
+ /* set delay time to udelay, unit is mini-second */
+ VNSvOutPortW(dwIoBase + MAC_REG_SOFT_TIMER0, (WORD)udelay);
+
+ /* delay time */
+ MACvRegBitsOn(dwIoBase, MAC_REG_MISC_CR0, MISC_CR0_TIMER0_EN);
+ MACvRegBitsOff(dwIoBase, MAC_REG_MISC_CR0, MISC_CR0_TIMER0_SUSPEND);
+
+ while (TRUE) {
+ VNSvInPortB(dwIoBase + MAC_REG_MISC_CR0, &byData);
+ if (BITbIsBitOn(byData, MISC_CR0_TIMER0_SUSPEND))
+ break;
+ }
+}
+
+VOID
+MACvWriteEECSR(
+ DWORD dwIoBase,
+ BYTE byValue,
+ BYTE byRevId
+ )
+{
+ VNSvOutPortB(dwIoBase + MAC_REG_EECSR, byValue);
+
+ /* delay 10 micro-seconds using MAC hardware timer */
+ MACvTimer0MicroSDelay(dwIoBase, byRevId, 10);
+}
+
+BYTE
+MACbyGetPhyId(
+ DWORD dwIoBase
+ )
+{
+ BYTE byOrgValue;
+
+ VNSvInPortB(dwIoBase + MAC_REG_MPHY, &byOrgValue);
+ return (BYTE)(byOrgValue & 0x1F);
+}
diff --git a/cpu/arm920t/wmt/mac.h b/cpu/arm920t/wmt/mac.h
new file mode 100755
index 0000000..04dffdb
--- /dev/null
+++ b/cpu/arm920t/wmt/mac.h
@@ -0,0 +1,844 @@
+/*++
+Copyright (c) 2010 WonderMedia Technologies, Inc.
+
+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, see http://www.gnu.org/licenses/>.
+
+WonderMedia Technologies, Inc.
+10F, 529, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C.
+--*/
+
+
+#ifndef __MAC_H__
+#define __MAC_H__
+
+#if !defined(__TTYPE_H__)
+#include "ttype.h"
+#endif
+#if !defined(__TMACRO_H__)
+#include "tmacro.h"
+#endif
+#if !defined(__UPC_H__)
+#include "upc.h"
+#endif
+
+
+/*--------------------- Export Definitions -------------------------*/
+//
+// Registers in the MAC
+//
+#define MAC_REG_PAR 0x00 // physical address
+#define MAC_REG_RCR 0x06 //
+#define MAC_REG_TCR 0x07 //
+#define MAC_REG_CR0 0x08 //
+#define MAC_REG_CR1 0x09 //
+#define MAC_REG_TQWK 0x0A
+#define MAC_REG_ISR 0x0C //
+#define MAC_REG_IMR 0x0E //
+#define MAC_REG_MAR 0x10 //
+#define MAC_REG_MCAM 0x10 //
+#define MAC_REG_VCAM 0x16 //
+#define MAC_REG_CUR_RD_ADDR 0x18 //
+#define MAC_REG_CUR_TD_ADDR 0x1C //
+#define MAC_REG_RX_DMA_PTR 0x60 //
+#define MAC_REG_MPHY 0x6C //
+#define MAC_REG_MIISR 0x6D //
+#define MAC_REG_BCR0 0x6E //
+#define MAC_REG_BCR1 0x6F //
+#define MAC_REG_MIICR 0x70 //
+#define MAC_REG_MIIAD 0x71 //
+#define MAC_REG_MIIDATA 0x72 //
+#define MAC_REG_EECSR 0x74 //
+#define MAC_REG_TEST 0x75 //
+#define MAC_REG_CFGA 0x78 //
+#define MAC_REG_CFGB 0x79 //
+#define MAC_REG_CFGC 0x7A //
+#define MAC_REG_CFGD 0x7B //
+#define MAC_REG_CNTR_MPA 0x7C //
+#define MAC_REG_CNTR_CRC 0x7E //
+
+// Registers only in integrated LAN
+#define MAC_REG_BISTCSR0 0x50 //
+#define MAC_REG_BISTCSR1 0x51 //
+#define MAC_REG_BISTCSR2 0x52 //
+#define MAC_REG_BISTCSR3 0x53 //
+
+// Registers for 3065
+#define MAC_REG_GFTEST 0x54 //
+#define MAC_REG_RFTCMD 0x55 //
+#define MAC_REG_TFTCMD 0x56 //
+#define MAC_REG_GFSTATUS 0x57 //
+#define MAC_REG_BNRY 0x58 //
+#define MAC_REG_CURR 0x5A //
+#define MAC_REG_FIFO_DATA 0x5C //
+#define MAC_REG_CUR_RXDMA 0x60 //
+#define MAC_REG_CUR_TXDMA 0x64 //
+
+// Registers for 3359 Ethernet MAC module
+#define MAC_REG_EEADR 0x7C //
+#define MAC_REG_EECMD 0x7D //
+#define MAC_REG_EESD_CKSUM 0x7E //
+#define MAC_REG_DPMSR 0x7F //
+
+#define MAC_REG_MISC_CR0 0x80 //
+#define MAC_REG_MISC_CR1 0x81 //
+#define MAC_REG_PMCPORT 0x82 //
+#define MAC_REG_STICKHW 0x83 //
+#define MAC_REG_MISR 0x84 //
+#define MAC_REG_MIMR 0x86 //
+#define MAC_REG_CAMMSK 0x88 //
+#define MAC_REG_BPMA 0x8C //
+#define MAC_REG_BPMD 0x8F //
+#define MAC_REG_BPCMD 0x90 //
+#define MAC_REG_BPIN_DATA 0x91 //
+#define MAC_REG_CAMC 0x92 //
+#define MAC_REG_CAMADD 0x93 //
+#define MAC_REG_EECHKSUM 0x93 //
+#define MAC_REG_SUS_MII_AD 0x94 //
+#define MAC_REG_MIBCR 0x94
+#define MAC_REG_MIBDATA 0x96 //
+#define MAC_REG_SUS_PHY_ID 0x96 //
+#define MAC_REG_MIBPORT 0x96 //
+#define MAC_REG_MIBDAT 0x97 //
+#define MAC_REG_PAUSE_TIMER 0x98 //
+#define MAC_REG_FLOWCR0 0x98
+#define MAC_REG_SOFT_TIMER0 0x9C //
+#define MAC_REG_SOFT_TIMER1 0x9E //
+#define MAC_REG_WOLCR_SET 0xA0 //
+#define MAC_REG_PWCFG_SET 0xA1 //
+#define MAC_REG_TSTREG_SET 0xA2 //
+#define MAC_REG_WOLCR1_SET 0xA2 //
+#define MAC_REG_WOLCG_SET 0xA3 //
+#define MAC_REG_WOLCR_CLR 0xA4 //
+#define MAC_REG_PWCFG_CLR 0xA5 //
+#define MAC_REG_TSTREG_CLR 0xA6 //
+#define MAC_REG_WOLCR1_CLR 0xA6 //
+#define MAC_REG_WOLCG_CLR 0xA7 //
+#define MAC_REG_PWRCSR_SET 0xA8 //
+#define MAC_REG_PWRCSR1_SET 0xA9 //
+#define MAC_REG_PWRCSR_CLR 0xAC //
+#define MAC_REG_PWRCSR1_CLR 0xAD //
+#define MAC_REG_PATRN_CRC0 0xB0 //
+#define MAC_REG_PATRN_CRC1 0xB4 //
+#define MAC_REG_PATRN_CRC2 0xB8 //
+#define MAC_REG_PATRN_CRC3 0xBC //
+#define MAC_REG_BYTEMSK0_0 0xC0 //
+#define MAC_REG_BYTEMSK0_1 0xC4 //
+#define MAC_REG_BYTEMSK0_2 0xC8 //
+#define MAC_REG_BYTEMSK0_3 0xCC //
+#define MAC_REG_BYTEMSK1_0 0xD0 //
+#define MAC_REG_BYTEMSK1_1 0xD4 //
+#define MAC_REG_BYTEMSK1_2 0xD8 //
+#define MAC_REG_BYTEMSK1_3 0xDC //
+#define MAC_REG_BYTEMSK2_0 0xE0 //
+#define MAC_REG_BYTEMSK2_1 0xE4 //
+#define MAC_REG_BYTEMSK2_2 0xE8 //
+#define MAC_REG_BYTEMSK2_3 0xEC //
+#define MAC_REG_BYTEMSK3_0 0xF0 //
+#define MAC_REG_BYTEMSK3_1 0xF4 //
+#define MAC_REG_BYTEMSK3_2 0xF8 //
+#define MAC_REG_BYTEMSK3_3 0xFC //
+
+
+//
+// Bits in the RCR register
+//
+#define RCR_RRFT2 0x80 //
+#define RCR_RRFT1 0x40 //
+#define RCR_RRFT0 0x20 //
+#define RCR_PROM 0x10 //
+#define RCR_AB 0x08 //
+#define RCR_AM 0x04 //
+#define RCR_AR 0x02 //
+#define RCR_SEP 0x01 //
+
+//
+// Bits in the TCR register
+//
+#define TCR_RTSF 0x80 //
+#define TCR_RTFT1 0x40 //
+#define TCR_RTFT0 0x20 //
+#define TCR_OFSET 0x08 //
+#define TCR_LB1 0x04 // loopback[1]
+#define TCR_LB0 0x02 // loopback[0]
+#define TCR_PQEN 0x01
+
+//
+// Bits in the CR0 register
+//
+#define CR0_RDMD 0x40 // rx descriptor polling demand
+#define CR0_TDMD 0x20 // tx descriptor polling demand
+#define CR0_TXON 0x10 //
+#define CR0_RXON 0x08 //
+#define CR0_STOP 0x04 // stop MAC, default = 1
+#define CR0_STRT 0x02 // start MAC
+#define CR0_INIT 0x01 // start init process
+
+//
+// Bits in the CR1 register
+//
+#define CR1_SFRST 0x80 // software reset
+#define CR1_RDMD1 0x40 //
+#define CR1_TDMD1 0x20 //
+#define CR1_KEYPAG 0x10 //
+#define CR1_DPOLL 0x08 // disable rx/tx auto polling
+#define CR1_FDX 0x04 // full duplex mode
+#define CR1_ETEN 0x02 // early tx mode
+#define CR1_EREN 0x01 // early rx mode
+
+//
+// Bits in the IMR register
+//
+#define IMR_KEYM 0x8000 //
+#define IMR_SRCM 0x4000 //
+#define IMR_ABTM 0x2000 //
+#define IMR_NORBFM 0x1000 //
+#define IMR_PKTRAM 0x0800 //
+#define IMR_OVFM 0x0400 //
+#define IMR_ETM 0x0200 //
+#define IMR_ERM 0x0100 //
+#define IMR_CNTM 0x0080 //
+#define IMR_BEM 0x0040 //
+#define IMR_RUM 0x0020 //
+#define IMR_TUM 0x0010 //
+#define IMR_TXEM 0x0008 //
+#define IMR_RXEM 0x0004 //
+#define IMR_PTXM 0x0002 //
+#define IMR_PRXM 0x0001 //
+
+//
+// Bits in the ISR (MISR) register
+//
+#define ISR_GENI 0x00008000UL // for 3065
+#define ISR_SRCI 0x00004000UL //
+#define ISR_ABTI 0x00002000UL //
+#define ISR_NORBF 0x00001000UL //
+#define ISR_PKTRA 0x00000800UL //
+#define ISR_OVFI 0x00000400UL //
+#define ISR_UDFI 0x00000200UL // for 3065
+#define ISR_ERI 0x00000100UL //
+#define ISR_CNT 0x00000080UL //
+#define ISR_BE 0x00000040UL //
+#define ISR_RU 0x00000020UL //
+#define ISR_TU 0x00000010UL //
+#define ISR_TXE 0x00000008UL //
+#define ISR_RXE 0x00000004UL //
+#define ISR_PTX 0x00000002UL //
+#define ISR_PRX 0x00000001UL //
+// Bits in MISR
+#define ISR_PWEINT 0x00800000UL // power event report in test mode
+#define ISR_UDPINT_CLR 0x00400000UL // userdefined, host driven interrupt.clear
+#define ISR_UDPINT_SET 0x00200000UL // userdefined, host driven interrupt.Set
+#define ISR_SSRCI 0x00100000UL // suspend well mii polling status change interrupt
+#define ISR_TDWBRAI 0x00080000UL // TD WB queue race
+#define ISR_PHYINT 0x00040000UL // PHY state change interrupt, active by
+ // PHYINTEN (misc.cr[9]) in normal mode
+#define ISR_TM1_INT 0x00020000UL //
+#define ISR_TM0_INT 0x00010000UL //
+
+
+//
+// Bits in the MIISR register
+//
+#define MIISR_N_FDX 0x04
+#define MIISR_LNKFL 0x02 //
+#define MIISR_SPEED 0x01 //
+
+//
+// Bits in the MIICR register
+//
+#define MIICR_MAUTO 0x80 //
+#define MIICR_RCMD 0x40 //
+#define MIICR_WCMD 0x20 //
+#define MIICR_MDPM 0x10 //
+#define MIICR_MOUT 0x08 //
+#define MIICR_MDO 0x04 //
+#define MIICR_MDI 0x02 //
+#define MIICR_MDC 0x01 //
+
+//
+// Bits in the MIIAD register
+//
+#define MIIAD_MIDLE 0x80 //
+#define MIIAD_MSRCEN 0x40 //
+#define MIIAD_MDONE 0x20 //
+//
+// Bits in the MIBCR register
+//
+#define MIBCR_MIBEN 0x10
+#define MIBCR_MIBHALF 0x20
+#define MIBCR_MIBINC 0x40
+#define MIBCR_MIBRTN 0x80
+//
+// Bits in the EECSR register
+//
+#define EECSR_EEPR 0x80 // eeprom programed status, 73h means programed
+#define EECSR_EMBP 0x40 // eeprom embeded programming
+#define EECSR_AUTOLD 0x20 // eeprom content reload
+#define EECSR_DPM 0x10 // eeprom direct programming
+#define EECSR_CS 0x08 // eeprom CS pin
+#define EECSR_SK 0x04 // eeprom SK pin
+#define EECSR_DI 0x02 // eeprom DI pin
+#define EECSR_DO 0x01 // eeprom DO pin
+
+//
+// Bits in the BCR0 register
+//
+#define BCR0_BOOT_MASK ((BYTE) 0xC0)
+#define BCR0_BOOT_INT19 ((BYTE) 0x00)
+#define BCR0_BOOT_INT18 ((BYTE) 0x40)
+#define BCR0_BOOT_LOCAL ((BYTE) 0x80)
+#define BCR0_BOOT_BEV ((BYTE) 0xC0)
+
+#define BCR0_MED2 0x80 //
+#define BCR0_LED100M 0x40 //
+#define BCR0_CRFT2 0x20 //
+#define BCR0_CRFT1 0x10 //
+#define BCR0_CRFT0 0x08 //
+#define BCR0_DMAL2 0x04 //
+#define BCR0_DMAL1 0x02 //
+#define BCR0_DMAL0 0x01 //
+
+//
+// Bits in the BCR1 register
+//
+#define BCR1_MED1 0x80 //
+#define BCR1_MED0 0x40 //
+#define BCR1_CTSF 0x20 //
+#define BCR1_CTFT1 0x10 //
+#define BCR1_CTFT0 0x08 //
+#define BCR1_POT2 0x04 //
+#define BCR1_POT1 0x02 //
+#define BCR1_POT0 0x01 //
+
+//
+// Bits in the CFGA register
+//
+#define CFGA_EELOAD 0x80 // enable eeprom embeded and direct programming
+#define CFGA_MMIOEN 0x20 // memory mapped I/O enable (3043)
+#define CFGA_LED0S0 0x01 //
+
+// VT3106
+#define CFGA_PMHCTG 0x20 // pattern match crc calculation TAG info inclusion
+
+//
+// Bits in the CFGB register
+//
+#define CFGB_QPKTDIS 0x80 //
+#define CFGB_MRLDIS 0x20 //
+
+//
+// Bits in the CFGC register
+//
+#define CFGC_BOOT_RPL ((BYTE) 0x80) //Boot method selection for VT3106S
+#define CFGC_MEDEN 0x80 //
+#define CFGC_BROPT 0x40 //
+#define CFGC_DLYEN 0x20 //
+#define CFGC_DTSEL 0x10 //
+#define CFGC_BTSEL 0x08 //
+#define CFGC_BPS2 0x04 // bootrom select[2]
+#define CFGC_BPS1 0x02 // bootrom select[1]
+#define CFGC_BPS0 0x01 // bootrom select[0]
+//
+// Bits in the CAMCR register
+//
+#define CAMC_CAMRD 0x08
+#define CAMC_CAMWR 0x04
+#define CAMC_VCAMSL 0x02
+#define CAMC_CAMEN 0x01
+
+//
+// Bits in the CFGD register
+//
+#define CFGD_GPIOEN 0x80 //
+#define CFGD_DIAG 0x40 //
+#define CFGD_BOOT_RPL ((BYTE) 0x20) //Boot method selection for VT3106J, VT3206
+#define CFGD_MAGIC 0x10 //
+#define CFGD_CRADOM 0x08 //
+#define CFGD_CAP 0x04 //
+#define CFGD_MBA 0x02 //
+#define CFGD_BAKOPT 0x01 //
+
+#define CFGD_MMIOEN 0x80 // memory mapped I/O enable (3065/3106)
+
+// for VT3065
+
+// Bits in STICKHW
+#define STICKHW_LEGWOLEN 0x0080 // status for software reference
+#define STICKHW_LEGACY_WOLSR 0x0008
+#define STICKHW_LEGACY_WOLEN 0x0004
+#define STICKHW_DS1_SHADOW 0x0002 // R/W by software/cfg cycle
+#define STICKHW_DS0_SHADOW 0x0001 // suspend well DS write port
+
+// Bits in MISC.CR0
+#define MISC_CR0_TM0US 0x20
+#define MISC_CR0_FDXTFEN 0x10 // Full-duplex flow control TX enable
+#define MISC_CR0_FDXRFEN 0x08 // Full-duplex flow control RX enable
+#define MISC_CR0_HDXFEN 0x04 // Half-duplex flow control enable
+#define MISC_CR0_TIMER0_SUSPEND 0x02
+#define MISC_CR0_TIMER0_EN 0x01
+
+// Bits in MISC.CR1
+#define MISC_CR1_FORSRST 0x40
+#define MISC_CR1_VAUXJMP 0x20
+#define MISC_CR1_PHYINT 0x02
+#define MISC_CR1_TIMER1_EN 0x01
+
+// Bits in BPCMD
+#define BPCMD_BPDNE 0x80
+#define BPCMD_EBPWR 0x02
+#define BPCMD_EBPRD 0x01
+
+// Bits in MISR
+#define MISR_PWEINT 0x80 // power event report in test mode
+#define MISR_UDPINT_CLR 0x40 // userdefined, host driven interrupt.clear
+#define MISR_UDPINT_SET 0x20 // userdefined, host driven interrupt.Set
+#define MISR_SSRCI 0x10 // suspend well mii polling status change interrupt
+#define MISR_TDWBRAI 0x08 // TD WB queue race
+#define MISR_PHYINT 0x04 // PHY state change interrupt, active by
+ // PHYINTEN (misc.cr[9]) in normal mode
+#define MISR_TM1_INT 0x02
+#define MISR_TM0_INT 0x01
+
+// Bits in WOLCR
+#define WOLCR_LNKOFF_EN 0x80 // link off detected enable
+#define WOLCR_LNKON_EN 0x40 // link on detected enable
+#define WOLCR_MAGPKT_EN 0x20 // magic packet filter enable
+#define WOLCR_UNICAST_EN 0x10 // unicast filter enable
+#define WOLCR_MSWOLEN3 0x08 // enable pattern match filtering
+#define WOLCR_MSWOLEN2 0x04
+#define WOLCR_MSWOLEN1 0x02
+#define WOLCR_MSWOLEN0 0x01
+
+
+// Bits in PWCFG
+#define PWCFG_SMIITIME 0x80 // internal MII I/F timing
+#define PWCFG_PCISTICK 0x40 // PCI sticky R/W enable
+#define PWCFG_WOLTYPE 0x20 // pulse(1) or button (0)
+#define PWCFG_LEGCY_WOL 0x10
+#define PWCFG_PMCSR_PME_SR 0x08
+#define PWCFG_PMCSR_PME_EN 0x04 // control by PCISTICK
+#define PWCFG_LEGACY_WOLSR 0x02 // Legacy WOL_SR shadow
+#define PWCFG_LEGACY_WOLEN 0x01 // Legacy WOL_EN shadow
+
+// Bits in TestReg
+#define TSTREG_SGENWATCH 0x08
+#define TSTREG_SMCSNOOP 0x04
+#define TSTREG_SMACTEST 0x02
+#define TSTREG_SNORMAL 0x01
+
+// Bits in WOLCFG
+#define WOLCFG_PME_OVR 0x80 // for legacy use, force PMEEN always
+#define WOLCFG_SFDX 0x40 // full duplex while in WOL mode
+#define WOLCFG_SAM 0x20 // accept multicast case reset, default=0
+#define WOLCFG_SAB 0x10 // accept broadcast case reset, default=0
+#define WOLCFG_SMIIACC 0x08 // ??
+#define WOLCFG_SMIIOPT 0x04 // MIIOPT to extend clock in suspendwell
+#define WOLCFG_SSRCEN 0x02 // suspend well mii status change enable
+#define WOLCFG_PHYINTEN 0x01 // 0:PHYINT trigger enable, 1:use internal MII
+ // to report status change
+
+// Bits in DPMSR
+#define DPMSR_PDPM 0x04 // Direct Programming Request
+
+// Bits in RAMBIST CSRs
+#define BISTCSR0_TSTPAT0 0x01 //
+#define BISTCSR0_TSTPAT1 0x02 //
+#define BISTCSR0_TSTMODE 0x04 //
+#define BISTCSR0_TX0RX1 0x08 //
+#define BISTCSR1_BISTGO 0x01 //
+#define BISTCSR2_TSTSR 0x01 //
+#define BISTCSR3_CMDPRTEN 0x02 //
+#define BISTCSR3_RAMTSTEN 0x01 //
+
+
+// Ethernet address filter type
+#define PKT_TYPE_NONE 0x0000 // turn off receiver
+#define PKT_TYPE_DIRECTED 0x0001 // obselete, directed address is always accepted
+#define PKT_TYPE_MULTICAST 0x0002
+#define PKT_TYPE_ALL_MULTICAST 0x0004
+#define PKT_TYPE_BROADCAST 0x0008
+#define PKT_TYPE_PROMISCUOUS 0x0020
+#define PKT_TYPE_LONG 0x2000 // NOTE.... the definition of LONG is >2048 bytes in our chip
+#define PKT_TYPE_RUNT 0x4000
+#define PKT_TYPE_ERROR 0x8000 // accept error packets, e.g. CRC error
+
+
+// Loopback mode
+#define MAC_LB_NONE 0x00 //
+#define MAC_LB_INTERNAL 0x01 //
+#define MAC_LB_PHY 0x02 // MII or Internal-10BaseT loopback
+
+
+// Forced media type
+#define FORCED_MEDIA_NONE 0x00 //
+#define FORCED_MEDIA_AUTO 0x01 //
+#define FORCED_MEDIA_100M_HALF 0x02 // hub card
+#define FORCED_MEDIA_100M_FULL 0x03 // fiber channel
+#define FORCED_MEDIA_10M_HALF 0x04 //
+#define FORCED_MEDIA_10M_FULL 0x05 //
+
+
+// enabled mask value of irq
+#if defined(_SIM)
+#define IMR_MASK_VALUE 0x000BFFFFUL // initial value of IMR
+#else
+#define IMR_MASK_VALUE 0x000BD77FUL // initial value of IMR
+ // ignore ABTI,PKTRACE,CNT to
+ // reduce intr. frequency
+ // NOTE.... do not enable NoBuf int mask at NDIS driver
+ // when (1) NoBuf -> RxThreshold = SF
+ // (2) OK -> RxThreshold = original value
+#endif
+
+
+// wait time within loop
+#define CB_DELAY_LOOP_WAIT 10 // 10ms
+#define CB_DELAY_MII_STABLE 660 //
+
+// max time out delay time
+#define W_MAX_TIMEOUT 0x0FFFU //
+
+/*--------------------- Export Types ------------------------------*/
+
+/*--------------------- Export Macros ------------------------------*/
+#define MACvRegBitsOn(dwIoBase, byRegOfs, byBits) \
+{ \
+ BYTE byData; \
+ VNSvInPortB(dwIoBase + byRegOfs, &byData); \
+ VNSvOutPortB(dwIoBase + byRegOfs, byData | (BYTE)(byBits)); \
+}
+
+
+#define MACvRegBitsOff(dwIoBase, byRegOfs, byBits) \
+{ \
+ BYTE byData; \
+ VNSvInPortB(dwIoBase + byRegOfs, &byData); \
+ VNSvOutPortB(dwIoBase + byRegOfs, byData & (BYTE)~(byBits)); \
+}
+
+
+// set the chip with current rx descriptor address
+#define MACvSetCurrRxDescAddr(dwIoBase, dwCurrDescAddr) \
+{ \
+ VNSvOutPortD(dwIoBase + MAC_REG_CUR_RD_ADDR, \
+ dwCurrDescAddr); \
+}
+
+#define MACvGetCurrRxDescAddr(dwIoBase, pdwCurrDescAddr) \
+{ \
+ VNSvInPortD(dwIoBase + MAC_REG_CUR_RD_ADDR, \
+ (PDWORD)pdwCurrDescAddr); \
+}
+
+
+// set the chip with current tx descriptor address
+#define MACvSetCurrTxDescAddr(dwIoBase, dwCurrDescAddr) \
+{ \
+ VNSvOutPortD(dwIoBase + MAC_REG_CUR_TD_ADDR, \
+ dwCurrDescAddr); \
+}
+
+// set the chip with current tx descriptor address for 3106
+
+#define MACvGetCurrTxDescAddr(dwIoBase, pdwCurrDescAddr) \
+{ \
+ VNSvInPortD(dwIoBase + MAC_REG_CUR_TD_ADDR, \
+ (PDWORD)pdwCurrDescAddr); \
+}
+
+#define MACvReadTallyCounter(dwIoBase, pwRegMPA, \
+ pwRegCRC) \
+{ \
+ VNSvInPortW(dwIoBase + MAC_REG_CNTR_MPA, pwRegMPA); \
+ VNSvInPortW(dwIoBase + MAC_REG_CNTR_CRC, pwRegCRC); \
+}
+
+
+#define MACvStart(dwIoBase) \
+{ \
+ VNSvOutPortB(dwIoBase + MAC_REG_CR0, \
+ CR0_TXON | CR0_RXON | CR0_STRT); \
+}
+
+
+#define MACvRxOn(dwIoBase) \
+{ \
+ BYTE byOrgValue; \
+ VNSvInPortB(dwIoBase + MAC_REG_CR0, &byOrgValue); \
+ byOrgValue = (BYTE)((byOrgValue & ~CR0_STOP) | CR0_RXON | CR0_STRT); \
+ VNSvOutPortB(dwIoBase + MAC_REG_CR0, byOrgValue); \
+}
+
+
+#define MACvTxOn(dwIoBase) \
+{ \
+ BYTE byOrgValue; \
+ VNSvInPortB(dwIoBase + MAC_REG_CR0, &byOrgValue); \
+ byOrgValue = (BYTE)((byOrgValue & ~CR0_STOP) | CR0_TXON | CR0_STRT); \
+ VNSvOutPortB(dwIoBase + MAC_REG_CR0, byOrgValue); \
+}
+
+
+#define MACvTransmit(dwIoBase) \
+{ \
+ BYTE byOrgValue; \
+ VNSvInPortB(dwIoBase + MAC_REG_CR1, &byOrgValue); \
+ byOrgValue = (BYTE)(byOrgValue | CR1_TDMD1); \
+ VNSvOutPortB(dwIoBase + MAC_REG_CR1, byOrgValue); \
+}
+
+
+#define MACvClearStckDS(dwIoBase) \
+{ \
+ BYTE byOrgValue; \
+ VNSvInPortB(dwIoBase + MAC_REG_STICKHW, &byOrgValue); \
+ byOrgValue = byOrgValue & (BYTE)0xFC; \
+ VNSvOutPortB(dwIoBase + MAC_REG_STICKHW, byOrgValue); \
+}
+
+
+#define MACvPwrEvntDisable(dwIoBase) \
+{ \
+ VNSvOutPortB(dwIoBase + MAC_REG_WOLCR_CLR, 0xFF); \
+ VNSvOutPortB(dwIoBase + MAC_REG_WOLCR1_CLR, 0x03); \
+}
+
+/*--------------------- Export Classes ----------------------------*/
+
+/*--------------------- Export Variables --------------------------*/
+
+/*--------------------- Export Functions --------------------------*/
+#ifdef __cplusplus
+extern "C" { /* Assume C declarations for C++ */
+#endif /* __cplusplus */
+
+BOOL
+MACbIsCableLinkOk(
+ DWORD dwIoBase
+ );
+
+BOOL
+MACbIsIn100MMode(
+ DWORD dwIoBase,
+ BYTE byRevId
+ );
+
+VOID
+MACvIsInFullDuplexMode(
+ PBOOL pbFullDup,
+ DWORD dwIoBase
+ );
+
+BOOL
+MACbIsRegBitsOff(
+ DWORD dwIoBase,
+ BYTE byRegOfs,
+ BYTE byTestBits
+ );
+
+BOOL
+MACbIsRegBitsOn(
+ DWORD dwIoBase,
+ BYTE byRegOfs,
+ BYTE byTestBits
+ );
+
+BOOL
+MACbSafeSoftwareReset(
+ DWORD dwIoBase,
+ BYTE byRevId
+ );
+
+BOOL
+MACbStop(
+ DWORD dwIoBase
+ );
+
+BOOL
+MACbSafeStop(
+ DWORD dwIoBase,
+ BYTE byRevId
+ );
+
+BOOL
+MACbSafeRxOff(
+ DWORD dwIoBase,
+ BYTE byRevId
+ );
+
+BOOL
+MACbSafeTxOff(
+ DWORD dwIoBase,
+ BYTE byRevId
+ );
+
+BOOL
+MACbSoftwareReset(
+ DWORD dwIoBase,
+ BYTE byRevId
+ );
+
+BYTE
+MACbyReadEECSR(
+ DWORD dwIoBase
+ );
+
+BYTE
+MACbyReadMIICR(
+ DWORD dwIoBase
+ );
+
+BYTE
+MACbyReadMultiAddr(
+ DWORD dwIoBase,
+ UINT uByteIdx
+ );
+
+VOID
+MACvWriteMultiAddr(
+ DWORD dwIoBase,
+ UINT uByteIdx,
+ BYTE byData
+ );
+
+VOID
+MACvEnableMiiAutoPoll(
+ DWORD dwIoBase
+ );
+
+VOID
+MACvInitialize(
+ DWORD dwIoBase,
+ BYTE byRevId
+ );
+
+VOID
+MACvIntDisable(
+ DWORD dwIoBase,
+ BYTE byRevId
+ );
+
+VOID
+MACvIntEnable(
+ DWORD dwIoBase,
+ BYTE byRevId,
+ DWORD dwMask
+ );
+
+VOID
+MACvSafeDisableMiiAutoPoll(
+ DWORD dwIoBase,
+ BYTE byRevId
+ );
+
+VOID
+MACvRestoreContext(
+ DWORD dwIoBase,
+ BYTE byRevId,
+ PBYTE pbyCxtBuf
+ );
+
+VOID
+MACvReadISR(
+ DWORD dwIoBase,
+ BYTE byRevId,
+ PDWORD pdwValue
+ );
+
+VOID
+MACvWriteISR(
+ DWORD dwIoBase,
+ BYTE byRevId,
+ DWORD dwValue
+ );
+
+VOID
+MACvSaveContext(
+ DWORD dwIoBase,
+ BYTE byRevId,
+ PBYTE pbyCxtBuf
+ );
+
+VOID
+MACvSetDmaLength(
+ DWORD dwIoBase,
+ BYTE byDmaLength
+ );
+
+VOID
+MACvSetDuplexMode(
+ DWORD dwIoBase,
+ BYTE byRevId,
+ BOOL bFullDuplexOn
+ );
+
+VOID
+MACvSetLoopbackMode(
+ DWORD dwIoBase,
+ BYTE byLoopbackMode
+ );
+
+VOID
+MACvSetPacketFilter(
+ DWORD dwIoBase,
+ WORD wFilterType
+ );
+
+VOID
+MACvSetRxThreshold(
+ DWORD dwIoBase,
+ BYTE byThreshold
+ );
+
+VOID
+MACvGetTxThreshold(
+ DWORD dwIoBase,
+ PBYTE pbyThreshold
+ );
+
+VOID
+MACvSetTxThreshold(
+ DWORD dwIoBase,
+ BYTE byThreshold
+ );
+
+VOID
+MACvTimer0MicroSDelay(
+ DWORD dwIoBase,
+ BYTE byRevId,
+ UINT udelay
+ );
+
+VOID
+MACvTimer0MiniSDelay(
+ DWORD dwIoBase,
+ BYTE byRevId,
+ UINT udelay
+ );
+
+VOID
+MACvWriteEECSR(
+ DWORD dwIoBase,
+ BYTE byValue,
+ BYTE byRevId
+ );
+
+BYTE
+MACbyGetPhyId(
+ DWORD dwIoBase
+ );
+
+#ifdef __cplusplus
+} /* End of extern "C" { */
+#endif /* __cplusplus */
+
+#endif // __MAC_H__
+
diff --git a/cpu/arm920t/wmt/macif.c b/cpu/arm920t/wmt/macif.c
new file mode 100755
index 0000000..8c85932
--- /dev/null
+++ b/cpu/arm920t/wmt/macif.c
@@ -0,0 +1,336 @@
+/*++
+Copyright (c) 2010 WonderMedia Technologies, Inc.
+
+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, see http://www.gnu.org/licenses/>.
+
+WonderMedia Technologies, Inc.
+10F, 529, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C.
+--*/
+
+
+/*#ifndef _GLOBAL_H_
+#include "global.h"
+#endif
+#ifndef _EXTVARS_H_
+#include "extvars.h"
+#endif*/
+
+#if !defined(__CARD_H__)
+#include "card.h"
+#endif
+#if !defined(__ADAPTER_H__)
+#include "adapter.h"
+#endif
+#if !defined(__DIAG_H__)
+/* #include "diag.h" */
+#endif
+#include "macif.h"
+#if !defined(__DBG_H__)
+#include "dbg.h"
+#endif
+
+/* #include "emacisr.h" */
+#include <net.h>
+#if MACDBG
+ULONG MacDebugLevel = MACDBG_INFO | MACDBG_ISR;
+#endif
+
+/*--------------------- Static Definitions -------------------------*/
+
+/*--------------------- Static Classes ----------------------------*/
+
+/*--------------------- Static Variables --------------------------*/
+
+/*--------------------- Static Functions --------------------------*/
+/* static BOOL s_bDiagnoseTest(PSAdapterInfo pAdapter, int idxItem, unsigned long *pcbPass, */
+/* unsigned long *pcbFail, WORD wTestCond, BOOL bShowMsg); */
+
+
+/*--------------------- Export Variables --------------------------*/
+/* PVOID g_pvBufferIndex = (PVOID)MEMORY_BUFFER_START; */
+
+/*--------------------- Export Functions --------------------------*/
+/* for inform allocation 0f TD RD & BUFFER have done!! */
+BOOL g_bInit = FALSE;
+#if MACDBG
+static void register_dump(void)
+{
+ int i;
+ DWORD state;
+ printf("resister dump-------------------------------------------\n");
+ for (i = 0; i < 32; i++) {
+ VNSvInPortD(sg_aAdapter->dwIoBase+4*i, &state);
+ printf("%08X\n", state);
+ }
+ printf("--------------------------------------------------------\n");
+ return;
+}
+
+static void TD_RD_dump(void)
+{
+ int i;
+ printf("TD dump-------------------------------------------------\n");
+ for (i = 0; i < sg_aAdapter->cbTD; i++) {
+ printf("TSR0:%02X ", sg_aAdapter->apTD[i]->m_td0TD0.byTSR0);
+ printf("TSR1:%02X ", sg_aAdapter->apTD[i]->m_td0TD0.byTSR1);
+ printf("OWNER:%02X\n", sg_aAdapter->apTD[i]->m_td0TD0.f1Owner);
+ printf("Buffer length:%d ", sg_aAdapter->apTD[i]->m_td1TD1.f15TxBufLen);
+ printf("Chain:%02X ", sg_aAdapter->apTD[i]->m_td1TD1.f1Chain);
+ printf("TCR:%02X\n", sg_aAdapter->apTD[i]->m_td1TD1.byTCR);
+ printf("Bufferaddress:%08X\n", sg_aAdapter->apTD[i]->m_dwTxBufferAddr);
+ printf("NextTD:%08X\n", sg_aAdapter->apTD[i]->m_dwTxNextDescAddr);
+ }
+ printf("RD dump-------------------------------------------------\n");
+ for (i = 0; i < sg_aAdapter->cbTD; i++) {
+ printf("RSR0:%02X ", sg_aAdapter->apRD[i]->m_rd0RD0.byRSR0);
+ printf("RSR1:%02X ", sg_aAdapter->apRD[i]->m_rd0RD0.byRSR1);
+ printf("receive length:%d ", sg_aAdapter->apRD[i]->m_rd0RD0.f15FrameLen);
+ printf("OWNER:%02X\n", sg_aAdapter->apRD[i]->m_rd0RD0.f1Owner);
+ printf("Buffer length:%d\n", sg_aAdapter->apRD[i]->m_rd1RD1.f15RxBufLen);
+ printf("Bufferaddress:%08X\n", sg_aAdapter->apRD[i]->m_dwRxBufferAddr);
+ printf("NextRD:%08X\n", sg_aAdapter->apRD[i]->m_dwRxNextDescAddr);
+ }
+ printf("--------------------------------------------------------\n");
+ return;
+}
+#endif
+int mac_startio(bd_t *bd)
+{
+ int ii, jj;
+ UINT uTotalAdapterNum = 0;
+ UINT uAdapterInWork = 0;
+
+ PSAdapterInfo apAdapter[CB_MAX_NET_DEVICE];
+
+ /* INIT ADAPTER: */
+ /* 1.allocate adapter structure */
+ /* 2.Get info from NIC and store to adapter structure */
+ uTotalAdapterNum = ADPuInitAll();
+#if MACDBG
+ printf("mac_startio - TotalAdapterNum=%d\n", uTotalAdapterNum);
+#endif
+ if (uTotalAdapterNum == 0) {
+ printf("Cannot find the adapter \n");
+ return 1;
+ }
+
+ uTotalAdapterNum = 0;
+
+ for (ii = 0; ii < CB_MAX_NET_DEVICE; ii++) {
+ if ((&sg_aAdapter[ii])->wDevId == W_DEVICE_ID_3106A ||
+ (&sg_aAdapter[ii])->wDevId == W_DEVICE_ID_3053A) {
+ /* Start driver: */
+ /* 1.allocte TD/RD & buffer then init them */
+ /* 2.MAC init */
+ /* 3.enable INT */
+ /* 4.Get status from NIC and store to adapter structure */
+ if (!ADPbBind(&sg_aAdapter[ii])) {
+ printf("Initialization of adapter[%d]'s TD RD or Init of MAC%d fail.\n",
+ ii, ii);
+ continue;
+ }
+ apAdapter[uAdapterInWork] = &sg_aAdapter[ii];
+ uAdapterInWork++;
+ uTotalAdapterNum++;
+#if MACDBG
+ printf("| %d) 10/100 Ethernet MAC%d |\n", ii, ii);
+ printf("| DevID:%04X RevID:%02X |\n",
+ (&sg_aAdapter[ii])->wDevId, (&sg_aAdapter[ii])->byRevId);
+#endif
+ }
+ }
+
+ if (uTotalAdapterNum == 0) {
+ printf("initialization is failed.\n");
+ return 1;
+ }
+
+ for (ii = 0; ii < CB_MAX_NET_DEVICE; ii++) {
+ /* init mac address from bd */
+ if (ii == 0) {
+ for (jj = 0; jj < U_ETHER_ADDR_LEN; jj++)
+ VNSvOutPortB(apAdapter[ii]->dwIoBase + MAC_REG_PAR + jj, bd->bi_enetaddr[jj]);
+ }
+ /* Start mac TX/RX */
+ MACvStart(apAdapter[ii]->dwIoBase);
+ }
+#if MACDBG
+ printf("Initialization done..\n");
+ register_dump();
+ TD_RD_dump();
+#endif
+ g_bInit = TRUE;
+ return 0;
+}
+
+static VOID s_vSetupData_TD(
+ PSAdapterInfo pAdapter, int entry, int length, volatile void *packet
+ )
+{
+ int jj;
+ PBYTE pbyBuf;
+
+ pbyBuf = (PBYTE)pAdapter->apTD[entry]->m_dwTxBufferAddr;
+ jj = 0;
+ while (jj < length) {
+ *(PBYTE)(pbyBuf+jj) = *((PBYTE)(packet+jj));
+ jj++;
+ }
+ /* fill TD */
+ pAdapter->apTD[entry]->m_td1TD1.f15TxBufLen = length >= 60 ? length : 60;
+ pAdapter->apTD[entry]->m_td1TD1.f1Chain = 1;
+ pAdapter->apTD[entry]->m_td1TD1.byTCR |= TCR_EDP|TCR_STP|TCR_IC;
+ pAdapter->apTD[entry]->m_td0TD0.f1Owner = B_OWNED_BY_CHIP;
+ return;
+}
+
+int mac_send(volatile void *packet, int length)
+{
+ int entry, dirty, tmp;
+ /* use mac0 to send */
+ entry = sg_aAdapter->idxTxCurDesc;
+ dirty = sg_aAdapter->idxTxdirtyDesc;
+
+ #if MACDBG
+ printf("enter mac_send\n");
+ #endif
+
+ /* because of no interrupt, check TD status when sending begins */
+ /* 1.check TD's ownership */
+ if (sg_aAdapter->apTD[entry]->m_td0TD0.f1Owner == B_OWNED_BY_CHIP) {
+ MACvRegBitsOn(sg_aAdapter->dwIoBase, (1 << 7), MAC_REG_TQWK);
+ MACvTransmit(sg_aAdapter->dwIoBase);
+ printf("TD overflow and let DMA send first\n");
+
+ #if MACDBG
+ TD_RD_dump();
+ #endif
+ return 1;
+ }
+
+ /* 2.clear current descriptor */
+ sg_aAdapter->apTD[entry]->m_td0TD0.byTSR0 = 0;
+ sg_aAdapter->apTD[entry]->m_td0TD0.byTSR1 = 0;
+ sg_aAdapter->apTD[entry]->m_td0TD0.f12VID = 0;
+ sg_aAdapter->apTD[entry]->m_td0TD0.f4Prioity = 0;
+
+ /* 3.prepare data:memcopy */
+ s_vSetupData_TD(sg_aAdapter, entry, length, packet);
+ /* printf("init TD and data\n"); */
+
+ /* 4.jump to next TD */
+ tmp = (++sg_aAdapter->idxTxCurDesc);
+ sg_aAdapter->idxTxCurDesc = tmp % sg_aAdapter->cbTD;
+
+ #if MACDBG
+ printf("jump to next TD=%d\n", sg_aAdapter->idxTxCurDesc);
+ #endif
+
+ /* 5.trigger TDMD1& enable queue */
+ MACvRegBitsOn(sg_aAdapter->dwIoBase, (1 << 7), MAC_REG_TQWK);
+ MACvTransmit(sg_aAdapter->dwIoBase);
+
+ #if MACDBG
+ printf("data sent!\n", sg_aAdapter->idxTxCurDesc);
+ #endif
+ /* 6.error handling :checking TD if ABT, UND */
+
+ return 0;
+}
+
+int mac_receive(void)
+{
+ PSRxDesc pRD;
+ int length = 0, tmp;
+ DWORD isr_status;
+ /* 1.store ISR */
+ MACvReadISR(sg_aAdapter->dwIoBase, sg_aAdapter->byRevId, &isr_status);
+ /* 2.disable IMR */
+ MACvIntDisable(sg_aAdapter->dwIoBase, sg_aAdapter->byRevId);
+ /* 3clear ISR */
+ MACvWriteISR(sg_aAdapter->dwIoBase, sg_aAdapter->byRevId, isr_status);
+
+ /* 4.handle ISR */
+ /* 5.handle received packets until owner==chip */
+ /* printf("enter mac_receive\n"); */
+ while (TRUE) {
+ pRD = sg_aAdapter->apRD[sg_aAdapter->idxRxCurDesc];
+ /* a.check RD status */
+ /* if owner==chip break; */
+ if (pRD->m_rd0RD0.f1Owner == B_OWNED_BY_CHIP) {
+ /* printf("receive done \n"); */
+ break;
+ }
+ /* if ok, net_receive() */
+ if (pRD->m_rd0RD0.byRSR1&RSR1_RXOK) {
+ NetReceive((volatile uchar *)pRD->m_dwRxBufferAddr, pRD->m_rd0RD0.f15FrameLen-4);
+ length += (pRD->m_rd0RD0.f15FrameLen-4);
+
+#if MACDBG
+ printf("receive ok\n");
+#endif
+ } else{
+ /* else, error handling */
+ printf("receive error status:%02X %02X%\n",
+ pRD->m_rd0RD0.byRSR1,
+ pRD->m_rd0RD0.byRSR0);
+ /* handler will do later */
+ }
+
+ /* b.set own==chip */
+ pRD->m_rd0RD0.f1Owner = B_OWNED_BY_CHIP;
+
+ /* c.increase to next RD */
+ tmp = (++sg_aAdapter->idxRxCurDesc);
+ sg_aAdapter->idxRxCurDesc = tmp % sg_aAdapter->cbRD;
+
+ #if MACDBG
+ printf("jump to next RD =%d\n", sg_aAdapter->idxRxCurDesc);
+ #endif
+ }
+ /* 6.enable IMR */
+ MACvIntEnable(sg_aAdapter->dwIoBase, sg_aAdapter->byRevId, IMR_MASK_VALUE);
+ return length;
+}
+
+void mac_halt(void)
+{
+#if MACDBG
+ printf("mac halt\n");
+#endif
+ //if (g_bInit)
+ // ADPbShutdown(sg_aAdapter);
+ return;
+}
+
+void mii_read(char *devname, unsigned char addr,
+ unsigned char reg, unsigned short *value)
+{
+ SAdapterInfo Adapter;
+ Adapter.dwIoBase = BA_MAC0;
+ Adapter.byPhyId = MACbyGetPhyId(Adapter.dwIoBase);
+ MIIbReadEmbedded(Adapter.dwIoBase, Adapter.byPhyId, addr, value);
+ #if MACDBG
+ printf("%02X %02X %04X\n", addr, reg, *value);
+ #endif
+}
+
+void mii_write(char *devname, unsigned char addr,
+ unsigned char reg, unsigned short value)
+{
+ SAdapterInfo Adapter;
+ Adapter.dwIoBase = BA_MAC0;
+ Adapter.byPhyId = MACbyGetPhyId(Adapter.dwIoBase);
+ MIIbWriteEmbedded(Adapter.dwIoBase, Adapter.byPhyId, addr, value);
+ #if MACDBG
+ printf("%02X %02X %04X\n", addr, reg, value);
+ #endif
+}
diff --git a/cpu/arm920t/wmt/macif.h b/cpu/arm920t/wmt/macif.h
new file mode 100755
index 0000000..44455af
--- /dev/null
+++ b/cpu/arm920t/wmt/macif.h
@@ -0,0 +1,71 @@
+/*++
+Copyright (c) 2010 WonderMedia Technologies, Inc.
+
+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, see http://www.gnu.org/licenses/>.
+
+WonderMedia Technologies, Inc.
+10F, 529, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C.
+--*/
+
+
+#ifndef _MACIF_H_
+#define _MACIF_H_
+
+#include "ttype.h"
+/*--------------------- Export Definitions -------------------------*/
+#define BA_MAC0 0xd8004000 /* MAC0 Base Address */
+#define BA_MAC1 0xd8005000 /* MAC1 Base Address */
+#define MEMORY_BUFFER_START 0x01000000 /* Start address of allocated memory buffer */
+#define CB_MAX_NET_DEVICE 1 /* max. # of the devices */
+#define W_MAX_TIMEOUT 0x0FFFU
+#define MACDBG 0 /* Switch to control debug message (0/1 = Disable/Enable) */
+#define IRQ_ETH0 10
+#define IRQ_ETH1 17
+/* Definition for diagnose test condition */
+#define DIAG_AUTO_TEST 0x0001
+#define DIAG_NO_WAIT 0x0002
+#define DIAG_REPORT 0x0004
+#define DIAG_NO_CABLE_TEST 0x0008
+#define DIAG_EXT_LOOPBACK 0x0010
+
+#define PCI_Configuration_Space_Offset 0x100
+#define VEE 0x5c
+#define VMSTS 0x7c
+#define MaxTimeOut 1000
+
+extern BOOL g_bInit;
+
+/*--------------------- Export Types ------------------------------*/
+
+/*--------------------- Export Macros ------------------------------*/
+
+/*--------------------- Export Classes ----------------------------*/
+
+/*--------------------- Export Variables --------------------------*/
+
+/*--------------------- Export Functions --------------------------*/
+#ifdef __cplusplus
+extern "C" { /* Assume C declarations for C++ */
+#endif /* __cplusplus */
+
+#include <asm/u-boot.h>
+
+int mac_startio(bd_t* bd );
+int mac_send(volatile void *packet, int length);
+int mac_receive(void);
+void mac_halt(void);
+void mii_read(char *devname, unsigned char addr,unsigned char reg, unsigned short * value);
+void mii_write(char *devname, unsigned char addr,unsigned char reg, unsigned short value) ;
+#ifdef __cplusplus
+} /* End of extern "C" { */
+#endif /* __cplusplus */
+
+#endif /* _MACIF_H_ */
diff --git a/cpu/arm920t/wmt/mem.c b/cpu/arm920t/wmt/mem.c
new file mode 100755
index 0000000..dbeadad
--- /dev/null
+++ b/cpu/arm920t/wmt/mem.c
@@ -0,0 +1,113 @@
+/*++
+Copyright (c) 2010 WonderMedia Technologies, Inc.
+
+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, see http://www.gnu.org/licenses/>.
+
+WonderMedia Technologies, Inc.
+10F, 529, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C.
+--*/
+
+
+/*#ifndef _GLOBAL_H_
+#include "global.h"
+#endif
+#ifndef _EXTVARS_H_
+#include "extvars.h"
+#endif*/
+
+#if !defined(__TMACRO_H__)
+#include "tmacro.h"
+#endif
+#if !defined(__MEM_H__)
+#include "mem.h"
+#endif
+#include <malloc.h>
+#include "macif.h"
+
+/*--------------------- Static Definitions -------------------------*/
+
+/*--------------------- Static Classes ----------------------------*/
+
+/*--------------------- Static Variables --------------------------*/
+extern PVOID g_pvBufferIndex;
+
+/*--------------------- Static Functions --------------------------*/
+
+/*--------------------- Export Variables --------------------------*/
+
+/*--------------------- Export Functions --------------------------*/
+
+VOID
+MEMvAlign(
+ PSAllocMap pamMem,
+ UINT uBoundary
+ )
+{
+ ULONG ulAlignmentOffset = 0;
+
+ if ((pamMem->dwRawVAddr % uBoundary) != 0)
+ ulAlignmentOffset = uBoundary - (pamMem->dwRawVAddr % uBoundary);
+ pamMem->dwVAddr = pamMem->dwRawVAddr + ulAlignmentOffset;
+ pamMem->dwPAddr = LODWORD(pamMem->qwRawPAddr) + ulAlignmentOffset;
+}
+
+/*PVOID
+MEMvAllocate(
+ UINT uCount
+ )
+{
+ PVOID pvMemAddr;
+
+ pvMemAddr = g_pvBufferIndex;
+ g_pvBufferIndex += uCount;
+
+ return pvMemAddr;
+}*/
+
+VOID
+MEMvAllocateShared(
+ PSAllocMap pamMem
+ )
+{
+ if (!g_bInit)
+ pamMem->dwRawVAddr = (DWORD)mALLOc((size_t)pamMem->dwRawSize * (size_t)sizeof(BYTE));
+
+ /* If allocation failed, virtual/phisical address == NULL */
+ if ((PVOID)pamMem->dwRawVAddr == NULL) {
+ LODWORD(pamMem->qwRawPAddr) = 0;
+ HIDWORD(pamMem->qwRawPAddr) = 0;
+ return;
+ } else
+ memset((PVOID)pamMem->dwRawVAddr, 0, (size_t)pamMem->dwRawSize * (size_t)sizeof(BYTE));
+
+ LODWORD(pamMem->qwRawPAddr) = pamMem->dwRawVAddr;
+ HIDWORD(pamMem->qwRawPAddr) = 0;
+}
+
+VOID
+MEMvCopy(
+ PVOID pvDst,
+ PVOID pvSrc,
+ UINT uCount
+ )
+{
+ memcpy(pvDst, pvSrc, uCount);
+}
+
+VOID
+MEMvSet(
+ PVOID pvDst,
+ BYTE byPattern,
+ UINT uCount
+ )
+{
+ memset(pvDst, byPattern, uCount);
+}
diff --git a/cpu/arm920t/wmt/mem.h b/cpu/arm920t/wmt/mem.h
new file mode 100755
index 0000000..209c7fa
--- /dev/null
+++ b/cpu/arm920t/wmt/mem.h
@@ -0,0 +1,90 @@
+/*++
+Copyright (c) 2010 WonderMedia Technologies, Inc.
+
+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, see http://www.gnu.org/licenses/>.
+
+WonderMedia Technologies, Inc.
+10F, 529, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C.
+--*/
+
+
+#ifndef __MEM_H__
+#define __MEM_H__
+
+
+#if !defined(__TTYPE_H__)
+#include "ttype.h"
+#endif
+
+
+/*--------------------- Export Definitions -------------------------*/
+/* memory allocation map from RAW(allocated) memory -> ALIGNED memory */
+typedef struct tagSAllocMap {
+ /* this dwRawSize value must assign */
+ DWORD dwRawSize; /* allocated size of the memory block */
+ DWORD dwRawVAddr; /* allocated virtual address of the memory block */
+ QWORD qwRawPAddr; /* allocated physical address of the memory block */
+ DWORD dwSize; /* aligned size (exactly) */
+ DWORD dwVAddr; /* aligned virtual address */
+ DWORD dwPAddr; /* aligned physical address */
+
+ PVOID pvHandle; /* handle to do system-call */
+
+} SAllocMap, *PSAllocMap;
+
+/*--------------------- Export Types ------------------------------*/
+
+/*--------------------- Export Macros ------------------------------*/
+
+/*--------------------- Export Classes ----------------------------*/
+
+/*--------------------- Export Variables --------------------------*/
+
+/*--------------------- Export Functions --------------------------*/
+#ifdef __cplusplus
+extern "C" { /* Assume C declarations for C++ */
+#endif /* __cplusplus */
+
+VOID
+MEMvAlign(
+ PSAllocMap pamMem,
+ UINT uBoundary
+ );
+
+PVOID
+MEMvAllocate(
+ UINT uCount
+ );
+
+VOID
+MEMvAllocateShared(
+ PSAllocMap pamMem
+ );
+
+VOID
+MEMvCopy(
+ PVOID pvDst,
+ PVOID pvSrc,
+ UINT uCount
+ );
+
+VOID
+MEMvSet(
+ PVOID pvDst,
+ BYTE byPattern,
+ UINT uCount
+ );
+
+#ifdef __cplusplus
+} /* End of extern "C" { */
+#endif /* __cplusplus */
+
+#endif /* __MEM_H__ */
diff --git a/cpu/arm920t/wmt/mib.h b/cpu/arm920t/wmt/mib.h
new file mode 100755
index 0000000..9224965
--- /dev/null
+++ b/cpu/arm920t/wmt/mib.h
@@ -0,0 +1,228 @@
+/*++
+Copyright (c) 2010 WonderMedia Technologies, Inc.
+
+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, see http://www.gnu.org/licenses/>.
+
+WonderMedia Technologies, Inc.
+10F, 529, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C.
+--*/
+
+
+#ifndef __MIB_H__
+#define __MIB_H__
+
+
+#if !defined(__TTYPE_H__)
+#include "ttype.h"
+#endif
+#if !defined(__DESC_H__)
+#include "desc.h"
+#endif
+
+
+/*--------------------- Export Definitions -------------------------*/
+//
+// statistic counter
+//
+typedef struct tagSStatCounter {
+ // ISR0,1 status count
+ //
+ DWORD dwIsrRxOK;
+ DWORD dwIsrTxOK;
+ DWORD dwIsrRxErr; // FOV | BUFF | CRC | FAE
+ DWORD dwIsrTxErr; // FUD | BUFF | ABT | BE
+ DWORD dwIsrRxDescUdfl;
+ DWORD dwIsrTxDescUdfl;
+ DWORD dwIsrBusErr;
+ DWORD dwIsrTlyCntOvfl;
+
+ DWORD dwIsrRxErly;
+
+ union {
+ DWORD dwIsrTxErly;
+ DWORD dwIsrTxFifoUdfl;
+ } u1;
+
+ DWORD dwIsrRxFifoOvfl;
+ DWORD dwIsrRxPktRace;
+ DWORD dwIsrRxNoBuf;
+ DWORD dwIsrTxAbort;
+ DWORD dwIsrLinkStatusChg;
+
+ // IsrKey for RevId < 3065 , GenInt for RevId >= 3065
+ union {
+ DWORD dwIsrKey;
+ DWORD dwGenInt;
+ } u2;
+
+ DWORD dwIsrUnknown; // unknown interrupt count
+ DWORD dwIsrTllyMPA; // tally counter for Miss Packet Abort
+ DWORD dwIsrTllyCRC; // tally counter for CRC err
+
+ // MISR for 3065
+ DWORD dwMisrSoftTimer0;
+ DWORD dwMisrSoftTimer1;
+ DWORD dwMisrPhyStatChg;
+ DWORD dwMisrTDWBRace;
+ DWORD dwMisrSSRC;
+ DWORD dwMisrUserDef;
+ DWORD dwMisrPWE;
+
+ DWORD dwIntLinkUp;
+ DWORD dwIntLinkDown;
+
+ // RSR0,1 status count
+ //
+ DWORD dwRsrCRCErr;
+ DWORD dwRsrFrmAlgnErr;
+ DWORD dwRsrFifoOvfl;
+ DWORD dwRsrLong;
+ DWORD dwRsrRunt;
+ DWORD dwRsrBusErr;
+ DWORD dwRsrBufUdfl;
+ DWORD dwRsrErr; // FOV | BUFF | CRC | FAE | SERR
+ DWORD dwRsrOK;
+
+ DWORD dwRsrRxPacket;
+ DWORD dwRsrRxOctet;
+ DWORD dwRsrBroadcast;
+ DWORD dwRsrMulticast;
+ DWORD dwRsrDirected;
+
+ DWORD dwRsrRxFragment;
+ DWORD dwRsrRxFrmLen64;
+ DWORD dwRsrRxFrmLen65_127;
+ DWORD dwRsrRxFrmLen128_255;
+ DWORD dwRsrRxFrmLen256_511;
+ DWORD dwRsrRxFrmLen512_1023;
+ DWORD dwRsrRxFrmLen1024_1518;
+ // for VT3106
+ DWORD dwRsrRxVIDHit;
+ DWORD dwRsrRxTagFrame;
+
+ // TSR0,1 status count
+ //
+ DWORD dwTsrTotalColRetry; // total collision retry count
+ DWORD dwTsrOnceCollision; // this packet only occur one collision
+ DWORD dwTsrMoreThanOnceCollision; // this packet occur more than one collision
+
+ DWORD dwTsrCollision; // this packet has ever occur collision,
+ // that is (dwTsrOnceCollision + dwTsrMoreThanOnceCollision)
+ DWORD dwTsrHeartBeat;
+
+ DWORD dwTsrAbort;
+ DWORD dwTsrLateCollision;
+ DWORD dwTsrCarrierLost;
+ DWORD dwTsrFifoUdfl;
+ DWORD dwTsrBufUdfl;
+ DWORD dwTsrBusErr;
+ DWORD dwTsrJab;
+ DWORD dwTsrErr; // FUD | BUFF | ABT
+ DWORD dwTsrOK;
+
+ DWORD dwTsrTxPacket;
+ DWORD dwTsrTxOctet;
+ DWORD dwTsrBroadcast;
+ DWORD dwTsrMulticast;
+ DWORD dwTsrDirected;
+
+ // RD/TD count
+ DWORD dwCntRxFrmLength;
+ DWORD dwCntTxBufLength;
+
+ BYTE abyCntRxPattern[16];
+ BYTE abyCntTxPattern[16];
+
+ // for pingpong
+ DWORD dwCntNoResponse;
+ DWORD dwCntSerialNumErr;
+ DWORD dwCntPPTDataErr;
+
+ // PATCH....
+ DWORD dwCntRxDataErr; // rx buffer data software compare CRC err count
+ DWORD dwIsrContinuePktRace; // if continueous packet-race happen, should reset
+ DWORD dwIsrContinueNoBuf; // if continueous no-buffer
+
+ // for multi Tx descriptor
+ DWORD dwTDSizePerPacket[CB_MAX_DESC_PER_PKT];
+
+} SStatCounter, *PSStatCounter;
+
+/*--------------------- Export Classes ----------------------------*/
+
+/*--------------------- Export Variables --------------------------*/
+
+/*--------------------- Export Functions --------------------------*/
+#ifdef __cplusplus
+extern "C" { /* Assume C declarations for C++ */
+#endif /* __cplusplus */
+
+VOID
+STAvClearAllCounter(
+ PSStatCounter pStatistic
+ );
+
+VOID
+STAvUpdateIsrStatCounter(
+ PSStatCounter pStatistic,
+ DWORD dwIsr,
+ BYTE byMISR
+ );
+
+VOID
+STAvUpdateRDStatCounter(
+ PVOID pvAdapter,
+ PSRxDesc prdCurr,
+ PBYTE pbyBuffer,
+ UINT cbFrameLength
+ );
+
+VOID
+STAvUpdateRDStatCounterEx(
+ PVOID pvAdapter,
+ PSRxDesc prdCurr,
+ PBYTE pbyBuffer,
+ UINT cbFrameLength
+ );
+
+VOID
+STAvUpdateTDStatCounter(
+ PVOID pvAdapter,
+ PSStatCounter pStatistic,
+ BYTE byTSR0,
+ BYTE byTSR1,
+ PBYTE pbyBuffer,
+ UINT cbFrameLength
+ );
+
+VOID
+STAvUpdateTDStatCounterEx(
+ PVOID pvAdapter,
+ PSStatCounter pStatistic,
+ BYTE byTSR0,
+ BYTE byTSR1,
+ PBYTE pbyBuffer,
+ DWORD cbFrameLength
+ );
+
+VOID
+STAvUpdateTallyCounter(
+ PSStatCounter pStatistic,
+ WORD wMPACount,
+ WORD wCRCCount
+ );
+
+#ifdef __cplusplus
+} /* End of extern "C" { */
+#endif /* __cplusplus */
+
+#endif // __MIB_H__
+
diff --git a/cpu/arm920t/wmt/mii.c b/cpu/arm920t/wmt/mii.c
new file mode 100755
index 0000000..9d0b661
--- /dev/null
+++ b/cpu/arm920t/wmt/mii.c
@@ -0,0 +1,352 @@
+/*++
+Copyright (c) 2010 WonderMedia Technologies, Inc.
+
+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, see http://www.gnu.org/licenses/>.
+
+WonderMedia Technologies, Inc.
+10F, 529, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C.
+--*/
+
+
+#if !defined(__UPC_H__)
+#include "upc.h"
+#endif
+#if !defined(__TBIT_H__)
+#include "tbit.h"
+#endif
+#if !defined(__MAC_H__)
+#include "mac.h"
+#endif
+#if !defined(__MII_H__)
+#include "mii.h"
+#endif
+
+/*--------------------- Static Definitions -------------------------*/
+
+/*--------------------- Static Classes ----------------------------*/
+
+/*--------------------- Static Variables --------------------------*/
+
+/*--------------------- Static Functions --------------------------*/
+
+/*--------------------- Export Variables --------------------------*/
+
+/*--------------------- Export Functions --------------------------*/
+
+BOOL
+MIIbIsAutoNegotiationOn(
+ DWORD dwIoBase,
+ BYTE byRevId
+ )
+{
+ return MIIbIsRegBitsOn(dwIoBase, byRevId, MII_REG_BMCR, BMCR_AUTO);
+}
+
+BOOL
+MIIbIsIn100MMode(
+ DWORD dwIoBase,
+ BYTE byRevId
+ )
+{
+ if (MIIbIsAutoNegotiationOn(dwIoBase, byRevId)) {
+ /* If my TX_FD on, check both TX_FD */
+ if (MIIbIsRegBitsOn(dwIoBase, byRevId, MII_REG_ANAR, ANAR_TXFD)) {
+ /* partner's TX_FD */
+ if (MIIbIsRegBitsOn(dwIoBase, byRevId, MII_REG_ANLPAR, ANLPAR_TXFD))
+ return TRUE;
+ }
+
+ /* If my T4 on, check both T4 */
+ if (MIIbIsRegBitsOn(dwIoBase, byRevId, MII_REG_ANAR, ANAR_T4)) {
+ /* partner's T4 */
+ if (MIIbIsRegBitsOn(dwIoBase, byRevId, MII_REG_ANLPAR, ANLPAR_T4))
+ return TRUE;
+ }
+
+ /* If my TX_HD on, check both TX_HD */
+ if (MIIbIsRegBitsOn(dwIoBase, byRevId, MII_REG_ANAR, ANAR_TX)) {
+ /* partner's TX_HD */
+ if (MIIbIsRegBitsOn(dwIoBase, byRevId, MII_REG_ANLPAR, ANLPAR_TX))
+ return TRUE;
+ }
+
+ /* If my 10_FD on, check both 10_FD */
+ if (MIIbIsRegBitsOn(dwIoBase, byRevId, MII_REG_ANAR, ANAR_10FD)) {
+ /* partner's 10_FD */
+ if (MIIbIsRegBitsOn(dwIoBase, byRevId, MII_REG_ANLPAR, ANLPAR_10FD))
+ return FALSE;
+ }
+
+ /* If all above is not, then it would be 10_HD or no link */
+ /* both case will be 10 Mb */
+ return FALSE;
+ } else {
+ /* If in force mode */
+ if (MIIbIsRegBitsOff(dwIoBase, byRevId, MII_REG_BMCR, BMCR_SPEED))
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+BOOL
+MIIbIsInFullDuplexMode(
+ DWORD dwIoBase,
+ BYTE byRevId
+ )
+{
+ if (MIIbIsAutoNegotiationOn(dwIoBase, byRevId)) {
+ /* if my TX_FD on, check both TX_FD */
+ if (MIIbIsRegBitsOn(dwIoBase, byRevId, MII_REG_ANAR, ANAR_TXFD)) {
+ /* partner's TX_FD */
+ if (MIIbIsRegBitsOn(dwIoBase, byRevId, MII_REG_ANLPAR, ANLPAR_TXFD))
+ return TRUE;
+ }
+
+ /* if my T4 on, check both T4 */
+ if (MIIbIsRegBitsOn(dwIoBase, byRevId, MII_REG_ANAR, ANAR_T4)) {
+ /* partner's T4 */
+ if (MIIbIsRegBitsOn(dwIoBase, byRevId, MII_REG_ANLPAR, ANLPAR_T4))
+ return FALSE;
+ }
+
+ /* if my TX_HD on, check both TX_HD */
+ if (MIIbIsRegBitsOn(dwIoBase, byRevId, MII_REG_ANAR, ANAR_TX)) {
+ /* partner's TX_HD */
+ if (MIIbIsRegBitsOn(dwIoBase, byRevId, MII_REG_ANLPAR, ANLPAR_TX))
+ return FALSE;
+ }
+
+ /* if my 10_FD on, check both 10_FD */
+ if (MIIbIsRegBitsOn(dwIoBase, byRevId, MII_REG_ANAR, ANAR_10FD)) {
+ /* partner's 10_FD */
+ if (MIIbIsRegBitsOn(dwIoBase, byRevId, MII_REG_ANLPAR, ANLPAR_10FD))
+ return TRUE;
+ }
+
+ /* if all above is not, then it would be 10_HD or no link */
+ /* both case will be half duplex */
+ return FALSE;
+ } else {
+ /* if in force mode */
+ if (MIIbIsRegBitsOff(dwIoBase, byRevId, MII_REG_BMCR, BMCR_FDX))
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+BOOL
+MIIbIsRegBitsOff(
+ DWORD dwIoBase,
+ BYTE byRevId,
+ BYTE byMiiAddr,
+ WORD wTestBits
+ )
+{
+ static WORD wOrgData;
+
+ MIIbReadEmbedded(dwIoBase, byRevId, byMiiAddr, &wOrgData);
+ return BITbIsAllBitsOff(wOrgData, wTestBits);
+}
+
+BOOL
+MIIbIsRegBitsOn(
+ DWORD dwIoBase,
+ BYTE byRevId,
+ BYTE byMiiAddr,
+ WORD wTestBits
+ )
+{
+ static WORD wOrgData;
+
+ MIIbReadEmbedded(dwIoBase, byRevId, byMiiAddr, &wOrgData);
+ return BITbIsAllBitsOn(wOrgData, wTestBits);
+}
+
+
+BOOL
+MIIbReadEmbedded(
+ DWORD dwIoBase,
+ BYTE byRevId,
+ BYTE byMiiAddr,
+ PWORD pwData
+ )
+{
+ WORD ww;
+
+ /* Disable MIICR_MAUTO, so that mii addr can be set normally */
+ MACvSafeDisableMiiAutoPoll(dwIoBase, byRevId);
+
+ /* MII reg offset */
+ VNSvOutPortB(dwIoBase + MAC_REG_MIIAD, byMiiAddr);
+
+ /* Turn on MIICR_RCMD */
+ MACvRegBitsOn(dwIoBase, MAC_REG_MIICR, MIICR_RCMD);
+ /* W_MAX_TIMEOUT is the timeout period */
+ for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
+ if (BITbIsBitOff(MACbyReadMIICR(dwIoBase), MIICR_RCMD))
+ break;
+ }
+
+ /* get MII data */
+ VNSvInPortW(dwIoBase + MAC_REG_MIIDATA, pwData);
+
+ MACvEnableMiiAutoPoll(dwIoBase);
+
+ if (ww == W_MAX_TIMEOUT)
+ return FALSE;
+
+ return TRUE;
+}
+
+BOOL
+MIIbWriteEmbedded(
+ DWORD dwIoBase,
+ BYTE byRevId,
+ BYTE byMiiAddr,
+ WORD wData
+ )
+{
+ WORD ww;
+
+ /* disable MIICR_MAUTO, so that mii addr can be set normally */
+ MACvSafeDisableMiiAutoPoll(dwIoBase, byRevId);
+
+ /* MII reg offset */
+ VNSvOutPortB(dwIoBase + MAC_REG_MIIAD, byMiiAddr);
+ /* set MII data */
+ VNSvOutPortW(dwIoBase + MAC_REG_MIIDATA, wData);
+
+ /* turn on MIICR_WCMD */
+ MACvRegBitsOn(dwIoBase, MAC_REG_MIICR, MIICR_WCMD);
+ /* W_MAX_TIMEOUT is the timeout period */
+ for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
+ if (BITbIsBitOff(MACbyReadMIICR(dwIoBase), MIICR_WCMD))
+ break;
+ }
+
+ MACvEnableMiiAutoPoll(dwIoBase);
+
+ if (ww == W_MAX_TIMEOUT)
+ return FALSE;
+
+ return TRUE;
+}
+
+VOID
+MIIvInitialize(
+ DWORD dwIoBase,
+ BYTE byRevId,
+ DWORD dwPhyCmrId
+ )
+{
+ WORD wOrgData;
+
+ /* PHY company/module, don't care revision id */
+ dwPhyCmrId &= CID_REV_ID_MASK_OFF;
+
+ switch (dwPhyCmrId) {
+ case CID_NS:
+ case CID_MYSON:
+ /* for MYSON turn on LED to indicate full-duplex in 10M mode */
+ MIIvRegBitsOn(dwIoBase, byRevId, MII_REG_PCR, PCR_LED4MODE);
+ break;
+
+ case CID_ESI:
+ /* for ESI, set TX/ACT LED option to ACT */
+ MIIvRegBitsOn(dwIoBase, byRevId, MII_REG_PCSR, PCSR_LEDON4ACT);
+ break;
+
+ default:
+ break;
+ }
+
+ /* if ISO is on, turn it off */
+ MIIbReadEmbedded(dwIoBase, byRevId, MII_REG_BMCR, &wOrgData);
+ if (BITbIsBitOn(wOrgData, BMCR_ISO)) {
+ wOrgData &= ~BMCR_ISO;
+ MIIbWriteEmbedded(dwIoBase, byRevId, MII_REG_BMCR, wOrgData);
+ }
+}
+
+VOID
+MIIvSetLoopbackMode(
+ DWORD dwIoBase,
+ BYTE byRevId,
+ BYTE byLoopbackMode
+ )
+{
+ /* handle AUTO-NEGO */
+ switch (byLoopbackMode) {
+ case MII_LB_NONE:
+ //check MII loopback status
+ if(MIIbIsRegBitsOn(dwIoBase, byRevId, MII_REG_BMCR, BMCR_LBK)){
+ /* turn off MII loopback */
+ MIIvRegBitsOff(dwIoBase, byRevId, MII_REG_BMCR, BMCR_LBK);
+ /* must turn on AUTO-NEGO after turn off BMCR_LBK, otherwise */
+ /* the AUTO-NEGO process will never end in some PHY (e.g. ESI...) */
+ MIIvSetAutoNegotiationOn(dwIoBase, byRevId);
+ }
+ break;
+
+ case MII_LB_INTERNAL:
+ MIIvSetAutoNegotiationOff(dwIoBase, byRevId);
+ MIIvRegBitsOn(dwIoBase, byRevId, MII_REG_BMCR, BMCR_LBK);
+ /* select 100M */
+ MIIvRegBitsOn(dwIoBase, byRevId, MII_REG_BMCR, BMCR_SPEED);
+ break;
+
+ case MII_LB_ISO:
+ /* we achieve isolation by do loopback in MII not in Transceiver */
+ MIIvSetAutoNegotiationOff(dwIoBase, byRevId);
+ MIIvRegBitsOn(dwIoBase, byRevId, MII_REG_BMCR, BMCR_LBK);
+ /* select 100M */
+ MIIvRegBitsOn(dwIoBase, byRevId, MII_REG_BMCR, BMCR_SPEED);
+ break;
+
+ default:
+ break;
+ }
+
+ /* wait for MII loopback to stable */
+ PCAvDelayByIO(CB_DELAY_MII_LB_STABLE);
+}
+
+VOID
+MIIvWaitForNwayCompleted(
+ DWORD dwIoBase,
+ BYTE byRevId
+ )
+{
+ UINT uu;
+
+ /* delay about 8 sec. */
+ /* wait for AUTO-NEGO to complete (may never complete if */
+ /* no link), after that then, we can get correct link status */
+ /* NOTE: because I have no timer, so looping is used, */
+ /* if timer is available in your OS, use timer */
+ /* in stead of looping */
+
+ /* wait for BMSR_AUTOCM to off */
+ for (uu = 0; uu < CB_MAX_COUNT_AUTO_COMPLETE; uu++) {
+ if (MIIbIsRegBitsOff(dwIoBase, byRevId, MII_REG_BMSR, BMSR_AUTOCM))
+ break;
+ }
+ /* wait for BMSR_AUTOCM to on */
+ /* NOTE.... read BMSR_AUTOCM bit will also clear BMSR_LNK bit */
+ for (uu = 0; uu < CB_MAX_COUNT_AUTO_COMPLETE; uu++) {
+ /* if AUTO-NEGO completed, then go out this loop */
+ /* otherwise, count down to time out */
+ if (MIIbIsRegBitsOn(dwIoBase, byRevId, MII_REG_BMSR, BMSR_AUTOCM))
+ break;
+ }
+}
diff --git a/cpu/arm920t/wmt/mii.h b/cpu/arm920t/wmt/mii.h
new file mode 100755
index 0000000..06e4228
--- /dev/null
+++ b/cpu/arm920t/wmt/mii.h
@@ -0,0 +1,270 @@
+/*++
+Copyright (c) 2010 WonderMedia Technologies, Inc.
+
+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, see http://www.gnu.org/licenses/>.
+
+WonderMedia Technologies, Inc.
+10F, 529, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C.
+--*/
+
+
+#ifndef __MII_H__
+#define __MII_H__
+
+#if !defined(__TTYPE_H__)
+#include "ttype.h"
+#endif
+
+
+/*--------------------- Export Definitions -------------------------*/
+#define CB_DELAY_MII_LB_STABLE (1000)
+#define MAX_PHY_DEVICE 32 // max. # of PHY in a MII bus
+
+//
+// Registers in the MII (offset unit is WORD)
+//
+#define MII_REG_BMCR 0x00 // physical address
+#define MII_REG_BMSR 0x01 //
+#define MII_REG_PHYID1 0x02 // OUI
+#define MII_REG_PHYID2 0x03 // OUI + Module ID + REV ID
+#define MII_REG_ANAR 0x04 //
+#define MII_REG_ANLPAR 0x05 //
+#define MII_REG_MODCFG 0x10
+// NS, MYSON only
+#define MII_REG_PCR 0x17 //
+// ESI only
+#define MII_REG_PCSR 0x17 //
+
+//
+// Bits in the BMCR register
+//
+#define BMCR_RESET 0x8000 //
+#define BMCR_LBK 0x4000 //
+#define BMCR_SPEED 0x2000 //
+#define BMCR_AUTO 0x1000 //
+#define BMCR_PD 0x0800 //
+#define BMCR_ISO 0x0400 //
+#define BMCR_REAUTO 0x0200 //
+#define BMCR_FDX 0x0100 //
+
+//
+// Bits in the BMSR register
+//
+#define BMSR_AUTOCM 0x0020 //
+#define BMSR_LNK 0x0004 //
+
+//
+// Bits in the ANAR register
+//
+#define ANAR_ASMDIR 0x0800 // Asymmetric PAUSE support
+#define ANAR_PAUSE 0x0400 // Symmetric PAUSE Support
+#define ANAR_T4 0x0200 //
+#define ANAR_TXFD 0x0100 //
+#define ANAR_TX 0x0080 //
+#define ANAR_10FD 0x0040 //
+#define ANAR_10 0x0020 //
+
+//
+// Bits in the ANLPAR register
+//
+#define ANLPAR_ASMDIR 0x0800 // Asymmetric PAUSE support
+#define ANLPAR_PAUSE 0x0400 // Symmetric PAUSE Support
+#define ANLPAR_T4 0x0200 //
+#define ANLPAR_TXFD 0x0100 //
+#define ANLPAR_TX 0x0080 //
+#define ANLPAR_10FD 0x0040 //
+#define ANLPAR_10 0x0020 //
+
+
+// NS, MYSON only
+
+//
+// Bits in the PCR register
+//
+#define PCR_LED4MODE 0x0002 //
+
+
+// ESI only
+
+//
+// Bits in the PCR register
+//
+#define PCSR_LEDON4ACT 0x0080 //
+
+
+// Loopback mode
+#define MII_LB_NONE 0x00 //
+#define MII_LB_INTERNAL 0x01 //
+#define MII_LB_ISO 0x02 // isolate endec/twister
+
+
+//
+// Company ID
+//
+#define CID_REV_ID_MASK_OFF 0xFFFFFFF0UL // the last 4-bit is revision id,
+ // we don't care it
+
+#define CID_NS 0x20005C00UL // OUI = 08-00-17 , 0x2000 5C01
+#define CID_ESI 0x00437400UL // , 0x0043 7412
+#define CID_DAVICOM 0x0181B800UL // OUI = 00-60-6E , 0x0181 B800
+#define CID_DAVICOM_B 0x0181B802UL //
+#define CID_MYSON 0x0302D000UL // , 0x0302 D000
+#define CID_SEEQ 0x0016F880UL // OUI = 00-A0-7D , 0x0016 F880
+#define CID_BROADCOM 0x00406000UL // , 0x0040 61B1
+#define CID_KENDIN 0x00221720UL // OUI = 00-10-A1 , 0x0022 1720
+#define CID_ADHOC 0x00225610UL // OUI = 00-10-A9 , 0x0022 5610
+#define CID_AMD_AM79C901_T 0x00006B70UL // , 0x0000 6B70
+#define CID_VIA_VT3072 0x01018F20UL
+//#define CID_VIA_VT3082 0x01018F20UL
+
+#define CB_MAX_COUNT_AUTO_COMPLETE (0x1244)
+ // AUTO-NEGO complete, polling time out count
+ // about 6 sec.
+
+/*--------------------- Export Types ------------------------------*/
+
+/*--------------------- Export Macros ------------------------------*/
+
+#define MIIvRegBitsOn(dwIoBase, byRevId, byMiiAddr, wBits) \
+{ \
+ WORD wOrgData; \
+ MIIbReadEmbedded(dwIoBase, byRevId, byMiiAddr, &wOrgData); \
+ MIIbWriteEmbedded(dwIoBase, byRevId, byMiiAddr, \
+ (WORD)(wOrgData | wBits)); \
+}
+
+
+#define MIIvRegBitsOff(dwIoBase, byRevId, byMiiAddr, wBits) \
+{ \
+ WORD wOrgData; \
+ MIIbReadEmbedded(dwIoBase, byRevId, byMiiAddr, &wOrgData); \
+ MIIbWriteEmbedded(dwIoBase, byRevId, byMiiAddr, \
+ (WORD)(wOrgData & (~wBits))); \
+}
+
+
+#define MIIvReadPhyCmrId(dwIoBase, byRevId, pdwPhyCmrId) \
+{ \
+ MIIbReadEmbedded(dwIoBase, byRevId, MII_REG_PHYID2, \
+ (PWORD)pdwPhyCmrId); \
+ MIIbReadEmbedded(dwIoBase, byRevId, MII_REG_PHYID1, \
+ ((PWORD)pdwPhyCmrId) + 1); \
+}
+
+
+#define MIIvSetAutoNegotiationOn(dwIoBase, byRevId) \
+{ \
+ MIIvRegBitsOn(dwIoBase, byRevId, MII_REG_BMCR, (BMCR_AUTO|BMCR_REAUTO)); \
+}
+
+
+#define MIIvSetAutoNegotiationOff(dwIoBase, byRevId) \
+{ \
+ MIIvRegBitsOff(dwIoBase, byRevId, MII_REG_BMCR, BMCR_AUTO); \
+}
+
+
+#define MIIvSetResetOn(dwIoBase, byRevId) \
+{ \
+ MIIvRegBitsOn(dwIoBase, byRevId, MII_REG_BMCR, BMCR_RESET); \
+}
+
+
+#define MIIvSetReAuto(dwIoBase, byRevId) \
+{ \
+ MIIvRegBitsOn(dwIoBase, byRevId, MII_REG_BMCR, BMCR_REAUTO);\
+}
+
+/*--------------------- Export Classes ----------------------------*/
+
+/*--------------------- Export Variables --------------------------*/
+
+/*--------------------- Export Functions --------------------------*/
+#ifdef __cplusplus
+extern "C" { /* Assume C declarations for C++ */
+#endif /* __cplusplus */
+
+BOOL
+MIIbIsAutoNegotiationOn(
+ DWORD dwIoBase,
+ BYTE byRevId
+ );
+
+BOOL
+MIIbIsIn100MMode(
+ DWORD dwIoBase,
+ BYTE byRevId
+ );
+
+BOOL
+MIIbIsInFullDuplexMode(
+ DWORD dwIoBase,
+ BYTE byRevId
+ );
+
+BOOL
+MIIbIsRegBitsOff(
+ DWORD dwIoBase,
+ BYTE byRevId,
+ BYTE byMiiAddr,
+ WORD wTestBits
+ );
+
+BOOL
+MIIbIsRegBitsOn(
+ DWORD dwIoBase,
+ BYTE byRevId,
+ BYTE byMiiAddr,
+ WORD wTestBits
+ );
+
+BOOL
+MIIbReadEmbedded(
+ DWORD dwIoBase,
+ BYTE byRevId,
+ BYTE byMiiAddr,
+ PWORD pwData
+ );
+
+BOOL
+MIIbWriteEmbedded(
+ DWORD dwIoBase,
+ BYTE byRevId,
+ BYTE byMiiAddr,
+ WORD wData
+ );
+
+VOID
+MIIvInitialize(
+ DWORD dwIoBase,
+ BYTE byRevId,
+ DWORD dwPhyCmrId
+ );
+
+VOID
+MIIvSetLoopbackMode(
+ DWORD dwIoBase,
+ BYTE byRevId,
+ BYTE byLoopbackMode
+ );
+
+VOID
+MIIvWaitForNwayCompleted(
+ DWORD dwIoBase,
+ BYTE byRevId
+ );
+
+#ifdef __cplusplus
+} /* End of extern "C" { */
+#endif /* __cplusplus */
+
+#endif // __MII_H__
+
diff --git a/cpu/arm920t/wmt/mmc.c b/cpu/arm920t/wmt/mmc.c
new file mode 100755
index 0000000..9782a57
--- /dev/null
+++ b/cpu/arm920t/wmt/mmc.c
@@ -0,0 +1,2854 @@
+/*++
+Copyright (c) 2013 WonderMedia Technologies, Inc.
+
+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, see http://www.gnu.org/licenses/>.
+
+WonderMedia Technologies, Inc.
+4F, 531-1, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C.
+--*/
+/*
+ * (C) Copyright 2003
+ * Kyle Harris, Nexus Technologies, Inc. kharris@nexus-tech.net
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <config.h>
+#include <common.h>
+#include <malloc.h>
+#include <mmc.h>
+#include <asm/errno.h>
+#include <asm/arch/hardware.h>
+#include <part.h>
+#include "ttype.h"
+#include "./sdc.h"
+#include <asm-arm/arch-wmt/common_def.h>
+#include "../../../board/wmt/include/wmt_clk.h"
+/*#define CONFIG_MMC*/
+
+#ifdef CONFIG_MMC
+/***********************************************************************************/
+#define BA_SDC_1 0xD800A400 /* SD Controller Base Address */
+#define BA_SDCDMA_1 0xD800A500 /* SD Controller DMA Base Address */
+#define BA_SDC 0xD800A000 /* SD Controller Base Address */
+#define BA_SDCDMA 0xD800A100 /* SD Controller DMA Base Address */
+#define BA_SDC_2 0xD800A800 /* SD Controller Base Address */
+#define BA_SDCDMA_2 0xD800A900 /* SD Controller DMA Base Address */
+
+
+#define SDMMC_SET_BLKSIZE(pHC, b) {pHC->blklen &= 0xF800; pHC->blklen |= ((b) & 0x7FF); }
+
+/* PMC module reg */
+#define PMC_BASE_ADDR 0XD8130000
+#define PMC_SD1_CLK REG32_PTR(PMC_BASE_ADDR + 0x324)
+#define PMC_SD_CLK REG32_PTR(PMC_BASE_ADDR + 0x328)
+#define PMC_Enable_SD_CLK REG32_PTR(PMC_BASE_ADDR + 0x254)
+#define PMC_PLLB_MULTIPLIER REG32_PTR(PMC_BASE_ADDR + 0x204)
+#define PMC_SD_CLOCK_EN 0x40000
+
+/* GPIO module reg */
+#define GPIO_BASE_ADDR 0xD8110000
+#define GPIO_SD_ENABLE REG32_PTR(GPIO_BASE_ADDR + 0x40)
+
+
+PWMT_SDMMC_REG pSd_Reg = (PWMT_SDMMC_REG) BA_SDC;
+struct _SD_PDMA_REG_ *pSd_PDma_Reg = (struct _SD_PDMA_REG_ *) BA_SDCDMA;
+PGPIO_REG GpioReg = (PGPIO_REG) GPIO_BASE_ADDR;
+/*static unsigned long RCA;*/
+sd_info_t *SDDevInfo;
+sd_info_t SD0DevInfo;
+sd_info_t SD1DevInfo;
+sd_info_t SD2DevInfo;
+
+static unsigned int Bitmode ;
+static unsigned short chip_id;
+static block_dev_desc_t *mmc_dev;
+static block_dev_desc_t mmc0_dev;
+static block_dev_desc_t mmc1_dev;
+static block_dev_desc_t mmc2_dev;
+
+static int mmc_ready;
+static int mmc0_ready;
+static int mmc1_ready;
+static int mmc2_ready;
+
+#define SDPRINTK(x...) do { } while (0)/*printf(x)*/
+extern int auto_pll_divisor(enum dev_id dev, enum clk_cmd cmd, int unit, int freq);
+
+/**********************************************************************************/
+int sd_command(unsigned char command, unsigned char cmdtype, unsigned int arg, unsigned char rsptype);
+int sd_config_pdma(unsigned long *DescAddr, char dir);
+unsigned int get_chip_version(void);
+
+void Change_SD_host(int host_num)
+{
+ switch (host_num) {
+ case 0:
+ pSd_Reg = (PWMT_SDMMC_REG) BA_SDC;
+ pSd_PDma_Reg = (struct _SD_PDMA_REG_ *) BA_SDCDMA;
+ SDDevInfo = &SD0DevInfo;
+ mmc_dev = &mmc0_dev;
+ mmc_ready = mmc0_ready;
+ break;
+ case 1:
+ if (chip_id == 0x3437 ||
+ chip_id == 0x3429 ||
+ chip_id == 0x3451 ||
+ chip_id == 0x3445 ||
+ chip_id == 0x3481 ||
+ chip_id == 0x3498) {
+
+ pSd_Reg = (PWMT_SDMMC_REG) BA_SDC_1;
+ pSd_PDma_Reg = (struct _SD_PDMA_REG_ *) BA_SDCDMA_1;
+ SDDevInfo = &SD1DevInfo;
+ mmc_dev = &mmc1_dev;
+ mmc_ready = mmc1_ready;
+ }
+ break;
+ case 2:
+ if (chip_id == 0x3445 ||
+ chip_id == 0x3481 ||
+ chip_id == 0x3498) {
+
+ pSd_Reg = (PWMT_SDMMC_REG) BA_SDC_2;
+ pSd_PDma_Reg = (struct _SD_PDMA_REG_ *) BA_SDCDMA_2;
+ SDDevInfo = &SD2DevInfo;
+ mmc_dev = &mmc2_dev;
+ mmc_ready = mmc2_ready;
+ }
+ break;
+ default:
+ break;
+ }
+}
+int SD_Init_PDMA(void)
+{
+ pSd_PDma_Reg->DMA_GCR = SD_PDMA_GCR_SOFTRESET;
+ pSd_PDma_Reg->DMA_GCR = SD_PDMA_GCR_DMA_EN;
+ if (pSd_PDma_Reg->DMA_GCR & SD_PDMA_GCR_DMA_EN)
+ return 0;
+ else
+ return 1;
+}
+
+int PrintPDMAReg(void)
+{
+ printf("0x00 =%x\n", pSd_PDma_Reg->DMA_GCR);
+ printf("0x04 =%x\n", pSd_PDma_Reg->DMA_IER);
+ printf("0x08 =%x\n", pSd_PDma_Reg->DMA_ISR);
+ printf("0x0C =%x\n", pSd_PDma_Reg->DMA_DESPR);
+ printf("0x10 =%x\n", pSd_PDma_Reg->DMA_RBR);
+ printf("0x14 =%x\n", pSd_PDma_Reg->DMA_DAR);
+ printf("0x18 =%x\n", pSd_PDma_Reg->DMA_BAR);
+ printf("0x1C =%x\n", pSd_PDma_Reg->DMA_CPR);
+ printf("0x20 =%x\n", pSd_PDma_Reg->DMA_CCR);
+}
+
+/* Check Align problem. if brffer size have no align, break up a descript
+ into two descripts for Align problem using AXI bus.*/
+int sd_check_long_desc(unsigned long *DescAddr, int Desc_num, unsigned int ReqCount,
+ unsigned long *BufferAddr, unsigned long *BranchAddr, int End)
+{
+ unsigned long first_size, second_size;
+ SDPRINTK("\nDescAddr=0x%x, Desc_num=%d, ReqCount=%d,\
+ BufferAddr=0x%x, BranchAddr=0x%x, End=%d\n",
+ DescAddr, Desc_num, ReqCount, BufferAddr, BranchAddr, End);
+
+ first_size = (unsigned long)BufferAddr % 0x1000;
+ first_size = 0x1000 - first_size;
+
+ SDPRINTK("firstsize=%d, buf+first 0x%x, sizeof=0x%x\n",
+ first_size,
+ (unsigned int)BufferAddr + first_size,
+ sizeof(struct _SD_PDMA_DESC_L));
+
+ if ((ReqCount > first_size) && (Desc_num > 1)) {
+ sd_init_long_desc(DescAddr, first_size, BufferAddr, BranchAddr, 0);
+ second_size = ReqCount - first_size;
+ sd_init_long_desc(BranchAddr, second_size, ((unsigned int)BufferAddr + first_size),
+ (unsigned int)BranchAddr + sizeof(struct _SD_PDMA_DESC_L), 1);
+ } else {
+ sd_init_long_desc(DescAddr, ReqCount, BufferAddr, BranchAddr, 1);
+ }
+
+ return 0;
+}
+
+int sd_init_long_desc(unsigned long *DescAddr, unsigned int ReqCount,
+ unsigned long *BufferAddr, unsigned long *BranchAddr, int End)
+{
+ struct _SD_PDMA_DESC_L *CurDes_L;
+ CurDes_L = (struct _SD_PDMA_DESC_L *) DescAddr;
+ /*Bug, Fix by leoli @2009.4 */
+ CurDes_L->ReqCount = (u16) ReqCount;
+ CurDes_L->i = 0;
+ CurDes_L->format = 1;
+ CurDes_L->end = 0;
+ CurDes_L->DataBufferAddr = BufferAddr;
+ CurDes_L->BranchAddr = BranchAddr;
+ SDPRINTK("DescAddr=0x%x, ReqCount=%d\
+ BufferAddr=0x%x, BranchAddr=0x%x,End=%d\n",
+ DescAddr, ReqCount, BufferAddr, BranchAddr, End);
+ if (End) {
+ CurDes_L->end = 1;
+ CurDes_L->i = 1;
+ }
+ SDPRINTK("ReqCount=0x%x, i=0x%x, end=0x%x, format=0x%d,\
+ DataBufferAddr=0x%x,BranchAddr=0x%x\n",
+ CurDes_L->ReqCount, CurDes_L->i, CurDes_L->end, CurDes_L->format,
+ CurDes_L->DataBufferAddr, CurDes_L->BranchAddr);
+ return 0;
+}
+
+int sd_pdma_handler(void)
+{
+ unsigned long status = SD_PDMA_CCR_Evt_no_status;
+ long count = 0;
+/* SDPRINTK("Before polling DMA status:\nSTS[0-3]: 0x%x 0x%x 0x%x 0x%x \n",pSd_Reg->str0,
+ pSd_Reg->str1, pSd_Reg->str2, pSd_Reg->str3);*/
+ count = 0x10000000;
+ /* polling CSR TC status */
+
+ do {
+ count--;
+ if (pSd_PDma_Reg->DMA_ISR & SD_PDMA_IER_INT_STS) {
+ SDPRINTK("pSd_PDma_Reg->DMA_CCR = 0x%lx!\n", pSd_PDma_Reg->DMA_CCR);
+ status = pSd_PDma_Reg->DMA_CCR & SD_PDMA_CCR_EvtCode;
+ pSd_PDma_Reg->DMA_ISR |= SD_PDMA_IER_INT_STS;
+ break ;
+ }
+ if (count == 0) {
+ SDPRINTK("SDPDMA Time Out!\n");
+ break;
+ }
+ } while (1);
+
+ /* SDPRINTK("\nPolling CSR TC status: 0x%lx!\n",status); */
+ if (status == SD_PDMA_CCR_Evt_ff_underrun)
+ SDPRINTK("PDMA Buffer under run!\n");
+
+ if (status == SD_PDMA_CCR_Evt_ff_overrun)
+ SDPRINTK("PDMA Buffer over run!\n");
+
+ if (status == SD_PDMA_CCR_Evt_desp_read)
+ SDPRINTK("PDMA read Descriptor error!\n");
+
+ if (status == SD_PDMA_CCR_Evt_data_rw)
+ SDPRINTK("PDMA read/write memory error!\n");
+
+ if (status == SD_PDMA_CCR_Evt_early_end)
+ SDPRINTK("PDMA read early end!\n");
+
+ if (count == 0) {
+ SDPRINTK("SDPDMA TimeOut!\n");
+ return -1;
+ }
+
+ count = 0x10000000;
+ /* check write direction */
+ /* Leo fix bug here, never go into the branch. */
+ if ((pSd_PDma_Reg->DMA_CCR & SD_PDMA_CCR_peripheral_to_IF) == SD_PDMA_CCR_IF_to_peripheral) {
+ if (pSd_Reg->cmdi == WRITE_MULTIPLE_BLOCK) {
+ while (!(pSd_Reg->str0 & 0x10)) {
+ count--;
+ if (count == 0) {
+ printf("SD Control Data TimeOut!\n");
+ return -1;
+ }
+ }
+ }
+ while (!(pSd_Reg->str0 & 0x30)) {
+ count--;
+ if (count == 0) {
+ printf("SD Control Data TimeOut!\n");
+ return -1;
+ }
+ }
+ }
+ /* printf("SD handler count = %x\n",count); */
+ return 0 ;
+}
+
+void sdmmcSendExCSD(unsigned long *ahb_mem_data_in)
+{
+ unsigned char Resp1[4], tmp;
+ struct _SD_PDMA_DESC_L ReadDesc;
+ /* bzero(ahb_mem_data_in, 512); */
+ memset(ahb_mem_data_in, 0x0, 512);
+ pSd_Reg->blkcnt = 0x01;
+
+ /* set normal speed bus mode */
+ pSd_Reg->extctl &= 0x7F;
+
+ /* set time-out value */
+ pSd_Reg->rtor = 0x1F;
+ pSd_Reg->ctlr |= 0x08; /* response FIFO reset */
+
+ pSd_Reg->str0 |= 0xFF;
+ pSd_Reg->str1 |= 0xFF;
+
+ SD_Init_PDMA();
+ sd_init_long_desc(
+ (unsigned long*)(&ReadDesc),
+ 512,
+ ahb_mem_data_in,
+ (unsigned long *)(&ReadDesc + sizeof(struct _SD_PDMA_DESC_L)),
+ 1
+ );
+ sd_config_pdma((unsigned long *)(&ReadDesc), SD_PDMA_READ);
+
+ if (sd_command(SEND_EXT_CSD, 2, 0x0, R1) != 0) {
+ SDPRINTK("\nErr : send extend csd! \n");
+ return;
+ }
+
+ tmp = pSd_Reg->resr[0];
+ Resp1[0] = pSd_Reg->resr[1];
+ Resp1[1] = pSd_Reg->resr[2];
+ Resp1[2] = pSd_Reg->resr[3];
+ Resp1[3] = pSd_Reg->resr[4];
+ /*
+ SDPRINTK("SWT response[31:24] =%x \n\r",Resp1[0]);
+ SDPRINTK("SWT response[23:16] =%x \n\r",Resp1[1]);
+ SDPRINTK("SWT response[15:8] =%x \n\r", Resp1[2]);
+ SDPRINTK("SWT response[7:0] =%x \n\r", Resp1[3]);
+ */
+ /* while (ost_delay_ms(200) != OST_NO_ERROR); */
+
+ sd_pdma_handler();
+
+ /* *IMR0_REG = 0x08; / Clark - RX buffer half full intr enable */
+
+ return;
+
+}
+
+int sd_free_pdma(void)
+{
+ pSd_PDma_Reg->DMA_DESPR = 0;
+ pSd_PDma_Reg->DMA_GCR = 0;
+ /*SDPRINTK("sd_free_pdma okay!\n");*/
+ return 0;
+}
+
+int sdmmcSwitch(void)
+{
+ unsigned char *SCR ;
+ unsigned char tmp ;
+ unsigned long *ahb_mem_data_in = (unsigned long *)malloc(64);
+ struct _SD_PDMA_DESC_L ReadDesc;
+ memset(ahb_mem_data_in, 0x0, 64);
+ /*bzero(ahb_mem_data_in, 64);*/
+
+ SDDevInfo->HighSpeedSupport = SD_FALSE;
+ SDDevInfo->MMCMaxClockRate = SD_Clk_25MHz;
+
+ pSd_Reg->blklen = 0x003F;
+ pSd_Reg->blkcnt = 0x00;
+ pSd_Reg->ctlr |= 0x08 ;
+
+
+ /* set normal speed bus mode */
+ pSd_Reg->extctl &= 0x7F ;
+
+ pSd_Reg->str0 |= 0xFF;
+ pSd_Reg->str1 |= 0xFF;
+
+ /* Config Read DMA */
+ SD_Init_PDMA();
+ sd_init_long_desc(
+ (unsigned long *)(&ReadDesc),
+ 64,
+ ahb_mem_data_in,
+ (unsigned long *)(&ReadDesc + sizeof(struct _SD_PDMA_DESC_L)),
+ 1
+ );
+ sd_config_pdma((unsigned long *)(&ReadDesc), SD_PDMA_READ);
+
+ /* (1)SD_SWITCH:Check function
+ * check Card support High speed mode
+ */
+ if (sd_command(0x6, 2, 0x00FFFF01, R1) != 0) {
+ SDPRINTK("\nErr : send switch cmd! \n");
+ return -1;
+ }
+
+ sd_pdma_handler();
+
+ SCR = (unsigned char *)(ahb_mem_data_in);
+ tmp = *(SCR+16) ;
+ if ((tmp & 0x0F) == 0x01) {
+ SDDevInfo->HighSpeedSupport = SD_TRUE;
+ SDDevInfo->MMCMaxClockRate = SD_Clk_44MHz;
+ }
+
+ /* while (ost_delay_ms(100) != OST_NO_ERROR); */
+
+ if (SDDevInfo->HighSpeedSupport == SD_TRUE) {
+ pSd_Reg->ctlr |= 0x08 ;
+
+ pSd_Reg->str0 |= 0xFF;
+ pSd_Reg->str1 |= 0xFF;
+
+ sd_init_long_desc(
+ (unsigned long *)(&ReadDesc),
+ 64,
+ ahb_mem_data_in,
+ (unsigned long *)(&ReadDesc + sizeof(struct _SD_PDMA_DESC_L)),
+ 1
+ );
+ sd_config_pdma((unsigned long *)(&ReadDesc), SD_PDMA_READ);
+
+ /* (1)SD_SWITCH:SET function
+ * switch card to High speend mode
+ */
+ if (sd_command(0x6, 2, 0x80FFFF01, R1) != 0) {
+ SDPRINTK("\nErr : send switch cmd! \n");
+ return -1;
+ }
+
+ sd_pdma_handler();
+
+ /* free dma */
+ sd_free_pdma();
+
+ SCR = (unsigned char *)(ahb_mem_data_in) ;
+ tmp = *(SCR+16) ;
+
+ if ((tmp & 0x0F) == 0x0F) {
+ SDDevInfo->HighSpeedSupport = SD_FALSE;
+ SDDevInfo->MMCMaxClockRate = SD_Clk_25MHz;
+ SDPRINTK("SD Card NormSpeed!\n") ;
+ return 0 ;
+ } else{
+ SDPRINTK("SD Card High Speed!\n") ;
+ }
+
+ }
+
+ return 0 ;
+}
+
+int sd_send_scr(void)
+{
+
+ unsigned long sd_status;
+ unsigned char rb_data ;
+
+ sd_status = sd_command(SD_SEND_SCR , 2, 0, R1);
+ if (sd_status != 0)
+ return -1;
+
+ while ((pSd_Reg->str0 & BLK_DONE) != BLK_DONE) {
+ if (pSd_Reg->str1 & DATA_TIMEOUT) {
+ rb_data = pSd_Reg->str1 ;
+ rb_data = pSd_Reg->str1 ;
+ rb_data = pSd_Reg->str1 ;
+ return -1 ;
+ }
+ }
+
+ rb_data = pSd_Reg->str0 ;
+ rb_data = pSd_Reg->str0 ;
+ rb_data = pSd_Reg->str0 ;
+
+ return 0 ;
+}
+
+void card_nop(void)
+{
+ int i = 2000 ;
+ do {
+ i--;
+ } while (i != 0);
+}
+
+/*------------------------------------------------------
+*send SD command (non-data related command) to SD card
+*
+*arg depends on command type
+*
+*-----------------------------------------------------
+*/
+int sd_command(
+ unsigned char command,
+ unsigned char cmdtype,
+ unsigned int arg,
+ unsigned char rsptype
+ )
+{
+
+ unsigned char rb_data ;
+
+
+ /* set command*/
+ pSd_Reg->cmdi = command ;
+ /* set command argument*/
+ pSd_Reg->cmdarg0 = (BYTE)arg;
+ pSd_Reg->cmdarg1 = (BYTE)(arg >> 8);/*move 8 bits*/
+ pSd_Reg->cmdarg2 = (BYTE)(arg >> 16);/*move 16 bits*/
+ pSd_Reg->cmdarg3 = (BYTE)(arg >> 24);/*move 24 bits*/
+ pSd_Reg->respt = rsptype;
+
+ /*clear all status registers*/
+ pSd_Reg->str0 &= 0xff;
+ pSd_Reg->str1 &= 0xff;
+ pSd_Reg->str2 &= 0xff;
+ pSd_Reg->str3 &= 0xff;
+
+ /*Choose SD mode*/
+ if (chip_id == 0x3426)
+ pSd_Reg->busm &= 0xEF;
+ else
+ pSd_Reg->busm |= 0x10;
+
+ pSd_Reg->ctlr &= 0x0F;
+ pSd_Reg->ctlr |= (cmdtype << 4);
+
+
+ /*send out the command*/
+ pSd_Reg->ctlr |= CMD_START;
+ rb_data = pSd_Reg->ctlr ;
+
+ /*wait for Ctrl[busy] clear*/
+ while ((pSd_Reg->ctlr & 0x1) != 0)
+ ;
+ /*wait for command completion, STS1[cmd-rsp-done]*/
+ while ((pSd_Reg->str1 & 0x4) != 0x4) {
+ if ((pSd_Reg->str1 & 0x2) == 0x2) {
+ rb_data = pSd_Reg->str1;
+ rb_data = pSd_Reg->str1;
+ rb_data = pSd_Reg->ctlr;
+ break;
+ }
+ }
+
+ /*SD status : command-response time-out*/
+ if ((pSd_Reg->str1 & 0x4) == 0x4) {
+ rb_data = pSd_Reg->str1;
+ rb_data = pSd_Reg->str1;
+ rb_data = pSd_Reg->ctlr;
+ return -1;
+ }
+
+ return 0;
+}
+
+int sd_app_command(
+ unsigned char command,
+ unsigned char cmdtype,
+ unsigned int arg,
+ unsigned char rsptype
+ )
+{
+ unsigned long sd_status;
+
+ if (command == SD_SEND_SCR) {
+ /*change blk length to 8 (SCR register is 8byte)*/
+ pSd_Reg->blklen = 0x7;
+ pSd_Reg->blkcnt = 0x00;
+ }
+
+ sd_status = sd_command(APP_CMD, 0, SDDevInfo->RCA, R1) ;
+
+ /*while( ost_delay_ms(200) != OST_NO_ERROR );*/
+ if (sd_status != 0) /*not successfully on CMD55*/
+ return -1;
+ /*while( ost_delay_ms(1000) != OST_NO_ERROR );*/
+
+ if (command == SD_SEND_SCR) {
+ sd_status = sd_send_scr();
+
+ if (sd_status != 0)
+ return -1;
+ } else {
+ sd_status = sd_command(command, cmdtype, arg, rsptype) ;
+
+ if(sd_status != 0)
+ return -1;
+ }
+
+ return 0;
+}
+
+int sd_alloc_desc_pool(unsigned long *DescAddr)
+{
+ /*bzero(DescAddr, 0x1000);*/
+ return 0;
+}
+
+int sd_init_short_desc(unsigned long *DescAddr, unsigned int ReqCount, unsigned long *BufferAddr)
+{
+ struct _SD_PDMA_DESC_S *CurDes_S;
+ CurDes_S = (struct _SD_PDMA_DESC_S *) DescAddr;
+ CurDes_S->ReqCount = ReqCount;
+ CurDes_S->i = 0;
+ CurDes_S->format = 0;
+ CurDes_S->DataBufferAddr = BufferAddr;
+ return 0;
+}
+
+int sd_init_short_desc_with_end(unsigned long *DescAddr, unsigned int ReqCount,
+ unsigned long *BufferAddr, int end)
+{
+ struct _SD_PDMA_DESC_S *CurDes_S = (struct _SD_PDMA_DESC_S *) DescAddr;
+ sd_init_short_desc(DescAddr,ReqCount,BufferAddr);
+ CurDes_S->end = end;
+ return 0;
+
+}
+
+#define MAX_LONG_DES_LEN ((1<<16) - 32) /*2^15*/
+
+
+void sd_config_desc(unsigned long *DescAddr, unsigned long *BufferAddr, int Blk_Cnt)
+{
+ struct _SD_PDMA_DESC_S *CurDes_S = (struct _SD_PDMA_DESC_S *)DescAddr;
+
+ CurDes_S->ReqCount = 512*Blk_Cnt;
+ CurDes_S->i = 1;
+ CurDes_S->format = 0;
+ CurDes_S->end = 1;
+ CurDes_S->DataBufferAddr = BufferAddr;
+
+}
+
+
+void sd_dump_memory(int where, int how_many)
+{
+ unsigned long *ahb_mem_data_in = (unsigned long *)(0x4600000) ;
+ unsigned long * CurValue = NULL;
+ int Blk_Cnt = how_many;
+ int loop = 0;
+ for (CurValue=ahb_mem_data_in + (where*512/4);
+ loop <Blk_Cnt*512/4;
+ loop++, CurValue++)
+ {
+ if (loop % 8 == 0)
+ SDPRINTK("\n0x%8x: 0x%8lx", (where*512+loop*4), *CurValue);
+ else
+ SDPRINTK(" 0x%8lx", *CurValue);
+ }
+}
+int sd_config_pdma(unsigned long *DescAddr, char dir)
+{
+ pSd_PDma_Reg->DMA_IER = SD_PDMA_IER_INT_EN;
+ pSd_PDma_Reg->DMA_DESPR = DescAddr;
+ if (dir == SD_PDMA_WRITE)
+ pSd_PDma_Reg->DMA_CCR &= SD_PDMA_CCR_IF_to_peripheral;
+ else
+ pSd_PDma_Reg->DMA_CCR |= SD_PDMA_CCR_peripheral_to_IF;
+ pSd_PDma_Reg->DMA_CCR |= SD_PDMA_CCR_RUN;
+ return 0;
+}
+
+int SD_Init(void)
+{
+ struct _SD_PDMA_DESC_L ReadDesc;
+ unsigned long *ahb_mem_data_in = (unsigned long *)malloc(8);
+ unsigned char *mmc_ext_csd = (unsigned char *)malloc(512);
+ memset(ahb_mem_data_in, 0x0, 8);
+ memset(mmc_ext_csd, 0x0, 512);
+ unsigned char csd[16];
+ unsigned int i;
+ unsigned char tmp, powerupOK, FourBitSupport = SD_FALSE;
+ unsigned int pwr_range0, pwr_range1, pwr_range2, pwr_range3, temp;
+ unsigned char Read_Blk_Len, C_Size_Multi;
+ unsigned short C_Size, blkLength;
+
+ unsigned long Card_Capacity, retryCount, sdstatus;
+
+ unsigned char scr[8], card_status[5], card_status_ready[5];
+ unsigned int RCA_t1, RCA_t2;
+
+ SDDevInfo->RCAHi = 0x0;
+ SDDevInfo->RCALo = 0x0;
+ SDDevInfo->RCA = 0;
+ udelay(1000);
+
+ /* get Strapping option status register */
+ SDDevInfo->strapping &= 0xE;
+ /* if strapping is emmc+sf, SD1 need boot software reset. */
+ if (SDDevInfo->CtrlID == 1 && SDDevInfo->strapping == 0x2) {
+ pSd_Reg->Reserved2[0] &= ~0x1;
+ pSd_Reg->busm &= ~0x10;
+ pSd_Reg->busm |= 0x10;
+ }
+
+ /* (1)send CMD0 to set all sd cards into Idle state */
+ sdstatus = sd_command(GO_IDLE_STATE, 0, 0, R0);
+ if (sdstatus != 0)
+ goto err;
+
+
+ /* (2)check card type and its voltage range */
+ powerupOK = SD_FALSE;
+ retryCount = 0;
+ SDDevInfo->SDVersion = SD1_1;
+
+ sdstatus = sd_command(SEND_IF_COND, 0, 0x000001AA, R1);
+ retryCount = 0;
+ while ((sdstatus != 0) && (retryCount < 5)) { /* retry 5 times */
+ sdstatus = sd_command(SEND_IF_COND, 0, 0x000001AA, R1);
+ retryCount++;
+ }
+
+ if (sdstatus == 0) {
+ SDDevInfo->MMC_Card = SD_FALSE;
+ SDDevInfo->SD_Card = SD_TRUE;
+
+ tmp = pSd_Reg->resr[0]; /* 1st byte is cmd index, no use */
+ pwr_range0 = pSd_Reg->resr[1]; /* 2st byte is resvert argument, no use */
+ pwr_range1 = pSd_Reg->resr[2]; /* 3st byte is resvert argument, no use */
+ pwr_range2 = pSd_Reg->resr[3]; /* 4st byte is VHS */
+ pwr_range3 = pSd_Reg->resr[4]; /* 5st byte is Echo check pattern */
+
+ if ((pwr_range2 == 0x01) && (pwr_range3 == 0xAA)) { /* operation condition accepted by card */
+ SDDevInfo->SDVersion = SD2_0;
+ SDPRINTK("\nSD2_0 : SDHC card!\n") ;
+ } else{
+ printf("0x%x, 0x%x, 0x%x, 0x%x\n", pwr_range0, pwr_range1, pwr_range2, pwr_range3);
+ SDPRINTK("\nSD2_0 Err : power fail !\n") ;
+ goto err;
+ }
+ } else {
+ /* 2006/10/13 janshiue SEND_IF_COND(CMD8) retry 5 times no response
+ * it means SD card below ver 1.1 or MMC card
+ * F/W resend RESET(CMD0) to restart initial procedure.
+ */
+ SDDevInfo->SDVersion = SD1_1;
+ sdstatus = sd_command(GO_IDLE_STATE, 0, 0, R0);
+
+ if (sdstatus != 0) {
+ SDPRINTK("\nSD1_1 Err : idle fail !\n");
+ goto err;
+ }
+ }
+
+ /* for 1.0 and 1.1 */
+ if (SDDevInfo->SDVersion != SD2_0) {
+ /* ACMD41 to get card's require voltage range */
+ sdstatus = sd_app_command(SD_APP_OP_COND, 0, 0, R3);
+ retryCount = 0;
+ /* retry ACMD41 */
+ while ((sdstatus != 0) && (retryCount < 20)) {
+ sdstatus = sd_app_command(SD_APP_OP_COND, 0, 0, R3);
+ retryCount++;
+ card_nop();
+ card_nop();
+ card_nop();
+ }
+
+ if (sdstatus == 0) {
+ SDDevInfo->MMC_Card = SD_FALSE;
+ SDDevInfo->SD_Card = SD_TRUE;
+ SDPRINTK("\nInit : SD Card !\n");
+ } else {
+ SDDevInfo->MMCMaxClockRate = SD_Clk_15MHz;
+ SDDevInfo->MMC_Card = SD_TRUE;
+ SDDevInfo->SD_Card = SD_FALSE;
+ SDPRINTK("\nInit : MMC Card !\n");
+ }
+
+ }
+
+
+ /* (i)check MMC card or not */
+ if (SDDevInfo->SD_Card == SD_FALSE) {
+ sdstatus = sd_command(GO_IDLE_STATE, 0, 0, R0);
+ if (sdstatus != 0) {
+ SDPRINTK("\nMMC Err : idle fail 1!\n");
+ goto err;
+ }
+ /* CMD1 to get card's require voltage range */
+ sdstatus = sd_command(SEND_OP_COND, 0x0, 0x40fc0000, R3);
+ retryCount = 0;
+ /* retry CMD1 */
+ while ((sdstatus != 0) && (retryCount < 10)) {
+ sdstatus = sd_command(SEND_OP_COND, 0x0, 0x40fc0000, R3);
+ retryCount++;
+ }
+ if (sdstatus == 0) {
+ SDDevInfo->MMC_Card = SD_TRUE;
+ SDDevInfo->SD_Card = SD_FALSE;
+ } else {
+ SDDevInfo->MMC_Card = SD_FALSE;
+ SDDevInfo->SD_Card = SD_FALSE;
+ }
+ }
+
+ /* no response to SD_APP_OP_COND and SEND_OP_COND */
+ /* card type can't be judged */
+ if ((SDDevInfo->MMC_Card == SD_FALSE) && (SDDevInfo->SD_Card == SD_FALSE)) {
+ SDPRINTK("\nErr : unknown type !\n");
+ goto err;
+ }
+
+ if (SDDevInfo->SDVersion == SD2_0)
+ sdstatus = sd_app_command(SD_APP_OP_COND, 0, 0x40ff8000, R3); /* 2.7~3.6 v */
+
+
+
+ /* get the retun OCR content */
+ tmp = pSd_Reg->resr[0]; /* 1st byte is cmd index, no use */
+ pwr_range0 = pSd_Reg->resr[1]; /* OCR[31:24] */
+ pwr_range1 = pSd_Reg->resr[2]; /* OCR[23:16] */
+ pwr_range2 = pSd_Reg->resr[3]; /* OCR[15:8] */
+ pwr_range3 = pSd_Reg->resr[4]; /* OCR[7:0] */
+
+ if (SDDevInfo->SDVersion == SD2_0) {
+ /* to support SD2.0 High capacity card */
+ pwr_range0 |= HostCapacitySupport;
+ }
+
+ /* (3)power the card and wait for card power phase complete */
+
+ /* retry CMD1 or ACMD41 till powerup ok */
+ retryCount = 0;
+ powerupOK = SD_FALSE;
+ /* add timeout to SD power up retry check (ACMD41 & CMD1). It is for plugin-plugout issue. */
+ if (chip_id == 0x3481 && SDDevInfo->CtrlID == 1) {
+ udelay(1000); //for ASUS MID case.
+ } else {
+ udelay(64000);
+ }
+ /*add timeout to SD power up retry check (ACMD41 & CMD1). It is for plugin-plugout issue.*/
+
+ /* If this card is MMCcard, resend CMD0 to reset MMC card register,
+ * MMC card enter Idel mode. If SD card don't enter Idle mode. added by Eason 2012/6/22 */
+ if (SDDevInfo->MMC_Card == SD_TRUE) {
+ sdstatus = sd_command(GO_IDLE_STATE, 0, 0, R0);
+ if (sdstatus != 0) {
+ SDPRINTK("\nMMC Err : idle fail 2!\n");
+ goto err;
+ }
+ }
+
+ while (powerupOK == SD_FALSE) {
+ if (SDDevInfo->MMC_Card == SD_TRUE)
+ sdstatus = sd_command(SEND_OP_COND, 0, 0x40fc0000, R3);
+ else{
+ temp = (pwr_range0 << 24)|(pwr_range1 << 16)|(pwr_range2 << 8)|(pwr_range3) ;
+ sdstatus = sd_app_command(SD_APP_OP_COND, 0, temp, R3);
+ }
+ /* chek OCR[31] bit set or not */
+ tmp = pSd_Reg->resr[0]; /* 1st byte is cmd index */
+ tmp = pSd_Reg->resr[1]; /* OCR[31:24] */
+ /* Save OCR Register */
+ SDDevInfo->ocr[0] = pSd_Reg->resr[1];
+ SDDevInfo->ocr[1] = pSd_Reg->resr[2];
+ SDDevInfo->ocr[2] = pSd_Reg->resr[3];
+ SDDevInfo->ocr[3] = pSd_Reg->resr[4];
+
+ if (tmp & 0x80) {
+ /* check CardCapacityStatus MMCA 4.2 must check this*/
+ if (tmp & 0x40)
+ SDDevInfo->CardCapacityStatus = HighCapacity;
+ else
+ SDDevInfo->CardCapacityStatus = StandardCapacity;
+
+
+ powerupOK = SD_TRUE;
+ } else{
+ for (i = 0; i < 20; i++) {
+ tmp = pSd_Reg->resr[i];
+ card_nop();
+ card_nop();
+ card_nop();
+ }
+ }
+
+
+ retryCount++;
+ udelay(64000);
+
+ if (retryCount > 36) {
+ SDPRINTK("\nSD Err : power fail 1 !\n");
+ goto err;
+ }
+
+ }
+
+ if (sdstatus != 0) {
+ SDPRINTK("\nSD Err : power fail 2 !\n");
+ goto err;
+ }
+ SDPRINTK("\nInit : Read OCR OK !\n");
+ /* (4)read card CID, RCA */
+ sdstatus = sd_command(ALL_SEND_CID, 0, 0x0, R2);
+ if (sdstatus != 0) {
+ SDPRINTK("\n Err :send CID fail !\n");
+ goto err;
+ }
+ /* Save CID Register*/
+ SDDevInfo->cid[0] = pSd_Reg->resr[1];
+ SDDevInfo->cid[1] = pSd_Reg->resr[2];
+ SDDevInfo->cid[2] = pSd_Reg->resr[3];
+ SDDevInfo->cid[3] = pSd_Reg->resr[4];
+ SDDevInfo->cid[4] = pSd_Reg->resr[5];
+ SDDevInfo->cid[5] = pSd_Reg->resr[6];
+ SDDevInfo->cid[6] = pSd_Reg->resr[7];
+ SDDevInfo->cid[7] = pSd_Reg->resr[8];
+ SDDevInfo->cid[8] = pSd_Reg->resr[9];
+ SDDevInfo->cid[9] = pSd_Reg->resr[10];
+ SDDevInfo->cid[10] = pSd_Reg->resr[11];
+ SDDevInfo->cid[11] = pSd_Reg->resr[12];
+ SDDevInfo->cid[12] = pSd_Reg->resr[13];
+ SDDevInfo->cid[13] = pSd_Reg->resr[14];
+ SDDevInfo->cid[14] = pSd_Reg->resr[15];
+
+
+ /**************************************************
+ *if SD Card, get RCA from card
+ *if MMC_Card, controller need to assign RCA (0xffc1) for card
+ **************************************************/
+ if (SDDevInfo->SD_Card == SD_TRUE) {
+ sdstatus = sd_command(SEND_RELATIVE_ADDR, 0, 0x0, R6);
+ if (sdstatus != 0) {
+ SDPRINTK("\nSD Err :send RCA fail !\n");
+ goto err;
+ }
+
+ tmp = pSd_Reg->resr[1];
+ SDDevInfo->RCAHi = tmp;
+ tmp = pSd_Reg->resr[2];
+ SDDevInfo->RCALo = tmp;
+ } else {
+ /* PKtest 9/5 adjust the timeOut register value */
+ sdstatus = sd_command(SET_RELATIVE_ADDR, 0, 0xffc10000, R1);
+ if (sdstatus != 0) {
+ SDPRINTK("\nMMC Err :send RCA fail !\n");
+ goto err;
+ }
+
+ SDDevInfo->RCAHi = 0xff;
+ SDDevInfo->RCALo = 0xc1;
+ }
+
+ /* (5)read card CSD to know card size, capability */
+
+ RCA_t1 = 0x0;
+ RCA_t2 = 0x0;
+ RCA_t1 |= SDDevInfo->RCAHi;
+ RCA_t2 |= SDDevInfo->RCALo;
+ SDDevInfo->RCA = (RCA_t1 << 24) | (RCA_t2 << 16);
+
+ sdstatus = sd_command(SEND_CSD, 0, SDDevInfo->RCA, R2);
+ if (sdstatus != 0) {
+ SDPRINTK("\nErr :send CSD fail !\n");
+ goto err;
+ }
+
+ /* Save CSD Register*/
+ for (i = 0; i < 15; i++) {
+ csd[i]= pSd_Reg->resr[i+1];
+ SDDevInfo->csd[i] = pSd_Reg->resr[i+1];
+ }
+
+ Read_Blk_Len = csd[5] & 0x0f;
+
+ if ((SDDevInfo->SD_Card == SD_TRUE) && (csd[0] == 0x40)) {
+ /* CSD 2.0 */
+ Card_Capacity = ((((csd[7] & 0x3F) << 8)|csd[8]) << 8) | csd[9];
+ Card_Capacity++;
+
+ /* SD2.0 SPEC : memory capacity = (C_SIZE + 1) * 512 K Byte
+ * Card_Capacity is base on 512 bytes,
+ * thus return Card_Capacity *((512 * 1024)/512)
+ */
+ Card_Capacity = Card_Capacity * 1024;
+ SDDevInfo->SDCard_Size = Card_Capacity;
+ }
+
+ if ((SDDevInfo->MMC_Card == SD_TRUE) || (csd[0] == 0x00)) {
+ /* MMC card or SD 1.1 below */
+ C_Size = (((csd[6] & 0x03) << 8) | csd[7]) << 2 | (csd[8] & 0xC0) >> 6;
+ C_Size_Multi = (csd[9] & 0x3) << 1 | (csd[10] & 0x80) >> 7;
+ blkLength = ((unsigned short)1) << Read_Blk_Len;
+ Card_Capacity = ((((unsigned long)(C_Size + 1)) << (C_Size_Multi + 2)) * blkLength) / 512;
+ SDDevInfo->SDCard_Size = Card_Capacity;
+ }
+
+ /* (6)select card */
+ sdstatus = sd_command(SELECT_DESELECT_CARD, 0, SDDevInfo->RCA, R1);
+ if (sdstatus != 0) {
+ SDPRINTK("\nErr :deselect card fail !\n");
+ goto err;
+ }
+
+ sdstatus = sd_command(SEND_STATUS, 0, SDDevInfo->RCA, R1);
+ if (sdstatus != 0)
+ goto err;
+
+ for (i = 0; i <= 4; i++) {
+ card_status[i] = 0 ;
+ card_status_ready[i] = 0;
+ }
+ card_status_ready[0] = 0x0;
+ card_status_ready[1] = 0x0;
+ card_status_ready[2] = 0x0;
+ card_status_ready[3] = 0x09;
+ card_status_ready[4] = 0x0;
+
+ for (i = 1; i <= 4; i++)
+ card_status[i] = pSd_Reg->resr[i];
+
+ for (i = 1; i <= 4; i++) {
+ if (card_status[i] != card_status_ready[i]) {
+ if (card_status[4] == 0x40) {
+ /* back operation support */
+ printf("\n !! Warning !! pSd_Reg->Rsp[4]=%X ! \n", pSd_Reg->resr[4]);
+ } else {
+ SDPRINTK("\n pSd_Reg->Rsp[1]=%X ! \n", pSd_Reg->resr[1]);
+ SDPRINTK("\n pSd_Reg->Rsp[2]=%X ! \n", pSd_Reg->resr[2]);
+ SDPRINTK("\n pSd_Reg->Rsp[3]=%X ! \n", pSd_Reg->resr[3]);
+ SDPRINTK("\n pSd_Reg->Rsp[4]=%X ! \n", pSd_Reg->resr[4]);
+
+ SDPRINTK("\n Card Status Error ! \n");
+ goto err;
+ }
+ }
+ }
+ SDPRINTK("\nInit : card selected !\n");
+ /* (7)read card SCR to know card support 4bit mode or not */
+ if (SDDevInfo->SD_Card == SD_TRUE) {
+ SDPRINTK("\nInit : SD card set mode !\n");
+ FourBitSupport = SD_FALSE;
+
+ SD_Init_PDMA();
+ sd_init_long_desc(
+ (unsigned long *)&ReadDesc,
+ 8,
+ ahb_mem_data_in,
+ (unsigned long *)(&ReadDesc + sizeof(struct _SD_PDMA_DESC_L)),
+ 1
+ );
+ sd_config_pdma((unsigned long *)(&ReadDesc), SD_PDMA_READ);
+
+ sdstatus = sd_app_command(SD_SEND_SCR, 2, 0x0, R1);
+ if (sdstatus != 0)
+ goto err;
+
+ sdstatus = sd_pdma_handler();
+
+ if (sdstatus != 0)
+ goto err;
+
+ /* Save SCR Register*/
+ for (i = 0; i < 8; i++) {
+ scr[i] = *((uchar *)ahb_mem_data_in + i);
+ SDDevInfo->scr[i] = *((uchar *)ahb_mem_data_in + i);
+ }
+ /* free dma */
+ sd_free_pdma();
+
+
+ tmp = scr[0];
+ if ((tmp & 0x0f) != 0x00)
+ SDDevInfo->HighSpeedSupport = SD_TRUE;
+
+ tmp = scr[1];
+ if ((tmp & 0x0f) == 0x05)
+ FourBitSupport = SD_TRUE;
+ }
+
+ /* (8)set blklength and bus width */
+
+ /* set block length to be 512bytes */
+ blkLength = 0;
+ blkLength = ((unsigned short)1) << Read_Blk_Len;
+ if (blkLength != 512) {
+ SDPRINTK("\nset blocklen fun. !\n");
+ sdstatus = sd_command(SET_BLOCKLEN, 0, 0x200, R1);
+ if (sdstatus != 0) {
+ SDPRINTK("\nErr :set blocklen fail !\n");
+ goto err;
+ }
+ }
+
+ pSd_Reg->blklen |= 0x1FF;
+
+ //if SD card support 4bit bus set to 4bit mode transfer
+ if (SDDevInfo->SD_Card == SD_TRUE) {
+ SDDevInfo->MMCMaxClockRate = SD_Clk_25MHz;
+ if (FourBitSupport == SD_TRUE) {
+ if (Bitmode == 0) {
+ sdstatus = sd_app_command(SET_BUS_WIDTH, 0, 0x2, R1);
+ if (sdstatus != 0)
+ goto err;
+
+ /* set BusMode register to 4bit mode */
+ pSd_Reg->busm |= FOURBIT_MODE;
+ SDPRINTK("\nSD:Four Bits Mode!\n");
+ } else {
+ pSd_Reg->busm &= ONEBIT_MODE;
+ SDPRINTK("\nSD:One Bit Mode!\n");
+ }
+ }
+ /* Check SD Card High Speend Support */
+ if (SDDevInfo->HighSpeedSupport == SD_TRUE) {
+ /* SDPRINTK("\nsdmmcSwitch func.\n"); */
+
+ SDDevInfo->MMCMaxClockRate = SD_Clk_44MHz;
+ if ( sdmmcSwitch() != 0 ) {
+ SDPRINTK("\nErr: sdmmcSwitch func.\n");
+ pSd_Reg->blklen = 0x01FF;
+ goto err;
+ }
+
+ pSd_Reg->blklen = 0x01FF;
+ }
+ }
+
+
+ if (SDDevInfo->MMC_Card == SD_TRUE) {
+ SDPRINTK("\nInit :MMC card set mode !\n");
+ /* save the MMCVersion */
+ SDDevInfo->MMCVersion = (csd[0] >> 2) & 0x0f;
+
+ /* check spec version */
+ if (SDDevInfo->MMCVersion < MMC4_01) {
+ pSd_Reg->busm &= ONEBIT_MODE ;
+ SDPRINTK("\nMMC1_0 :One Bit Mode!\n");
+
+ }
+ if (SDDevInfo->MMCVersion >= MMC4_01) {
+
+ sdmmcSendExCSD((unsigned long *)mmc_ext_csd);
+ /* Save MMC Extended CSD Register */
+ for (i = 0; i < 512; i += 4) {
+ SDDevInfo->ext_csd[i] = *(mmc_ext_csd + i);
+ SDDevInfo->ext_csd[i + 1] = *(mmc_ext_csd + i + 1);
+ SDDevInfo->ext_csd[i + 2] = *(mmc_ext_csd + i + 2);
+ SDDevInfo->ext_csd[i + 3] = *(mmc_ext_csd + i + 3);
+ /*SDPRINTK("CMD %x SCR[%x] =%x \n", pSd_Reg->Cmd, i, *(mmc_ext_csd + i));*/
+ }
+ Card_Capacity = SDDevInfo->ext_csd[212] << 0 |
+ SDDevInfo->ext_csd[213] << 8 |
+ SDDevInfo->ext_csd[214] << 16 |
+ SDDevInfo->ext_csd[215] << 24;
+ if (Card_Capacity)
+ SDDevInfo->SDCard_Size = Card_Capacity;
+
+ tmp = *(mmc_ext_csd + 196);
+ if (tmp & BIT1) { /* high speed and max clock rate at 52Mhz*/
+ /*high speed mode 52Mhz*/
+ SDDevInfo->MMCMaxClockRate = SD_Clk_44MHz;
+ SDDevInfo->HighSpeedSupport = SD_TRUE;
+ SDPRINTK("\nMMC : CLK 48!\n");
+ } else if (tmp == 0x01) {/* high speed and max clock rate at 26Mhz*/
+ SDDevInfo->MMCMaxClockRate = SD_Clk_25MHz;
+ SDDevInfo->HighSpeedSupport = SD_FALSE;
+ SDPRINTK("\nMMC : CLK 24!\n");
+ } else {
+ SDDevInfo->MMCMaxClockRate = SD_Clk_15MHz;/*Clk_15;*/
+ SDDevInfo->HighSpeedSupport = SD_FALSE;
+ SDPRINTK("\nMMC : CLK 15!\n");
+ }
+
+ if (SDDevInfo->HighSpeedSupport == SD_TRUE) {
+ SDPRINTK("\nInit :MMC card High Speed Support !\n");
+ /* Card support High Speed interface */
+ sdstatus = sd_command(SWITCH_MMC, 0, 0x03B90100, R1);
+
+ /*add delay to patch eMMC for MMCA 4.3*/
+ udelay(10000);
+
+ sdstatus = sd_command(SEND_STATUS, 0, SDDevInfo->RCA, R1);
+ for (i = 1; i <= 4; i++)
+ card_status[i]=pSd_Reg->resr[i];
+
+ if ((card_status[3] & 0x80) == 0x00) {
+ /* switch command ok */
+ /* check SWITCH to High speed timming SUCCESS */
+
+ sdmmcSendExCSD((unsigned long *)mmc_ext_csd);
+ tmp = *(mmc_ext_csd + 185);
+
+ if (tmp == 0x01) {/* switch to high speed timming*/
+ SDDevInfo->HighSpeedSupport = SD_TRUE;
+ SDPRINTK("\nMMC : High speed is true !\n");
+ } else { /* switch failer*/
+ SDDevInfo->HighSpeedSupport = SD_FALSE;
+ SDPRINTK("\nMMC : High speed is false !\n");
+ }
+ }
+ }
+
+ /* Use SWITCH command to set MMC 4.0 card to 4bit mode
+ * access = 0x3 write byte
+ * index = 183 point to BUS_WIDTH field
+ * value = 1 indicate 4 bit bus, 2 indicate 8 bit bus
+ */
+ if (Bitmode == 0)
+ Bitmode = 4;
+ if (Bitmode == 0) {
+ sdstatus = sd_command(SWITCH_MMC, 0, 0x03B70200, R1);
+
+ sdstatus = sd_command(SEND_STATUS, 0, SDDevInfo->RCA, R1);
+ for (i = 1; i <= 4; i++)
+ card_status[i]=pSd_Reg->resr[i];
+
+ if ((card_status[3] & 0x80) == 0x00) { /* switch command ok */
+ /* set BusMode register to 8bit mode */
+ /*
+ //SDReg.BusMode |= FOURBIT_MODE;
+ //SDDevInfo->MMC40 = TRUE;
+ */
+ pSd_Reg->extctl |= EIGHTBIT_MODE;
+ SDDevInfo->MMCVersion = MMC4_01;
+ SDPRINTK("\nMMC4_0 : Eight Bits Mode !\n");
+ } else {
+ /* can't switch to 8bit mode, try 4bit mode */
+
+ /*2006/03/08 marked by janshiue, Since if card don't support
+ * 8 bit mode the card still MMC 4.0 card, it should
+ * perform at 1 or 4 bit mode. if set SDDevInfo->MMCVersion to
+ * MMC3_123. it will also disable the high speed support.
+ */
+ /*//SDDevInfo->MMCVersion = MMC4_01;*/
+
+ sdstatus = sd_command(SWITCH_MMC, 0, 0x03B70100, R1);
+
+ sdstatus = sd_command(SEND_STATUS, 0, SDDevInfo->RCA, R1);
+ for (i = 1; i <= 4; i++)
+ card_status[i]=pSd_Reg->resr[i];
+
+ if ((card_status[3] & 0x80) == 0x00) {
+ /* switch command ok */
+ /* set BusMode register to 4bit mode */
+ pSd_Reg->busm |= FOURBIT_MODE;
+ SDPRINTK("\nMMC4_0:Four Bits Mode!\n");
+ SDDevInfo->MMCVersion = MMC4_01;
+ }
+
+ }
+ }
+ if (Bitmode == 4) {
+ /*switch to 4 bit mode*/
+
+ sdstatus = sd_command(SWITCH_MMC, 0, 0x03B70100, R1);
+
+ sdstatus = sd_command(SEND_STATUS, 0, SDDevInfo->RCA, R1);
+ for (i = 1; i <= 4; i++)
+ card_status[i] = pSd_Reg->resr[i] ;
+
+ if ((card_status[3] & 0x80) == 0x00) {
+ /* switch command ok */
+ /* set BusMode register to 4bit mode */
+ pSd_Reg->busm |= FOURBIT_MODE;
+ SDPRINTK("\nMMC4_0:Four Bits Mode!\n") ;
+ SDDevInfo->MMCVersion = MMC4_01;
+ }
+ }
+ if (Bitmode == 1) {
+ sdstatus = sd_command(SWITCH_MMC, 0, 0x03B70000, R1);
+ sdstatus = sd_command(SEND_STATUS, 0, SDDevInfo->RCA, R1);
+ for (i = 1; i <= 4; i++)
+ card_status[i] = pSd_Reg->resr[i];
+
+ if ((card_status[3] & 0x80) == 0x00) {
+ /* switch command ok */
+ /* set BusMode register to 1bit mode */
+ pSd_Reg->busm &= ONEBIT_MODE ;
+ SDPRINTK("\nMMC4_0 :One Bit Mode!\n");
+ SDDevInfo->MMCVersion = MMC4_01;
+ }
+ }
+
+ }
+ }
+ free(mmc_ext_csd);
+ free(ahb_mem_data_in);
+ return 0;
+err:
+ free(mmc_ext_csd);
+ free(ahb_mem_data_in);
+ return -1;
+}
+
+
+int SD_Initialization(void)
+{
+ unsigned char sdstatus = 0;
+
+ Bitmode = 0; /* eight/four bits mode */
+ /* card type is unknown here */
+ SDDevInfo->MMC_Card = SD_FALSE;
+ SDDevInfo->SD_Card = SD_FALSE;
+ SDDevInfo->SD_IO_Card = SD_FALSE;
+
+ /* get SD/MMC card info */
+ SDDevInfo->InitOK = SD_FALSE;
+ /* SDDevInfo->MMCMaxClockRate = Clk_375; */
+ sdstatus = SD_Init();
+ /* error handle during initialization */
+ if (sdstatus != 0) {
+ printf("\nInitial SD/MMC Card Fail!\n");
+ return -1;
+ } else {
+ SDDevInfo->InitOK = SD_TRUE;
+ printf("\nInitial SD/MMC Card OK!\n");
+ }
+
+ return 0;
+}
+
+
+
+/**********************************************************************************/
+extern int
+fat_register_device(block_dev_desc_t *dev_desc, int part_no);
+
+block_dev_desc_t * mmc_get_dev(int dev)
+{
+ if (dev == 0)
+ return ((block_dev_desc_t *)&mmc0_dev);
+ else if (dev == 1)
+ return ((block_dev_desc_t *)&mmc1_dev);
+ else if (dev == 2)
+ return ((block_dev_desc_t *)&mmc2_dev);
+ return NULL;
+}
+
+/*
+ * FIXME needs to read cid and csd info to determine block size
+ * and other parameters
+ */
+//static uchar mmc_buf[MMC_BLOCK_SIZE];
+//static mmc_csd_t mmc_csd;
+
+
+int
+/****************************************************/
+mmc_block_read_singleblock(uchar *dst, ulong src)
+/****************************************************/
+{
+ unsigned long sd_status;
+ struct _SD_PDMA_DESC_S ReadDesc;
+ /*SDPRINTK("\n Read Single block begin \n");*/
+ long count =1000000;
+ while(1) {
+ sd_status = sd_command(SEND_STATUS, 0, SDDevInfo->RCA, R1);
+ if (sd_status != 0)
+ return -1 ;
+ if (pSd_Reg->resr[3] == 0x09)
+ break;
+ count--;
+ if (count == 0) {
+ SDPRINTK("mmc_block_read_singleblock Time Out!\n");
+ break;
+ }
+
+ }
+
+ pSd_Reg->blkcnt = 0x01;
+
+ pSd_Reg->str0 |= 0xFF;
+ pSd_Reg->str1 |= 0xFF;
+
+ /* Config Read DMA */
+ SD_Init_PDMA();
+ sd_config_desc((unsigned long *)(&ReadDesc), (unsigned long*)dst, 1);
+ sd_config_pdma((unsigned long *)(&ReadDesc), SD_PDMA_READ);
+
+ sd_status = sd_command(READ_SINGLE_BLOCK, 2, src, R1);
+ if (sd_status != 0) {
+ SDPRINTK("\nRead single Block CMD Err !\n");
+ return -1 ;
+ }
+
+ sd_status = sd_pdma_handler();
+ if (sd_status != 0) {
+ pSd_Reg->timeval = 0xefff;
+ /* SDPRINTK("pSd_Reg->Cmd = 0x%x\n", pSd_Reg->Cmd);
+ SDPRINTK("pSd_Reg->STS0 = 0x%x\n", pSd_Reg->ctrl);
+ SDPRINTK("pSd_Reg->DmaTout0 = 0x%x\n", pSd_Reg->DmaTout[0]);
+ SDPRINTK("pSd_Reg->DmaTout1 = 0x%x\n", pSd_Reg->DmaTout[1]);
+ SDPRINTK("pSd_Reg->STS1 = 0x%x\n", pSd_Reg->str1);
+ SDPRINTK("pSd_Reg->BlkCnt[0] = 0x%x\n", pSd_Reg->blkcnt);
+ SDPRINTK("pSd_Reg->Cbcr[0] = 0x%x\n", pSd_Reg->Cbcr[0]);
+ SDPRINTK("pSd_Reg->Cbcr[1] = 0x%x\n", pSd_Reg->Cbcr[1]);
+ SDPRINTK("pSd_Reg->Res3[0] = 0x%x\n", pSd_Reg->Res3[0]);
+ SDPRINTK("pSd_Reg->Res3[1] = 0x%x\n", pSd_Reg->Res3[1]);*/
+ return -1 ;
+
+ }
+
+ /* free dma */
+ sd_free_pdma();
+ /*SDPRINTK("\n Read Single block end \n");*/
+ return 0;
+
+}
+
+int
+/****************************************************/
+mmc_block_read_multiblock(uchar *dst, ulong src, ulong ulBlockCount)
+/****************************************************/
+{
+ unsigned long sd_status;
+ struct _SD_PDMA_DESC_S ReadDesc;
+ long count =1000000;
+ while(1) {
+ sd_status = sd_command(SEND_STATUS, 0, SDDevInfo->RCA, R1);
+ if (sd_status != 0)
+ return -1 ;
+ if (pSd_Reg->resr[3] == 0x09)
+ break;
+ count--;
+ if (count == 0) {
+ SDPRINTK("mmc_block_read_multiblock Time Out!\n");
+ break;
+ }
+
+ }
+
+ /*SDPRINTK("\n Read Multi block begin \n");*/
+ while (ulBlockCount > 127) {
+ pSd_Reg->blkcnt = (unsigned short)(127 & 0xFFFF);
+ pSd_Reg->ctlr |= 0x08; /* response FIFO reset, */
+
+ pSd_Reg->str0 |= 0xFF;
+ pSd_Reg->str1 |= 0xFF;
+
+ /* Config Read DMA */
+ SD_Init_PDMA();
+ sd_config_desc((unsigned long *)(&ReadDesc), (unsigned long*)dst, 127);
+ sd_config_pdma((unsigned long *)(&ReadDesc), SD_PDMA_READ);
+ /* pSd_Reg->extctl |= 0x01; */
+
+ sd_status = sd_command(READ_MULTIPLE_BLOCK, 4, src, R1);
+ if (sd_status != 0) {
+ SDPRINTK("\nRead Multi Block CMD Err !\n");
+ return -1;
+ }
+
+ sd_status = sd_pdma_handler();
+
+ if (sd_status != 0) {
+ pSd_Reg->timeval = 0xefff;
+ /* SDPRINTK("pSd_Reg->Cmd = 0x%x\n", pSd_Reg->Cmd);
+ SDPRINTK("pSd_Reg->STS0 = 0x%x\n", pSd_Reg->ctrl);
+ SDPRINTK("pSd_Reg->DmaTout0 = 0x%x\n", pSd_Reg->DmaTout[0]);
+ SDPRINTK("pSd_Reg->DmaTout1 = 0x%x\n", pSd_Reg->DmaTout[1]);
+ SDPRINTK("pSd_Reg->STS1 = 0x%x\n", pSd_Reg->str1);
+ SDPRINTK("pSd_Reg->BlkCnt[0] = 0x%x\n", pSd_Reg->blkcnt);
+ SDPRINTK("pSd_Reg->Cbcr[0] = 0x%x\n", pSd_Reg->Cbcr[0]);
+ SDPRINTK("pSd_Reg->Cbcr[1] = 0x%x\n", pSd_Reg->Cbcr[1]);
+ SDPRINTK("pSd_Reg->Res3[0] = 0x%x\n", pSd_Reg->Res3[0]);
+ SDPRINTK("pSd_Reg->Res3[1] = 0x%x\n", pSd_Reg->Res3[1]);*/
+ return -1;
+ }
+
+ /* free dma */
+ sd_free_pdma();
+
+ /* send CMD12 : stop command */
+ pSd_Reg->ctlr |= 0x08 ; /* response FIFO reset, */
+ sd_status = sd_command(STOP_TRANSMISSION, 7, src, R1b);
+ if (sd_status != 0)
+ return -1 ;
+ ulBlockCount -= 127;
+
+ if (SDDevInfo->CardCapacityStatus == 0)
+ src += 127*512;
+ else
+ src += 127;
+ dst += 127*512;
+
+ count = 1000000;
+ while(1) {
+ sd_status = sd_command(SEND_STATUS, 0, SDDevInfo->RCA, R1);
+ if (sd_status != 0)
+ return -1 ;
+ if (pSd_Reg->resr[3] == 0x09)
+ break;
+ count--;
+ if (count == 0) {
+ SDPRINTK("mmc_block_write_multiblock Time Out!\n");
+ break;
+ }
+
+ }
+
+ }
+ if (ulBlockCount) {
+ pSd_Reg->blkcnt = (unsigned short)(ulBlockCount & 0xFFFF);
+ pSd_Reg->ctlr |= 0x08; /* response FIFO reset, */
+
+ pSd_Reg->str0 |= 0xFF;
+ pSd_Reg->str1 |= 0xFF;
+
+ /* Config Read DMA */
+ SD_Init_PDMA();
+ sd_config_desc((unsigned long *)(&ReadDesc), (unsigned long*)dst, ulBlockCount);
+ sd_config_pdma((unsigned long *)(&ReadDesc), SD_PDMA_READ);
+ //pSd_Reg->extctl |= 0x01;
+
+ sd_status = sd_command(READ_MULTIPLE_BLOCK, 4, src, R1);
+ if (sd_status != 0) {
+ SDPRINTK("\nRead Multi Block CMD Err !\n");
+ return -1 ;
+ }
+
+ sd_status = sd_pdma_handler();
+ if (sd_status != 0) {
+ pSd_Reg->timeval = 0xefff;
+ /* SDPRINTK("pSd_Reg->Cmd = 0x%x\n", pSd_Reg->Cmd);
+ SDPRINTK("pSd_Reg->STS0 = 0x%x\n", pSd_Reg->ctrl);
+ SDPRINTK("pSd_Reg->DmaTout0 = 0x%x\n", pSd_Reg->DmaTout[0]);
+ SDPRINTK("pSd_Reg->DmaTout1 = 0x%x\n", pSd_Reg->DmaTout[1]);
+ SDPRINTK("pSd_Reg->STS1 = 0x%x\n", pSd_Reg->str1);
+ SDPRINTK("pSd_Reg->BlkCnt[0] = 0x%x\n", pSd_Reg->blkcnt);
+ SDPRINTK("pSd_Reg->Cbcr[0] = 0x%x\n", pSd_Reg->Cbcr[0]);
+ SDPRINTK("pSd_Reg->Cbcr[1] = 0x%x\n", pSd_Reg->Cbcr[1]);
+ SDPRINTK("pSd_Reg->Res3[0] = 0x%x\n", pSd_Reg->Res3[0]);
+ SDPRINTK("pSd_Reg->Res3[1] = 0x%x\n", pSd_Reg->Res3[1]);*/
+ return -1;
+ }
+
+ /* free dma */
+ sd_free_pdma();
+
+ /* send CMD12 : stop command */
+ pSd_Reg->ctlr |= 0x08 ; /* response FIFO reset, */
+ sd_status = sd_command(STOP_TRANSMISSION, 7, src, R1b);
+ if (sd_status != 0)
+ return -1;
+
+ count =1000000;
+ while(1) {
+ sd_status = sd_command(SEND_STATUS, 0, SDDevInfo->RCA, R1);
+ if (sd_status != 0)
+ return -1;
+ if (pSd_Reg->resr[3] == 0x09)
+ break;
+ count--;
+ if (count == 0) {
+ SDPRINTK("mmc_block_write_multiblock Time Out!\n");
+ break;
+ }
+
+ }
+
+ }
+ /*SDPRINTK("\nRead multi Block CMD OK !\n");*/
+ return 0 ;
+}
+
+int
+/****************************************************/
+mmc_block_write_singleblock(uchar *src, ulong ulBlockStart)
+/****************************************************/
+{
+ unsigned long sd_status;
+ struct _SD_PDMA_DESC_S WriteDesc;
+ //SDPRINTK("\n Write Single block begin \n");
+ long count =0x1000000;
+
+ pSd_Reg->ctlr |= 0x08; /* response FIFO reset, */
+ pSd_Reg->str0 |= 0x30;
+
+ while(1) {
+ sd_status = sd_command(SEND_STATUS, 0, SDDevInfo->RCA, R1);
+ if (sd_status != 0)
+ return -1 ;
+ if (pSd_Reg->resr[3] == 0x09)
+ break;
+ count--;
+ if (count == 0) {
+ SDPRINTK("mmc_block_write_singleblock Time Out!\n");
+ break;
+ }
+
+ }
+
+ pSd_Reg->blkcnt = 0x01;
+
+ pSd_Reg->str0 |= 0xFF;
+ pSd_Reg->str1 |= 0xFF;
+ /* Config Read DMA */
+ SD_Init_PDMA();
+ sd_config_desc((unsigned long *)(&WriteDesc), (unsigned long*)src, 1);
+ sd_config_pdma((unsigned long *)(&WriteDesc), SD_PDMA_WRITE);
+
+ sd_status = sd_command(WRITE_SINGLE_BLOCK, 1, ulBlockStart, R1);
+ if (sd_status != 0) {
+ SDPRINTK("\nRead single Block CMD Err !\n");
+ return -1;
+ }
+
+ sd_status = sd_pdma_handler();
+ if (sd_status != 0) {
+ pSd_Reg->timeval = 0xefff;
+ return -1;
+ }
+
+ /* free dma */
+ sd_free_pdma();
+ //SDPRINTK("\n Write Single block end \n");
+
+ count = 0x1000000;
+ while(1) {
+ sd_status = sd_command(SEND_STATUS, 0, SDDevInfo->RCA, R1);
+ if (sd_status != 0)
+ return -1;
+ if (pSd_Reg->resr[3] == 0x09)
+ break;
+ count--;
+ if (count == 0) {
+ SDPRINTK("mmc_block_write_multiblock Time Out!\n");
+ break;
+ }
+
+ }
+ return 0;
+
+}
+
+int
+/****************************************************/
+mmc_block_write_multiblock(uchar *src, ulong ulBlockStart, ulong ulBlockCount)
+/****************************************************/
+{
+ unsigned long sd_status;
+ long count =0x1000000;
+ struct _SD_PDMA_DESC_S WriteDesc;
+ while(1) {
+ sd_status = sd_command(SEND_STATUS, 0, SDDevInfo->RCA, R1);
+ if (sd_status != 0)
+ return -1;
+ if (pSd_Reg->resr[3] == 0x09)
+ break;
+ count--;
+ if (count == 0) {
+ SDPRINTK("mmc_block_write_multiblock Time Out!\n");
+ break;
+ }
+
+ }
+ while(ulBlockCount > 127) {
+ pSd_Reg->blkcnt = (unsigned short)(127 & 0xFFFF);
+ pSd_Reg->ctlr |= 0x08; /* response FIFO reset, */
+ pSd_Reg->str0 |= 0xFF;
+ pSd_Reg->str1 |= 0xFF;
+ /* Config Read DMA */
+ SD_Init_PDMA();
+ sd_config_desc((unsigned long *)(&WriteDesc), (unsigned long*)src, 127);
+ sd_config_pdma((unsigned long *)(&WriteDesc), SD_PDMA_WRITE);
+ /* pSd_Reg->extctl |= 0x01; */
+
+ sd_status = sd_command(WRITE_MULTIPLE_BLOCK, 3, ulBlockStart, R1);
+ if (sd_status != 0) {
+ SDPRINTK("\nWrite Multi Block CMD Err !\n");
+ return -1 ;
+ }
+
+ /*sd_status = vt3400_sd_dma_handler() ;*/
+ sd_status = sd_pdma_handler();
+ if (sd_status != 0) {
+ pSd_Reg->timeval = 0xefff;
+ return -1;
+ }
+
+ /* free dma */
+ sd_free_pdma();
+
+ /* send CMD12 : stop command */
+ pSd_Reg->ctlr |= 0x08; /* response FIFO reset, */
+ sd_status = sd_command(STOP_TRANSMISSION, 7, (unsigned int)src, R1b);
+ if (sd_status != 0)
+ return -1;
+ if (SDDevInfo->CardCapacityStatus == 0)
+ ulBlockStart += 127*512;
+ else
+ ulBlockStart += 127;
+ ulBlockCount -= 127;
+ src += 127*512;
+
+
+ count = 0x1000000;
+ while(1) {
+ sd_status = sd_command(SEND_STATUS, 0, SDDevInfo->RCA, R1);
+ if (sd_status != 0) {
+ printf("mmc_block_write_multiblock fail!\n");
+ return -1;
+ }
+ if (pSd_Reg->resr[3] == 0x09)
+ break;
+ count--;
+ if (count == 0) {
+ printf("mmc_block_write_multiblock Time Out!\n");
+ break;
+ }
+
+ }
+ }
+
+ if (ulBlockCount) {
+ pSd_Reg->blkcnt = (unsigned short)(ulBlockCount & 0xFFFF);
+ pSd_Reg->ctlr |= 0x08; /* response FIFO reset, */
+ pSd_Reg->str0 |= 0xFF;
+ pSd_Reg->str1 |= 0xFF;
+ /* Config Read DMA */
+ SD_Init_PDMA();
+ sd_config_desc((unsigned long *)(&WriteDesc), (unsigned long*)src, ulBlockCount);
+ sd_config_pdma((unsigned long *)(&WriteDesc), SD_PDMA_WRITE);
+ //pSd_Reg->extctl |= 0x01;
+
+ sd_status = sd_command(WRITE_MULTIPLE_BLOCK, 3, ulBlockStart, R1);
+ if (sd_status != 0) {
+ SDPRINTK("\nWrite Multi Block CMD last Err ! ulBlockStart %d ulBlockCount %d\n", ulBlockStart, ulBlockCount);
+ return -1 ;
+ }
+
+
+ sd_status = sd_pdma_handler();
+ if (sd_status != 0) {
+ pSd_Reg->timeval = 0xefff;
+ return -1 ;
+ }
+
+ /* free dma */
+ sd_free_pdma();
+
+ /* send CMD12 : stop command */
+ pSd_Reg->ctlr |= 0x08 ; /* response FIFO reset, */
+ sd_status = sd_command(STOP_TRANSMISSION, 7, (unsigned int)src, R1b);
+ if (sd_status != 0)
+ return -1 ;
+
+ count = 0x1000000;
+ while(1) {
+ sd_status = sd_command(SEND_STATUS, 0, SDDevInfo->RCA, R1);
+ if (sd_status != 0)
+ return -1;
+ if (pSd_Reg->resr[3] == 0x09)
+ break;
+ count--;
+ if (count == 0) {
+ printf("mmc_block_write_multiblock Time Out!\n");
+ break;
+ }
+
+ }
+ }
+ SDPRINTK("\n Write multi Block CMD OK !\n");
+ return 0 ;
+}
+
+int
+/****************************************************/
+mmc_read(ulong src, uchar *dst, int size)
+/****************************************************/
+{
+ ulong end, part_start, part_end, aligned_start, aligned_end;
+ ulong mmc_block_size, mmc_block_address, ulBlockCount;
+
+ if (size == 0) {
+ return 0;
+ }
+
+ if (!mmc_ready) {
+ printf("Please initial the MMC first\n");
+ return -1;
+ }
+
+ mmc_block_size = MMC_BLOCK_SIZE;
+ mmc_block_address = ~(mmc_block_size - 1);
+
+ src -= CFG_MMC_BASE;
+ end = src + size;
+ part_start = ~mmc_block_address & src;
+ part_end = ~mmc_block_address & end;
+ aligned_start = mmc_block_address & src;
+ aligned_end = mmc_block_address & end;
+ ulBlockCount = (aligned_end-src)/MMC_BLOCK_SIZE;
+
+ if (ulBlockCount ==1) {
+ /*This is for single block read*/
+ /*for (; src < aligned_end; src += mmc_block_size, dst += mmc_block_size) {*/
+ if ((mmc_block_read_singleblock((uchar *)dst, (src>>9*SDDevInfo->CardCapacityStatus))) < 0) {
+ return -1;
+ }
+ /*}*/
+ } else {
+ /*This is for multi block read*/
+ if (mmc_block_read_multiblock((uchar*)dst, (src>>9*SDDevInfo->CardCapacityStatus), ulBlockCount) < 0) {
+ return -1;
+ }
+ }
+ return 0;
+}
+
+int
+/****************************************************/
+mmc_write(uchar *src, ulong dst, int size)
+/****************************************************/
+{
+
+ return 0;
+}
+
+
+ulong
+/****************************************************/
+mmc_bread(int dev_num, ulong blknr, ulong blkcnt, ulong *dst)
+/****************************************************/
+{
+ ulong src = 0;
+ //ulong src_size = 0; //20120105 by eason
+ //ulong SDCard_Size = SDDevInfo->SDCard_Size;
+ //printf("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n");
+ //printf(" dst 0x%x dev_num 0x%x, blknr 0x%x, blkcnt 0x%x \n", dst, dev_num, blknr, blkcnt);
+ //printf(" SDDevInfo->CardCapacityStatus %d \n", SDDevInfo->CardCapacityStatus);
+ if(!blkcnt)
+ return blkcnt;
+
+ /*select host*/
+ Change_SD_host(dev_num);
+
+ if (!mmc_ready) {
+ printf("Please initial the MMC first\n");
+ return -1;
+ }
+
+ src = SDDevInfo->CardCapacityStatus ? blknr : (blknr*MMC_BLOCK_SIZE);
+ /*ount SD size by block based, a block = 512 bytes */
+ //src_size = SDDevInfo->CardCapacityStatus ? src : (src/MMC_BLOCK_SIZE);
+ //if(src_size > SDCard_Size) { /*if reas address > SDCard size , the part_address is error */
+ // printf("mmc_bwrite part_offset error\n");
+ // return -1;
+ //}
+
+ if (blkcnt == 1) {
+ /*This is for single block read*/
+ if ((mmc_block_read_singleblock((uchar *)dst, src)) < 0) {
+ return -1;
+ }
+ } else {
+ /*This is for multi block read*/
+ if (mmc_block_read_multiblock((uchar*)dst, src, blkcnt) < 0) {
+ return -1;
+ }
+ }
+ return blkcnt;
+}
+
+
+ulong
+/****************************************************/
+mmc_bwrite(int dev_num, ulong blknr, ulong blkcnt, ulong *src)
+/****************************************************/
+{
+ ulong dst = 0;
+ //ulong dst_size = 0;
+ //ulong SDCard_Size = SDDevInfo->SDCard_Size;
+ dst = SDDevInfo->CardCapacityStatus ? blknr : (blknr*MMC_BLOCK_SIZE);
+
+ /* count SD size by block based, a block = 512 bytes */
+ //dst_size = SDDevInfo->CardCapacityStatus ? dst : (dst/MMC_BLOCK_SIZE);
+ //printf("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n");
+ //printf("[mmc_bwrite] dst 0x%x src 0x%x dev_num 0x%x, blknr 0x%x, blkcnt 0x%x \n", dst, src, dev_num, blknr, blkcnt);
+ if(!blkcnt)
+ return blkcnt;
+
+ /*select host*/
+ Change_SD_host(dev_num);
+
+ if (!mmc_ready) {
+ printf("Please initial the MMC first\n");
+ return -1;
+ }
+ //if(dst_size > SDCard_Size) { /*if write address > SDCard size , the part_offset is error */
+ // printf("mmc_bwrite part_offset error\n");
+ // return -1;
+ //}
+ if (blkcnt ==1) {
+ /*This is for single block read*/
+ if ((mmc_block_write_singleblock((uchar *)src, dst)) < 0) {
+ return -1;
+ }
+ } else {
+ /*This is for multi block read*/
+ if (mmc_block_write_multiblock((uchar*)src, dst, blkcnt) < 0) {
+ return -1;
+ }
+ }
+ return blkcnt;
+}
+int
+/****************************************************/
+mmc_fb_write(unsigned dev_num, ulong blknr, ulong blkcnt, uchar *src)
+/****************************************************/
+{
+ ulong dst = 0;
+ //ulong dst_size = 0;
+ //ulong SDCard_Size = SDDevInfo->SDCard_Size;
+ dst = SDDevInfo->CardCapacityStatus ? blknr : (blknr*MMC_BLOCK_SIZE);
+
+ /* count SD size by block based, a block = 512 bytes */
+ //dst_size = SDDevInfo->CardCapacityStatus ? dst : (dst/MMC_BLOCK_SIZE);
+ //printf("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n");
+ //printf("[mmc_bwrite] dst 0x%x src 0x%x dev_num 0x%x, blknr 0x%x, blkcnt 0x%x \n", dst, src, dev_num, blknr, blkcnt);
+ if(!blkcnt)
+ return blkcnt;
+
+ /*select host*/
+ Change_SD_host(dev_num);
+
+ if (!mmc_ready) {
+ printf("Please initial the MMC first\n");
+ return -1;
+ }
+ //if(dst_size > SDCard_Size) { /*if write address > SDCard size , the part_offset is error */
+ // printf("mmc_bwrite part_offset error\n");
+ // return -1;
+ //}
+ if (blkcnt ==1) {
+ /*This is for single block read*/
+ if ((mmc_block_write_singleblock((uchar *)src, dst)) < 0) {
+ return -1;
+ }
+ } else {
+ /*This is for multi block read*/
+ if (mmc_block_write_multiblock((uchar*)src, dst, blkcnt) < 0) {
+ return -1;
+ }
+ }
+ return blkcnt;
+}
+int sd_set_clock(int Frequence)
+{
+
+ if (Frequence == SD_Clk_Auto) {
+ /* Check SD Card */
+ if (SDDevInfo->SD_Card == SD_TRUE) {
+ if (SDDevInfo->HighSpeedSupport == SD_TRUE)
+ Frequence = 6; /* 50Mhz */
+ else
+ Frequence = 3; /* 25Mhz */
+ }
+
+ /* Check MMC Card */
+ if (SDDevInfo->MMC_Card == SD_TRUE) {
+ if (SDDevInfo->MMCMaxClockRate == Clk_48)
+ Frequence = 6; /* 50Mhz */
+ else if (SDDevInfo->MMCMaxClockRate == Clk_24)
+ Frequence = 3; /* 25Mhz */
+ else if (SDDevInfo->MMCMaxClockRate == Clk_15)
+ Frequence = 1; /* 15Mhz */
+ }
+ }
+
+ switch (Frequence) {
+ case SD_Clk_Auto:
+ break;
+ case SD_Clk_15MHz:
+ pSd_Reg->extctl &= ~0x80; /* Disable High Speed timing */
+ if (SDDevInfo->CtrlID == 0) {
+ auto_pll_divisor(DEV_SDMMC0, SET_DIV, 2, 15);
+ SDPRINTK("ATSMB Host0 15MHz \n");
+ }
+ if (SDDevInfo->CtrlID == 1) {
+ auto_pll_divisor(DEV_SDMMC1, SET_DIV, 2, 15);
+ SDPRINTK("ATSMB Host1 15MHz \n");
+ }
+ if (SDDevInfo->CtrlID == 2) {
+ auto_pll_divisor(DEV_SDMMC2, SET_DIV, 2, 15);
+ SDPRINTK("ATSMB Host2 15MHz \n");
+ }
+ break;
+ case SD_Clk_20MHz:
+ pSd_Reg->extctl &= ~0x80; /* Disable High Speed timing */
+ if (SDDevInfo->CtrlID == 0) {
+ auto_pll_divisor(DEV_SDMMC0, SET_DIV, 2, 20);
+ SDPRINTK("ATSMB Host0 20MHz \n");
+ }
+ if (SDDevInfo->CtrlID == 1) {
+ auto_pll_divisor(DEV_SDMMC1, SET_DIV, 2, 20);
+ SDPRINTK("ATSMB Host1 20MHz \n");
+ }
+ if (SDDevInfo->CtrlID == 2) {
+ auto_pll_divisor(DEV_SDMMC2, SET_DIV, 2, 20);
+ SDPRINTK("ATSMB Host2 20MHz \n");
+ }
+ break;
+ case SD_Clk_25MHz:
+ pSd_Reg->extctl &= ~0x80; /* Disable High Speed timing */
+ if (SDDevInfo->CtrlID == 0) {
+ auto_pll_divisor(DEV_SDMMC0, SET_DIV, 2, 24);
+ SDPRINTK("ATSMB Host0 25MHz \n");
+ }
+ if (SDDevInfo->CtrlID == 1) {
+ auto_pll_divisor(DEV_SDMMC1, SET_DIV, 2, 24);
+ SDPRINTK("ATSMB Host1 25MHz \n");
+ }
+ if (SDDevInfo->CtrlID == 2) {
+ auto_pll_divisor(DEV_SDMMC2, SET_DIV, 2, 24);
+ SDPRINTK("ATSMB Host2 25MHz \n");
+ }
+ break;
+ case SD_Clk_33MHz:
+ if (SDDevInfo->SD_Card == SD_TRUE) {
+ pSd_Reg->extctl |= 0x80; /* Enable High Speed timing */
+ }
+ if (SDDevInfo->MMC_Card == SD_TRUE) {
+ pSd_Reg->extctl &= ~0x80; /* Disable High Speed timing */
+ }
+ if (SDDevInfo->CtrlID == 0) {
+ auto_pll_divisor(DEV_SDMMC0, SET_DIV, 2, 33);
+ SDPRINTK("ATSMB Host0 33MHz \n");
+ }
+ if (SDDevInfo->CtrlID == 1) {
+ pSd_Reg->extctl &= ~0x80; /* Disable High Speed timing for WM3498 */
+ auto_pll_divisor(DEV_SDMMC1, SET_DIV, 2, 33);
+ SDPRINTK("ATSMB Host1 33MHz \n");
+ }
+ if (SDDevInfo->CtrlID == 2) {
+ auto_pll_divisor(DEV_SDMMC2, SET_DIV, 2, 33);
+ SDPRINTK("ATSMB Host2 33MHz \n");
+ }
+ break;
+ case SD_Clk_40MHz:
+ if (SDDevInfo->SD_Card == SD_TRUE) {
+ pSd_Reg->extctl |= 0x80; /* Enable High Speed timing */
+ }
+ if (SDDevInfo->MMC_Card == SD_TRUE) {
+ pSd_Reg->extctl &= ~0x80; /* Disable High Speed timing */
+ }
+ if (SDDevInfo->CtrlID == 0) {
+ auto_pll_divisor(DEV_SDMMC0, SET_DIV, 2, 40);
+ SDPRINTK("ATSMB Host0 40MHz \n");
+ }
+ if (SDDevInfo->CtrlID == 1) {
+ pSd_Reg->extctl &= ~0x80; /* Disable High Speed timing for WM3498 */
+ auto_pll_divisor(DEV_SDMMC1, SET_DIV, 2, 40);
+ SDPRINTK("ATSMB Host1 40MHz \n");
+ }
+ if (SDDevInfo->CtrlID == 2) {
+ auto_pll_divisor(DEV_SDMMC2, SET_DIV, 2, 40);
+ SDPRINTK("ATSMB Host2 40MHz \n");
+ }
+ break;
+ case SD_Clk_44MHz:
+ if (SDDevInfo->SD_Card == SD_TRUE) {
+ pSd_Reg->extctl |= 0x80; /* Enable High Speed timing */
+ }
+ if (SDDevInfo->MMC_Card == SD_TRUE) {
+ pSd_Reg->extctl &= ~0x80; /* Disable High Speed timing */
+ }
+ if (SDDevInfo->CtrlID == 0) {
+ auto_pll_divisor(DEV_SDMMC0, SET_DIV, 2, 44);
+ SDPRINTK("ATSMB Host0 44MHz \n");
+ }
+ if (SDDevInfo->CtrlID == 1) {
+ pSd_Reg->extctl &= ~0x80; /* Disable High Speed timing for WM3498 */
+ auto_pll_divisor(DEV_SDMMC1, SET_DIV, 2, 44);
+ SDPRINTK("ATSMB Host1 44MHz \n");
+ }
+ if (SDDevInfo->CtrlID == 2) {
+ auto_pll_divisor(DEV_SDMMC2, SET_DIV, 2, 44);
+ SDPRINTK("ATSMB Host2 44MHz \n");
+ }
+ break;
+/* case SD_Clk_50MHz:
+ if (SDDevInfo->SD_Card == SD_TRUE) {
+ pSd_Reg->extctl |= 0x80;
+ }
+ if (SDDevInfo->MMC_Card == SD_TRUE) {
+ pSd_Reg->extctl &= ~0x80;
+ }
+ if (SDDevInfo->CtrlID == 0) {
+ auto_pll_divisor(DEV_SDMMC0, SET_DIV, 2, 50);
+ SDPRINTK("ATSMB Host0 50MHz \n");
+ }
+ if (SDDevInfo->CtrlID == 1) {
+ auto_pll_divisor(DEV_SDMMC1, SET_DIV, 2, 50);
+ SDPRINTK("ATSMB Host1 50MHz \n");
+ }
+ if (SDDevInfo->CtrlID == 2) {
+ auto_pll_divisor(DEV_SDMMC2, SET_DIV, 2, 50);
+ SDPRINTK("ATSMB Host2 50MHz \n");
+ }
+ if (SDDevInfo->CtrlID == 3) {
+ auto_pll_divisor(DEV_SDMMC3, SET_DIV, 2, 50);
+ SDPRINTK("ATSMB Host3 50MHz \n");
+ }
+ break;*/
+ case SD_Clk_400KHz:
+ pSd_Reg->extctl &= ~0x80; /* Disable High Speed timing */
+ if (SDDevInfo->CtrlID == 0) {
+ auto_pll_divisor(DEV_SDMMC0, SET_DIV, 1, 400);
+ SDPRINTK("ATSMB Host0 400KHz \n");
+ }
+ if (SDDevInfo->CtrlID == 1) {
+ auto_pll_divisor(DEV_SDMMC1, SET_DIV, 1, 400);
+ SDPRINTK("ATSMB Host1 400KHz \n");
+ }
+ if (SDDevInfo->CtrlID == 2) {
+ auto_pll_divisor(DEV_SDMMC2, SET_DIV, 1, 400);
+ SDPRINTK("ATSMB Host2 400KHz \n");
+ }
+ break;
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+int
+mmc_init(int verbose, int device_num)
+/****************************************************/
+{
+ unsigned long sd_status;
+
+
+ int Fre = 3;/*3*/
+
+ get_chip_version();
+ if (chip_id == 0x3437 ||
+ chip_id == 0x3429 ||
+ chip_id == 0x3451) {
+ if (device_num > 1)
+ device_num = 1;
+ if (device_num < 0)
+ device_num = 0;
+ } else if (chip_id == 0x3445 || chip_id == 0x3498) {
+ if (device_num > 2)
+ device_num = 2;
+ if (device_num < 0)
+ device_num = 0;
+ } else if (chip_id == 0x3481) {
+ if (device_num > 3)
+ device_num = 3;
+ if (device_num < 0)
+ device_num = 0;
+ } else {
+ device_num = 0;
+ }
+
+ if (device_num == 0)
+ auto_pll_divisor(DEV_SDMMC0, CLK_ENABLE, 0, 0);
+ if (device_num == 1)
+ auto_pll_divisor(DEV_SDMMC1, CLK_ENABLE, 0, 0);
+ if (device_num == 2)
+ auto_pll_divisor(DEV_SDMMC2, CLK_ENABLE, 0, 0);
+
+ Change_SD_host(device_num);
+ memset(SDDevInfo, 0x0, sizeof(sd_info_t));
+ SDDevInfo->CtrlID = (char)device_num;
+
+ SD_Controller_Powerup();
+
+ sd_status = SD_Initialization(); /* for Emul. */
+ if (sd_status != 0 )
+ return -1 ;
+ Fre = SDDevInfo->MMCMaxClockRate;
+ switch (Fre) {
+ case SD_Clk_400KHz:
+ sd_set_clock(SD_Clk_400KHz); /* 400Khz */
+ printf("SD/MMC clock is 400Khz\n");
+ break;
+ case SD_Clk_15MHz:
+ sd_set_clock(SD_Clk_15MHz); /* 15Mhz */
+ printf("SD/MMC clock is 15Mhz\n");
+ break;
+ case SD_Clk_25MHz:
+ sd_set_clock(SD_Clk_25MHz); /* 25Mhz */
+ printf("SD/MMC clock is 22.36Mhz\n");
+ break;
+ case SD_Clk_44MHz:
+ sd_set_clock(SD_Clk_44MHz); /* 44Mhz */
+ printf("SD/MMC clock is 41Mhz\n");
+ break;
+ /*case SD_Clk_50MHz:
+ sd_set_clock(SD_Clk_50MHz); /* 48Mhz
+ printf( "SD/MMC clock is 50Mhz\n");
+ break;*/
+ default:
+ break;
+
+ }
+
+ /* set normal speed bus mode */
+ /* pSd_Reg->extctl &= 0x7F; */
+
+ pSd_Reg->blkcnt = 0x01 ;
+ pSd_Reg->ctlr |= 0x08 ; // response FIFO reset,
+
+
+ mmc_dev->if_type = IF_TYPE_MMC;
+ mmc_dev->part_type = PART_TYPE_DOS;
+ mmc_dev->dev = device_num;
+ mmc_dev->lun = 0;
+ mmc_dev->type = 0;
+ /* FIXME fill in the correct size (is set to 32MByte) */
+ mmc_dev->blksz = 512;
+ mmc_dev->lba = SDDevInfo->SDCard_Size;
+ mmc_dev->removable = 0;
+ mmc_dev->block_read = mmc_bread;
+ mmc_dev->block_write = mmc_bwrite;
+
+ if (device_num == 0)
+ mmc0_ready = 1;
+ if (device_num == 1)
+ mmc1_ready = 1;
+ if (device_num == 2)
+ mmc2_ready = 1;
+ mmc_ready = 1;
+
+
+ printf("register mmc device\n");
+ SDPRINTK("SDCard_Size = %ld MB\n",SDDevInfo->SDCard_Size / (2*1024));
+ fat_register_device(mmc_dev, 1); /* partitions start counting with 1 */
+
+ return 0;
+}
+
+int
+mmc_ident(block_dev_desc_t *dev)
+{
+ return 0;
+}
+
+int
+mmc2info(ulong addr)
+{
+ /* FIXME hard codes to 32 MB device */
+ if (addr >= CFG_MMC_BASE && addr < CFG_MMC_BASE + 0x02000000) {
+ return 1;
+ }
+ return 0;
+}
+
+unsigned int get_chip_version(void)
+{
+ static unsigned int chip_version = 0;
+ unsigned int val;
+
+ if (chip_version)
+ return chip_version;
+
+ chip_id = *(unsigned short *) 0xD8120002;
+ switch (chip_id) {
+ case 0x3357:
+ val = *(unsigned int *)(0xd8120700);
+ *(unsigned int *)(0xd8120700) = val;
+
+ val = *(unsigned int *)(0xd8120700);
+ chip_version = ((0xA + ((val & 0x0F) - 0x02)) << 4) + ((val & 0xF0) >> 4);
+ break;
+ case 0x3400:
+ val = *(unsigned int *) 0xD8120000;
+ chip_version = ((val & 0xF00) >> 4) + 0x90 + ((val & 0xFF) - 1);
+ break;
+ case 0x3426:
+ pSd_Reg = (PWMT_SDMMC_REG) BA_SDC;
+ pSd_PDma_Reg = (struct _SD_PDMA_REG_ *) BA_SDCDMA;
+ val = *(unsigned int *) 0xD8120000;
+ chip_version = ((val & 0xF00) >> 4) + 0x90 + ((val & 0xFF) - 1);
+ break;
+ default:
+ val = *(unsigned int *) 0xD8120000;
+ chip_version = ((val & 0xF00) >> 4) + 0x90 + ((val & 0xFF) - 1);
+ break;
+ }
+ chip_version = (chip_id << 16) | chip_version;
+ SDPRINTK( "debug chip_id = %x, chip_version = %x\n", chip_id, chip_version);
+ return chip_version;
+}
+
+
+
+void SD_Controller_Powerup(void)
+{
+
+#define GPIO_PIN_Sharing REG32_PTR(GPIO_BASE_ADDR + 0x200)
+#define GPIO_Strapping REG32_PTR(GPIO_BASE_ADDR + 0x100)
+
+/*SD0*/
+#define GPIO_INPUT_DATA_SD018SEL REG8_PTR(GPIO_BASE_ADDR + 0x00C)
+#define GPIO_INPUT_DATA_SD REG8_PTR(GPIO_BASE_ADDR + 0x00D)
+#define GPIO_INPUT_DATA_SDCardDetect REG8_PTR(GPIO_BASE_ADDR + 0x03F)
+
+#define GPIO_Enable_SD018SEL REG8_PTR(GPIO_BASE_ADDR + 0x04C)
+#define GPIO_Enable_SD REG8_PTR(GPIO_BASE_ADDR + 0x04D)
+#define GPIO_Enable_SDCardDetect REG8_PTR(GPIO_BASE_ADDR + 0x07F)
+
+#define GPIO_OUTPUT_Enable_SD018SEL REG8_PTR(GPIO_BASE_ADDR + 0x08C)
+#define GPIO_OUTPUT_Enable_SD REG8_PTR(GPIO_BASE_ADDR + 0x08D)
+#define GPIO_OUTPUT_Enable_SDCardDetect REG8_PTR(GPIO_BASE_ADDR + 0x0BF)
+
+#define GPIO_OUTPUT_DATA_SD018SEL REG8_PTR(GPIO_BASE_ADDR + 0x0CC)
+#define GPIO_OUTPUT_DATA_SD REG8_PTR(GPIO_BASE_ADDR + 0x0CD)
+#define GPIO_OUTPUT_DATA_SDCardDetect REG8_PTR(GPIO_BASE_ADDR + 0x0FF)
+
+#define GPIO_PULL_Enable_SD018SEL REG8_PTR(GPIO_BASE_ADDR + 0x48C)
+#define GPIO_PULL_Enable_SD REG8_PTR(GPIO_BASE_ADDR + 0x48D)
+#define GPIO_PULL_Enable_SDCardDetect REG8_PTR(GPIO_BASE_ADDR + 0x4BF)
+
+#define GPIO_PULL_Control_SD018SEL REG8_PTR(GPIO_BASE_ADDR + 0x4CC)
+#define GPIO_PULL_Control_SD REG8_PTR(GPIO_BASE_ADDR + 0x4CD)
+#define GPIO_PULL_Control2_SD REG8_PTR(GPIO_BASE_ADDR + 0x4DB)
+#define GPIO_PULL_Control_SDCardDetect REG8_PTR(GPIO_BASE_ADDR + 0x4FF)
+
+/*SD1*/
+#define GPIO_INPUT_DATA_SD1 REG8_PTR(GPIO_BASE_ADDR + 0x00E)
+#define GPIO_INPUT_DATA_SD1Data REG8_PTR(GPIO_BASE_ADDR + 0x010)
+
+#define GPIO_Enable_SD1 REG8_PTR(GPIO_BASE_ADDR + 0x04E)
+#define GPIO_Enable_SD1Data REG8_PTR(GPIO_BASE_ADDR + 0x050)
+
+#define GPIO_OUTPUT_Enable_SD1 REG8_PTR(GPIO_BASE_ADDR + 0x08E)
+#define GPIO_OUTPUT_Enable_SD1Data REG8_PTR(GPIO_BASE_ADDR + 0x090)
+
+#define GPIO_OUTPUT_DATA_SD1 REG8_PTR(GPIO_BASE_ADDR + 0x0CE)
+#define GPIO_OUTPUT_DATA_SD1Data REG8_PTR(GPIO_BASE_ADDR + 0x0D0)
+
+#define GPIO_PULL_Enable_SD1 REG8_PTR(GPIO_BASE_ADDR + 0x48E)
+#define GPIO_PULL_Enable_SD1Data REG8_PTR(GPIO_BASE_ADDR + 0x490)
+
+#define GPIO_PULL_Control_SD1 REG8_PTR(GPIO_BASE_ADDR + 0x4CE)
+#define GPIO_PULL_Control_SD1Data REG8_PTR(GPIO_BASE_ADDR + 0x4D0)
+
+/*SD2*/
+#define GPIO_INPUT_DATA_SD2 REG8_PTR(GPIO_BASE_ADDR + 0x013)
+#define GPIO_INPUT_DATA_SD2CardDetect REG8_PTR(GPIO_BASE_ADDR + 0x03F)
+
+#define GPIO_Enable_SD2 REG8_PTR(GPIO_BASE_ADDR + 0x053)
+#define GPIO_Enable_SD2CardDetect REG8_PTR(GPIO_BASE_ADDR + 0x07F)
+
+#define GPIO_OUTPUT_Enable_SD2 REG8_PTR(GPIO_BASE_ADDR + 0x093)
+#define GPIO_OUTPUT_Enable_SD2CardDetect REG8_PTR(GPIO_BASE_ADDR + 0x0BF)
+
+#define GPIO_OUTPUT_DATA_SD2 REG8_PTR(GPIO_BASE_ADDR + 0x0D3)
+#define GPIO_OUTPUT_DATA_SD2CardDetect REG8_PTR(GPIO_BASE_ADDR + 0x0FF)
+
+#define GPIO_PULL_Enable_SD2 REG8_PTR(GPIO_BASE_ADDR + 0x493)
+#define GPIO_PULL_Enable_SD2CardDetect REG8_PTR(GPIO_BASE_ADDR + 0x4BF)
+
+#define GPIO_PULL_Control_SD2 REG8_PTR(GPIO_BASE_ADDR + 0x4D3)
+#define GPIO_PULL_Control_SD2CardDetect REG8_PTR(GPIO_BASE_ADDR + 0x4FF)
+
+/* SD pin */
+#define GPIO_SD0_CD BIT4
+#define GPIO_SD0_Data (BIT6 | BIT5 | BIT4 | BIT3)
+#define GPIO_SD0_WriteProtect BIT2
+#define GPIO_SD0_Command BIT1
+#define GPIO_SD0_Clock BIT0
+#define GPIO_SD0_POWER BIT7
+#define GPIO_SD0_18SEL BIT4
+
+#define GPIO_SD1_Data (BIT7 | BIT6 | BIT5 | BIT4 | BIT3 | BIT2 | BIT1 | BIT0)
+#define GPIO_SD1_Command BIT1
+#define GPIO_SD1_Clock BIT0
+#define GPIO_SD1_CD BIT6
+#define GPIO_SD1_WriteProtect BIT5
+#define GPIO_SD1_POWER BIT4
+#define GPIO_SD1_RSTN BIT3
+
+#define GPIO_SD2_Data (BIT3 | BIT2 | BIT1 | BIT0)
+#define GPIO_SD2_Command BIT4
+#define GPIO_SD2_Clock BIT5
+#define GPIO_SD2_CD BIT2
+#define GPIO_SD2_WriteProtect BIT7
+#define GPIO_SD2_POWER BIT6
+
+/* PIN share switch */
+#define GPIO_SD1_PinShare BIT11
+#define GPIO_SD2_PinShare BIT28
+
+#define SD0_CARD_PWR BIT1
+#define SD1_CARD_PWR BIT2
+#define SD2_CARD_PWR BIT3
+
+ /* unsigned long SD0_PIN,SD1_PIN,SD2_PIN; */
+ /* SD0_PIN = ( GPIO_SD0_Clock | GPIO_SD0_Command | GPIO_SD0_WriteProtect | GPIO_SD0_Data); */
+ /* SD1_PIN = ( GPIO_SD1_Clock | GPIO_SD1_Command | GPIO_SD1_WriteProtect | GPIO_SD1_RSTN | GPIO_SD1_CD); */
+ /* SD2_PIN = ( GPIO_SD2_Clock | GPIO_SD2_Command | GPIO_SD2_WriteProtect | GPIO_SD2_Data); */
+ /* Get Strapping option status register */
+ SDDevInfo->strapping = *GPIO_Strapping;
+
+ /* set normal speed bus mode */
+ pSd_Reg->extctl = 0x0;
+ pSd_Reg->busm = 0x0; /* response FIFO reset, */
+
+ /* disable SD Card power */
+ if (SDDevInfo->CtrlID == 0) {
+ /*set SD0 power pin as GPO pin*/
+ *GPIO_Enable_SD |= GPIO_SD0_POWER; /*Set power pin as GPIO pin*/
+ *GPIO_OUTPUT_Enable_SD |= GPIO_SD0_POWER; /*Set output pin*/
+
+ /*set internal pull up*/
+ *GPIO_PULL_Control_SD |= GPIO_SD0_POWER;
+
+ /*set internal pull enable*/
+ *GPIO_PULL_Enable_SD |= GPIO_SD0_POWER;
+
+ /*disable SD0 power*/
+ *GPIO_OUTPUT_DATA_SD |= GPIO_SD0_POWER;
+ } else if (SDDevInfo->CtrlID == 1) {
+ /*set SD1 power pin as GPO pin*/
+ *GPIO_Enable_SD1 |= GPIO_SD1_POWER; /*Set power pin as GPIO pin*/
+ *GPIO_OUTPUT_Enable_SD1 |= GPIO_SD1_POWER; /*Set output pin*/
+
+ /*set internal pull up*/
+ *GPIO_PULL_Control_SD1 |= GPIO_SD1_POWER;
+
+ /*set internal pull enable*/
+ *GPIO_PULL_Enable_SD1 |= GPIO_SD1_POWER;
+
+ /*disable SD1 power*/
+ *GPIO_OUTPUT_DATA_SD1 |= GPIO_SD1_POWER;
+ } else if (SDDevInfo->CtrlID == 2) {
+ /*set SD2 power pin as GPO pin*/
+ *GPIO_Enable_SD2 |= GPIO_SD2_POWER; /*Set power pin as GPIO pin*/
+ *GPIO_OUTPUT_Enable_SD2 |= GPIO_SD2_POWER; /*Set output pin*/
+
+ /*set internal pull up*/
+ *GPIO_PULL_Control_SD2 |= GPIO_SD2_POWER;
+
+ /*set internal pull enable*/
+ *GPIO_PULL_Enable_SD2 |= GPIO_SD2_POWER;
+
+ /*disable SD2 power*/
+ *GPIO_OUTPUT_DATA_SD2 |= GPIO_SD2_POWER;
+ }
+
+ /* Config SD PIN share */
+ if (SDDevInfo->CtrlID == 1)
+ *GPIO_PIN_Sharing |= GPIO_SD1_PinShare;
+ else if (SDDevInfo->CtrlID == 2)
+ *GPIO_PIN_Sharing |= GPIO_SD2_PinShare;
+
+ /* do not config GPIO_SD1_CD because ISR has already rum,
+ * config card detect will issue ISR storm.
+ */
+
+ /* Config SD to GPIO */
+ if (SDDevInfo->CtrlID == 0) {
+ *GPIO_Enable_SD |= (GPIO_SD0_Clock | GPIO_SD0_Command | GPIO_SD0_WriteProtect | GPIO_SD0_Data);
+ *GPIO_Enable_SDCardDetect |= GPIO_SD0_CD;
+ *GPIO_Enable_SD018SEL |= GPIO_SD0_18SEL;
+ } else if (SDDevInfo->CtrlID == 1) {
+ *GPIO_Enable_SD1 |= (GPIO_SD1_Clock | GPIO_SD1_Command | GPIO_SD1_WriteProtect | GPIO_SD1_RSTN | GPIO_SD1_CD);
+ *GPIO_Enable_SD1Data |= GPIO_SD1_Data;
+ } else if (SDDevInfo->CtrlID == 2) {
+ *GPIO_Enable_SD2 |= (GPIO_SD2_Clock | GPIO_SD2_Command | GPIO_SD1_WriteProtect | GPIO_SD2_Data);
+ *GPIO_Enable_SD2CardDetect |= GPIO_SD2_CD;
+ }
+
+ /* SD all pins output low */
+ if (SDDevInfo->CtrlID == 0) {
+ *GPIO_OUTPUT_DATA_SD &= ~(GPIO_SD0_Clock | GPIO_SD0_Command | GPIO_SD0_WriteProtect | GPIO_SD0_Data);
+ *GPIO_OUTPUT_DATA_SDCardDetect &= ~GPIO_SD0_CD;
+ *GPIO_OUTPUT_DATA_SD018SEL |= GPIO_SD0_18SEL;
+ } else if (SDDevInfo->CtrlID == 1) {
+ *GPIO_OUTPUT_DATA_SD1 &= ~(GPIO_SD1_Clock | GPIO_SD1_Command | GPIO_SD1_WriteProtect | GPIO_SD1_RSTN | GPIO_SD1_CD);
+ *GPIO_OUTPUT_DATA_SD1Data &= ~GPIO_SD1_Data;
+ } else if (SDDevInfo->CtrlID == 2) {
+ *GPIO_OUTPUT_DATA_SD2 &= ~(GPIO_SD2_Clock | GPIO_SD2_Command | GPIO_SD1_WriteProtect | GPIO_SD2_Data);
+ *GPIO_OUTPUT_DATA_SD2CardDetect &= ~GPIO_SD2_CD;
+ }
+
+ /* Config SD to GPO */
+ if (SDDevInfo->CtrlID == 0) {
+ *GPIO_OUTPUT_Enable_SD |= (GPIO_SD0_Clock | GPIO_SD0_Command | GPIO_SD0_WriteProtect | GPIO_SD0_Data);
+ *GPIO_OUTPUT_Enable_SDCardDetect |= GPIO_SD0_CD;
+ *GPIO_OUTPUT_Enable_SD018SEL = GPIO_SD0_18SEL;
+ } else if (SDDevInfo->CtrlID == 1) {
+ *GPIO_OUTPUT_Enable_SD1 |= (GPIO_SD1_Clock | GPIO_SD1_Command | GPIO_SD1_WriteProtect | GPIO_SD1_RSTN | GPIO_SD1_CD);
+ *GPIO_OUTPUT_Enable_SD1Data |= GPIO_SD1_Data;
+ } else if (SDDevInfo->CtrlID == 2) {
+ *GPIO_OUTPUT_Enable_SD2 |= (GPIO_SD2_Clock | GPIO_SD2_Command | GPIO_SD1_WriteProtect | GPIO_SD2_Data);
+ *GPIO_OUTPUT_Enable_SD2CardDetect |= GPIO_SD2_CD;
+ }
+
+ /* stop SD output clock */
+ pSd_Reg->busm &= ~BIT4;
+ udelay(100000); /* for SD card, need to delay 100 ms. */
+
+ /* Pull up/down resister of SD Bus */
+ if (SDDevInfo->CtrlID == 0) {
+ /*Disable Clock & CMD Pull enable*/
+ *GPIO_PULL_Enable_SD &= ~(GPIO_SD0_Clock | GPIO_SD0_Command);
+
+ /*Set CD ,WP ,DATA pin pull up*/
+ *GPIO_PULL_Control_SDCardDetect |= GPIO_SD0_CD;
+ *GPIO_PULL_Control_SD |= (GPIO_SD0_Data | GPIO_SD0_WriteProtect);
+ *GPIO_PULL_Control_SD018SEL |= GPIO_SD0_18SEL;
+
+ /*Enable CD ,WP ,DATA internal pull*/
+ *GPIO_PULL_Enable_SDCardDetect |= GPIO_SD0_CD;
+ *GPIO_PULL_Enable_SD |= (GPIO_SD0_Data | GPIO_SD0_WriteProtect);
+ *GPIO_PULL_Enable_SD018SEL |= GPIO_SD0_18SEL;
+
+ } else if (SDDevInfo->CtrlID == 1) {
+ /*Disable Clock & CMD Pull enable*/
+ *GPIO_PULL_Enable_SD1 &= ~(GPIO_SD1_Clock | GPIO_SD1_Command);
+
+ /*Set CD ,WP ,DATA pin pull up*/
+ /* SD1 no card detect feature Bow */
+ /**GPIO_PULL_Control_SD1 |= GPIO_SD1_CD;*/
+ *GPIO_PULL_Control_SD1 |= GPIO_SD1_WriteProtect;
+ *GPIO_PULL_Control_SD1Data |= GPIO_SD1_Data;
+
+ /*Enable CD ,WP ,DATA internal pull*/
+ /* SD1 no card detect feature Bow */
+ /**GPIO_PULL_Enable_SD1 |= GPIO_SD1_CD;*/
+ *GPIO_PULL_Enable_SD1 |= GPIO_SD1_WriteProtect;
+ *GPIO_PULL_Enable_SD1Data |= GPIO_SD1_Data;
+
+ } else if (SDDevInfo->CtrlID == 2) {
+ /*Disable Clock & CMD Pull enable*/
+ *GPIO_PULL_Enable_SD2 &= ~(GPIO_SD2_Clock | GPIO_SD2_Command);
+
+ /*Set CD ,WP ,DATA pin pull up*/
+ *GPIO_PULL_Control_SD2CardDetect |= GPIO_SD2_CD;
+ *GPIO_PULL_Control_SD2 |= (GPIO_SD2_Data | GPIO_SD2_WriteProtect);
+
+ /*Enable CD ,WP ,DATA internal pull*/
+ *GPIO_PULL_Enable_SD2CardDetect |= GPIO_SD2_CD;
+ *GPIO_PULL_Enable_SD2 |= (GPIO_SD2_Data | GPIO_SD2_WriteProtect);
+
+ }
+
+ udelay(10000);
+ /*enable SD power*/
+ if (SDDevInfo->CtrlID == 0) {
+ /*Enable SD0 power*/
+ *GPIO_OUTPUT_DATA_SD &= ~GPIO_SD0_POWER;
+ } else if (SDDevInfo->CtrlID == 1) {
+ /*Ensable SD1 power*/
+ *GPIO_OUTPUT_DATA_SD1 &= ~GPIO_SD1_POWER;
+ } else if (SDDevInfo->CtrlID == 2) {
+ /*Ensable SD2 power*/
+ *GPIO_OUTPUT_DATA_SD2 &= ~GPIO_SD2_POWER;
+ }
+
+ /* issue softReset to SD controller */
+ pSd_Reg->busm = SOFT_RESET;
+
+ /* automatic clock freezing enable */
+ pSd_Reg->str2 = DIS_FORCECLK;
+
+ pSd_Reg->timeval = 0xefff;
+ SD_Init_PDMA();
+
+ /* clear card_insert in STS0[7] */
+ pSd_Reg->str0 = DEVICE_INS;
+
+ /* SD clock = 400Khz */
+ sd_set_clock(SD_Clk_400KHz);
+
+ /* enable SD output clock */
+ pSd_Reg->busm |= 0x10;
+ udelay(10000);
+
+
+ /* Config SD back to function */
+ if (SDDevInfo->CtrlID == 0) {
+ *GPIO_Enable_SD &= ~(GPIO_SD0_Clock | GPIO_SD0_Command | GPIO_SD0_WriteProtect | GPIO_SD0_Data);
+ *GPIO_Enable_SDCardDetect &= ~GPIO_SD0_CD;
+ *GPIO_Enable_SD018SEL &= ~GPIO_SD0_18SEL;
+ } else if (SDDevInfo->CtrlID == 1) {
+ *GPIO_Enable_SD1 &= ~(GPIO_SD1_Clock | GPIO_SD1_Command | GPIO_SD1_WriteProtect | GPIO_SD1_RSTN);
+ /* SD1 no card detect feature Bow */
+ /**GPIO_Enable_SD1CardDetect &= ~GPIO_SD1_CD;*/
+ *GPIO_Enable_SD1Data &= ~GPIO_SD1_Data;
+ } else if (SDDevInfo->CtrlID == 2) {
+ *GPIO_Enable_SD2 &= ~(GPIO_SD2_Clock | GPIO_SD2_Command | GPIO_SD2_WriteProtect | GPIO_SD2_Data);
+ *GPIO_Enable_SD2CardDetect &= ~GPIO_SD2_CD;
+ }
+
+ /* issue softReset to SD controller */
+ //pSd_Reg->busm= SOFT_RESET;
+ card_nop();
+}
+
+
+int SD_card_inserted(void)
+{
+ int ret;
+ SD_Controller_Powerup();
+
+ sd_command(GO_IDLE_STATE, 0, 0x0, R0); /*reset SD Card*/
+ ret = sd_command(APP_CMD, 0, 0x0, R1);
+ if (!ret)
+ ret = sd_command(SD_APP_OP_COND, 0, 0x0, R3); /*send ACMD41 to get card's require voltage range*/
+ if (!ret)
+ return 1; /*inserted*/
+ else
+ return 0; /*not inserted*/
+}
+
+
+int mmc_wfs_read(unsigned long dev, unsigned long addr, char *filename, unsigned long bytes) {
+
+
+ disk_partition_t pt;
+ char buffer[512];
+ root_dir *RootDir = buffer;
+ unsigned long blkcnt = 0;
+ unsigned long blk_addr = 0;
+ unsigned long status = 0;
+
+ Change_SD_host(dev);
+
+ if (!mmc_ready) {
+ printf("Please initial the SD/MMC first\n");
+ return -1;
+ }
+#if 0
+ printf("mmc_wfs_read\n");
+ printf("<dev> : 0x%x\n",dev);
+ printf("<addr> : 0x%x\n",addr);
+ printf("<filename> : %s\n",filename);
+ printf("<bytes> : 0x%x\n",bytes);
+#endif
+ get_partition_info(mmc_dev, 1, &pt);
+#if 0
+ printf("\nPartition info\n");
+ printf("offset = 0x%x\n", pt.offset);
+ printf("start = 0x%x\n", pt.start);
+ printf("size = 0x%x 0x%xMB\n", pt.size, pt.size/2048);
+ printf("blksz = 0x%x\n", pt.blksz);
+ printf("name = %s\n", &pt.name);
+ printf("type = %s\n", &pt.type);
+#endif
+ /*Read Root Dir*/
+ mmc_bread(dev, pt.start, 1, RootDir);
+
+ if (strcmp(RootDir->MagicHeader, "WMTBLS!") != 0) {
+ printf("The MagicHeader is not correct '%s'\n",RootDir->MagicHeader);
+ return -1;
+ }
+#if 0
+ printf("RootDir->MagicHeader = %s\n",RootDir->MagicHeader);
+ printf("RootDir->filename1 = %s\n",RootDir->filename1);
+ printf("RootDir->filesize1 = 0x%x\n",RootDir->filesize1);
+ printf("RootDir->filename2 = %s\n",RootDir->filename2);
+ printf("RootDir->filesize2 = 0x%x\n",RootDir->filesize2);
+ printf("RootDir->filename3 = %s\n",RootDir->filename3);
+ printf("RootDir->filesize3 = 0x%x\n",RootDir->filesize3);
+#endif
+ if (strcmp(filename, "wx-load.bin") == 0) {
+ if (bytes > 0) {
+ blkcnt = bytes/MMC_BLOCK_SIZE;
+
+ if (bytes % MMC_BLOCK_SIZE)
+ blkcnt++;
+ } else {
+ blkcnt = RootDir->filesize1/MMC_BLOCK_SIZE;
+
+ if (RootDir->filesize1 % MMC_BLOCK_SIZE)
+ blkcnt++;
+ }
+
+ blk_addr = pt.start + (0x10000 / MMC_BLOCK_SIZE);
+
+ status = mmc_bread(dev, blk_addr, blkcnt, addr);
+
+ if (status == -1)
+ return -1;
+ } else if (strcmp(filename, "wmt-env.bin") == 0){
+ if (bytes > 0) {
+ blkcnt = bytes/MMC_BLOCK_SIZE;
+
+ if (bytes % MMC_BLOCK_SIZE)
+ blkcnt++;
+ } else {
+ blkcnt = RootDir->filesize2/MMC_BLOCK_SIZE;
+
+ if (RootDir->filesize2 % MMC_BLOCK_SIZE)
+ blkcnt++;
+ }
+
+ blk_addr = pt.start + (0x20000 / MMC_BLOCK_SIZE);
+
+ status = mmc_bread(dev, blk_addr, blkcnt, addr);
+
+ if (status == -1)
+ return -1;
+ } else if (strcmp(filename, "u-boot.bin") == 0) {
+ if (bytes > 0) {
+ blkcnt = bytes/MMC_BLOCK_SIZE;
+
+ if (bytes % MMC_BLOCK_SIZE)
+ blkcnt++;
+ } else {
+ blkcnt = RootDir->filesize3/MMC_BLOCK_SIZE;
+
+ if (RootDir->filesize3 % MMC_BLOCK_SIZE)
+ blkcnt++;
+ }
+
+ blk_addr = pt.start + (0x30000 / MMC_BLOCK_SIZE);
+
+ status = mmc_bread(dev, blk_addr, blkcnt, addr);
+
+ if (status == -1)
+ return -1;
+ } else
+ return -1;
+
+
+ return 0;
+
+}
+
+int mmc_wfs_write(unsigned long dev, unsigned long addr, char *filename, unsigned long bytes) {
+
+ disk_partition_t pt;
+ char buffer[512];
+ root_dir *RootDir = buffer;
+ unsigned long blkcnt = 0;
+ unsigned long blk_addr = 0;
+ unsigned long status = 0;
+ int i = 0;
+
+
+ Change_SD_host(dev);
+
+ if (!mmc_ready) {
+ printf("Please initial the SD/MMC first\n");
+ return -1;
+ }
+
+#if 0
+ printf("mmc_wfs_read\n");
+ printf("<dev> : 0x%x\n",dev);
+ printf("<addr> : 0x%x\n",addr);
+ printf("<filename> : %s\n",filename);
+ printf("<bytes> : 0x%x\n",bytes);
+#endif
+ get_partition_info(mmc_dev, 1, &pt);
+#if 0
+ printf("\nPartition info\n");
+ printf("offset = 0x%x\n", pt.offset);
+ printf("start = 0x%x\n", pt.start);
+ printf("size = 0x%x 0x%xMB\n", pt.size, pt.size/2048);
+ printf("blksz = 0x%x\n", pt.blksz);
+ printf("name = %s\n", &pt.name);
+ printf("type = %s\n", &pt.type);
+#endif
+
+ /*Read Root Dir*/
+ mmc_bread(dev, pt.start, 1, (unsigned long *)RootDir);
+
+ strcpy(RootDir->MagicHeader, "WMTBLS!");
+
+
+ if (strcmp(filename, "wx-load.bin") == 0) {
+ blkcnt = bytes/MMC_BLOCK_SIZE;
+
+ if (bytes % MMC_BLOCK_SIZE)
+ blkcnt++;
+
+ RootDir->filesize1 = bytes;
+
+ strcpy(RootDir->filename1, "wx-load.bin");
+
+ blk_addr = pt.start + (0x10000 / MMC_BLOCK_SIZE);
+
+ status = mmc_bwrite(dev, blk_addr, blkcnt, addr);
+
+ if (status == -1)
+ return -1;
+
+ /*Write RootDir*/
+ status = mmc_bwrite(dev, pt.start, 1, RootDir);
+ if (status == -1)
+ return -1;
+
+
+ } else if (strcmp(filename, "wmt-env.bin") == 0){
+ blkcnt = bytes/MMC_BLOCK_SIZE;
+
+ if (bytes % MMC_BLOCK_SIZE)
+ blkcnt++;
+
+ RootDir->filesize2 = bytes;
+
+ strcpy(RootDir->filename2, "wmt-env.bin");
+
+ blk_addr = pt.start + (0x20000 / MMC_BLOCK_SIZE);
+
+ status = mmc_bwrite(dev, blk_addr, blkcnt, addr);
+
+ if (status == -1)
+ return -1;
+
+ /*Write RootDir*/
+ status = mmc_bwrite(dev, pt.start, 1, RootDir);
+ if (status == -1)
+ return -1;
+ } else if (strcmp(filename, "u-boot.bin") == 0) {
+ blkcnt = bytes/MMC_BLOCK_SIZE;
+
+ if (bytes % MMC_BLOCK_SIZE)
+ blkcnt++;
+
+ RootDir->filesize3 = bytes;
+
+ strcpy(RootDir->filename3, "u-boot.bin");
+
+ blk_addr = pt.start + (0x30000 / MMC_BLOCK_SIZE);
+
+ status = mmc_bwrite(dev, blk_addr, blkcnt, addr);
+
+ if (status == -1)
+ return -1;
+
+ /*Write RootDir*/
+ status = mmc_bwrite(dev, pt.start, 1, RootDir);
+ if (status == -1)
+ return -1;
+ } else
+ return -1;
+
+
+
+#if 0
+ printf("RootDir = 0x%x\n",RootDir);
+ printf("RootDir->MagicHeader = %s\n",RootDir->MagicHeader);
+ printf("RootDir->filename1 = %s\n",RootDir->filename1);
+ printf("RootDir->filesize1 = 0x%x\n",RootDir->filesize1);
+ printf("RootDir->filename2 = %s\n",RootDir->filename2);
+ printf("RootDir->filesize2 = 0x%x\n",RootDir->filesize2);
+ printf("RootDir->filename3 = %s\n",RootDir->filename3);
+ printf("RootDir->filesize3 = 0x%x\n",RootDir->filesize3);
+#endif
+
+ return 0;
+}
+
+#endif /* CONFIG_MMC */
diff --git a/cpu/arm920t/wmt/pcinet.c b/cpu/arm920t/wmt/pcinet.c
new file mode 100755
index 0000000..2bbe52f
--- /dev/null
+++ b/cpu/arm920t/wmt/pcinet.c
@@ -0,0 +1,263 @@
+/*++
+Copyright (c) 2010 WonderMedia Technologies, Inc.
+
+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, see http://www.gnu.org/licenses/>.
+
+WonderMedia Technologies, Inc.
+10F, 529, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C.
+--*/
+
+#if !defined(__UPCI_H__)
+#include "upci.h"
+#endif
+#if !defined(__MAC_H__)
+#include "mac.h"
+#endif
+#if !defined(__PCINET_H__)
+#include "pcinet.h"
+#endif
+#if !defined(__TBIT_H__)
+#include "tbit.h"
+#endif
+
+/*--------------------- Static Definitions -------------------------*/
+
+/*--------------------- Static Classes ----------------------------*/
+
+/*--------------------- Static Variables --------------------------*/
+
+/*--------------------- Static Functions --------------------------*/
+
+/*--------------------- Export Variables --------------------------*/
+int g_IO_point = PCI_base_addr;
+int g_Mem_point = PCI_base_addr + PCI_io_range;
+
+BOOL NPCIbIsRegBitsOn(HANDLE hHandle, WORD wBusDevFunId, BYTE byRegOffset, BYTE byBits)
+{
+ BYTE byOrgData;
+
+ PCIvReadConfigB(hHandle, wBusDevFunId, byRegOffset, &byOrgData);
+ return BITbIsAllBitsOn(byOrgData, byBits);
+}
+
+BOOL NPCIbIsRegBitsOff(HANDLE hHandle, WORD wBusDevFunId, BYTE byRegOffset, BYTE byBits)
+{
+ BYTE byOrgData;
+
+ PCIvReadConfigB(hHandle, wBusDevFunId, byRegOffset, &byOrgData);
+ return BITbIsAllBitsOff(byOrgData, byBits);
+}
+
+void NPCIvRegBitsOn(HANDLE hHandle, WORD wBusDevFunId, BYTE byRegOffset, BYTE byBits)
+{
+ BYTE byOrgData;
+
+ PCIvReadConfigB(hHandle, wBusDevFunId, byRegOffset, &byOrgData);
+ PCIvWriteConfigB(hHandle, wBusDevFunId, byRegOffset, (BYTE)(byOrgData | byBits));
+}
+
+void NPCIvRegBitsOff(HANDLE hHandle, WORD wBusDevFunId, BYTE byRegOffset, BYTE byBits)
+{
+ BYTE byOrgData;
+
+ PCIvReadConfigB(hHandle, wBusDevFunId, byRegOffset, &byOrgData);
+ PCIvWriteConfigB(hHandle, wBusDevFunId, byRegOffset, (BYTE)(byOrgData & ~byBits));
+}
+
+void NPCIvReadManyConfigSpace(HANDLE hHandle, WORD wBusDevFunId, BYTE byRegOffset,
+ PBYTE pbyBuffer, WORD wCount)
+{
+ PCIvReadConfigManyBytes(hHandle, wBusDevFunId, byRegOffset, pbyBuffer, wCount);
+}
+
+void NPCIvReadRevisionId(HANDLE hHandle, WORD wBusDevFunId, PBYTE pbyRevId)
+{
+ PCIvReadConfigB(hHandle, wBusDevFunId, PCI_REG_REV_ID, pbyRevId);
+}
+
+/*
+ * Description: Read PCI information by Vendor's id and Device's id
+ *
+ * Parameters:
+ *
+ * Return Value:
+ *
+ */
+BOOL NPCIbReadDeviceInfo(HANDLE hHandle, WORD wVendorID, WORD wDeviceID, PSPciDevice pPciDevs)
+{
+ BYTE byBusNum;
+ BYTE bySlotNum;
+ BYTE byFuncNum;
+ BYTE byRevId;
+ DWORD dwIoBase;
+ DWORD dwIoSpaceRange;
+ BYTE byIrqNo;
+ DWORD dwDevVenID = MAKEDWORD(wVendorID, wDeviceID);
+
+ /* init device number to 0 */
+ pPciDevs->wDeviceNum = 0;
+ byBusNum = 0;
+ bySlotNum = 0;
+ byFuncNum = 0;
+ /* get each Bus/Device/Function no. by vendor & device id */
+ while (PCIbFindConfigDeviceInfo(dwDevVenID, &byBusNum, &bySlotNum, &byFuncNum, &byRevId,
+ &dwIoBase, &dwIoSpaceRange, &byIrqNo)) {
+ pPciDevs->awBusDevFunID[pPciDevs->wDeviceNum] =
+ MAKE_BDF_TO_WORD(byBusNum, bySlotNum, byFuncNum);
+ (pPciDevs->wDeviceNum)++;
+
+ /* increase bySlotNum or byFuncNum to do the next search */
+ /* by checking PCI header type bit 7 */
+ if (NPCIbIsRegBitsOn(
+ hHandle,
+ MAKE_BDF_TO_WORD(byBusNum, bySlotNum, 0),
+ PCI_REG_HDR_TYPE,
+ 0x80)
+ )
+ byFuncNum++;
+ else
+ bySlotNum++;
+ }
+
+ return TRUE;
+}
+
+void NPCIvInitialize(HANDLE hHandle, WORD wBusDevFunId, BYTE byRevId)
+{
+ /* PATCH.... turn this on to avoid retry forever */
+ NPCIvRegBitsOn(hHandle, wBusDevFunId, PCI_REG_MODE2, MODE2_PCEROPT);
+ /* PATCH.... */
+ /* for some legacy BIOS and OS don't open BusM */
+ /* bit in PCI configuration space. So, turn it on. */
+ NPCIvRegBitsOn(hHandle, wBusDevFunId, PCI_REG_COMMAND, COMMAND_BUSM);
+ /* PATCH.... turn this on to detect MII coding error */
+ /* NPCIvRegBitsOn(hHandle, wBusDevFunId, PCI_REG_MODE3, MODE3_MIION); */
+}
+
+/* add by kevin */
+/* search all pci devices matched vender & device ID */
+BOOL NPCIbPCIAlloc(HANDLE hHandle, WORD wVendorID, WORD wDeviceID, PSPciDevice pPciDevs)
+{
+ BYTE byBusNum;
+ BYTE bySlotNum;
+ BYTE byFuncNum;
+ BYTE byRevId;
+ DWORD dwIoBase;
+ DWORD dwIoSpaceRange;
+ BYTE byIrqNo;
+ DWORD dwDevVenID = MAKEDWORD(wVendorID, wDeviceID);
+ int i;
+ WORD command;
+ DWORD space_size;
+
+ /* init device number to 0 */
+ pPciDevs->wDeviceNum = 0;
+ byBusNum = 0;
+ bySlotNum = 0;
+ byFuncNum = 0;
+ /* get each Bus/Device/Function no. by vendor & device id */
+ while (PCIbFindConfigDeviceInfo(dwDevVenID, &byBusNum, &bySlotNum, &byFuncNum, &byRevId,
+ &dwIoBase, &dwIoSpaceRange, &byIrqNo)) {
+ pPciDevs->awBusDevFunID[pPciDevs->wDeviceNum] =
+ MAKE_BDF_TO_WORD(byBusNum, bySlotNum, byFuncNum);
+ /* disable IO/Mem accesss */
+ PCIXvReadW(pPciDevs->awBusDevFunID[pPciDevs->wDeviceNum], PCI_REG_COMMAND, &command);
+ command = (~0x3)&command;
+ PCIXvWriteW(pPciDevs->awBusDevFunID[pPciDevs->wDeviceNum], PCI_REG_COMMAND, command);
+
+ /* allocate IO or Memory space */
+ for (i = 0; i < 6; i++) {
+ /* judge whether size equals to 0 */
+ PCIXvWriteD(
+ pPciDevs->awBusDevFunID[pPciDevs->wDeviceNum],
+ PCI_REG_BAR0+i*4,
+ PCI_invalid
+ );
+ PCIXvReadD(pPciDevs->awBusDevFunID[pPciDevs->wDeviceNum],
+ PCI_REG_BAR0+i*4,
+ &space_size
+ );
+
+ if (space_size != 0) {
+ if (space_size & PCI_IO_ENABLE) {
+ /* assign IO space */
+ /* assume io space doesn't exceed 256 bytes */
+ PCIXvWriteD(
+ pPciDevs->awBusDevFunID[pPciDevs->wDeviceNum],
+ PCI_REG_BAR0+i*4,
+ g_IO_point
+ );
+ g_IO_point += PCI_io_page;
+ } else {
+ /* assign memory space */
+ /* assume mem space doesn't exceed 4k bytes */
+ PCIXvWriteD(
+ pPciDevs->awBusDevFunID[pPciDevs->wDeviceNum],
+ PCI_REG_BAR0+i*4,
+ g_Mem_point
+ );
+ g_Mem_point += PCI_memory_page;
+ }
+ }
+ }
+ /* 2.assign PCI slot interrupt */
+ /* slot 8-a:44 */
+ /* slot 9-a:45 */
+ /* slot 10-a:46 */
+ /* slot 11-a:47 */
+ if (bySlotNum == 8)
+ PCIXvWriteB(pPciDevs->awBusDevFunID[pPciDevs->wDeviceNum], PCI_REG_INT_LINE, 44);
+ else if (bySlotNum == 9)
+ PCIXvWriteB(pPciDevs->awBusDevFunID[pPciDevs->wDeviceNum], PCI_REG_INT_LINE, 45);
+ else if (bySlotNum == 0xa)
+ PCIXvWriteB(pPciDevs->awBusDevFunID[pPciDevs->wDeviceNum], PCI_REG_INT_LINE, 46);
+ else if (bySlotNum == 0xb)
+ PCIXvWriteB(pPciDevs->awBusDevFunID[pPciDevs->wDeviceNum], PCI_REG_INT_LINE, 47);
+ else
+ PCIXvWriteB(pPciDevs->awBusDevFunID[pPciDevs->wDeviceNum], PCI_REG_INT_LINE, 44);
+
+ /* enable IO/Mem accesss and PCI master */
+ PCIXvReadW(pPciDevs->awBusDevFunID[pPciDevs->wDeviceNum], PCI_REG_COMMAND, &command);
+ command |= (0x7);
+ PCIXvWriteW(pPciDevs->awBusDevFunID[pPciDevs->wDeviceNum], PCI_REG_COMMAND, command);
+
+ pPciDevs->wDeviceNum++;
+ /* increase bySlotNum or byFuncNum to do the next search */
+ /* by checking PCI header type bit 7 */
+ if (NPCIbIsRegBitsOn(
+ hHandle,
+ MAKE_BDF_TO_WORD(byBusNum, bySlotNum, 0),
+ PCI_REG_HDR_TYPE,
+ 0x80)
+ )
+ byFuncNum++;
+ else
+ bySlotNum++;
+ }
+ /* printf("Richard DBG3\n"); */
+ return TRUE;
+}
+
+void pciconfigurationdump(WORD wBusDevFunId)
+{
+ unsigned long s_c;
+
+ PCIXvReadD(wBusDevFunId, 0, &s_c);
+ printf("pci ID:%8x\n", s_c);
+ PCIXvReadD(wBusDevFunId, 4, &s_c);
+ printf("pci status and command:%8x\n", s_c);
+ PCIXvReadD(wBusDevFunId, 16, &s_c);
+ printf("pci io space:%8x\n", s_c);
+ PCIXvReadD(wBusDevFunId, 20, &s_c);
+ printf("pci mem spae:%8x\n", s_c);
+ return;
+}
diff --git a/cpu/arm920t/wmt/pcinet.h b/cpu/arm920t/wmt/pcinet.h
new file mode 100755
index 0000000..fabeabe
--- /dev/null
+++ b/cpu/arm920t/wmt/pcinet.h
@@ -0,0 +1,139 @@
+/*++
+Copyright (c) 2010 WonderMedia Technologies, Inc.
+
+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, see http://www.gnu.org/licenses/>.
+
+WonderMedia Technologies, Inc.
+10F, 529, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C.
+--*/
+
+
+#ifndef __PCINET_H__
+#define __PCINET_H__
+
+#if !defined(__TTYPE_H__)
+#include "ttype.h"
+#endif
+#if !defined(__TPCI_H__)
+#include "tpci.h"
+#endif
+
+
+/*--------------------- Export Definitions -------------------------*/
+/* #define CB_MAX_NET_DEVICE 6 // max. # of the devices */
+
+/*
+ * PCI total devices with the same Vendor id and Device id
+ */
+typedef struct tagSPciDevice {
+ WORD wDeviceNum;
+ WORD awBusDevFunID[MAX_NET_DEVICE];
+} SPciDevice, DEF * PSPciDevice;
+
+
+/*
+ * Registers in the PCI configuration space
+ */
+#define PCI_REG_MODE0 0x60
+#define PCI_REG_MODE1 0x61
+#define PCI_REG_MODE2 0x62
+#define PCI_REG_MODE3 0x63
+#define PCI_REG_DELAY_TIMER 0x64
+
+
+/*
+ * Registers for power management (offset)
+ */
+#define PCI_REG_PM_BASE 0x50
+
+#define PM_CAP_ID 0x00
+#define PM_NEXT_ITEM_PTR 0x01
+#define PM_PMC0 0x02
+#define PM_PMC1 0x03
+#define PM_PMCSR0 0x04
+#define PM_PMCSR1 0x05
+#define PM_CSR_BSE 0x06
+#define PM_DATA 0x07
+
+
+/*
+ * Bits in the COMMAND register
+ */
+#define COMMAND_BUSM 0x04
+
+/*
+ * Bits in the MODE0 register
+ */
+#define MODE0_QPKTDS 0x80
+#define MODE0_GWTHSEL 0x04
+#define MODE0_FFWHSEL 0x02
+#define MODE0_DLWHSEL 0x01
+
+/*
+ * Bits in the MODE2 register
+ */
+#define MODE2_PCEROPT 0x80
+#define MODE2_TXQ16 0x40
+#define MODE2_TCPLSOPT 0x01
+
+/*
+ * Bits in the MODE3 register
+ */
+#define MODE3_MIION 0x04
+
+/*
+ * Bits in PMCSR0 register
+ */
+#define PMCSR0_PW_STAT1 0x02
+#define PMCSR0_PW_STAT0 0x01
+
+/*
+ * Bits in PMCSR1 register
+ */
+#define PMCSR1_PME_STATUS 0x80
+#define PMCSR1_PME_EN 0x01
+
+
+/*--------------------- Export Classes ----------------------------*/
+
+/*--------------------- Export Variables --------------------------*/
+extern int g_IO_point;
+extern int g_Mem_point;
+/*--------------------- Export Functions --------------------------*/
+#ifdef __cplusplus
+extern "C" { /* Assume C declarations for C++ */
+#endif /* __cplusplus */
+
+BOOL NPCIbIsRegBitsOn(HANDLE hHandle, WORD wBusDevFunId, BYTE byRegOffset, BYTE byBits);
+BOOL NPCIbIsRegBitsOff(HANDLE hHandle, WORD wBusDevFunId, BYTE byRegOffset, BYTE byBits);
+
+void NPCIvRegBitsOn(HANDLE hHandle, WORD wBusDevFunId, BYTE byRegOffset, BYTE byBits);
+void NPCIvRegBitsOff(HANDLE hHandle, WORD wBusDevFunId, BYTE byRegOffset, BYTE byBits);
+
+void NPCIvReadManyConfigSpace(HANDLE hHandle, WORD wBusDevFunId, BYTE byRegOffset,
+ PBYTE pbyBuffer, WORD wCount);
+
+void NPCIvReadRevisionId(HANDLE hHandle, WORD wBusDevFunId, PBYTE pbyRevId);
+
+BOOL NPCIbReadDeviceInfo(HANDLE hHandle, WORD wVendorID, WORD wDeviceID, PSPciDevice pPciDevs);
+
+void NPCIvInitialize(HANDLE hHandle, WORD wBusDevFunId, BYTE byRevId);
+
+BOOL NPCIbPCIAlloc(HANDLE hHandle, WORD wVendorID, WORD wDeviceID, PSPciDevice pPciDevs);
+
+void pciconfigurationdump(WORD wBusDevFunId);
+
+#ifdef __cplusplus
+} /* End of extern "C" { */
+#endif /* __cplusplus */
+
+#endif /* __PCINET_H__ */
diff --git a/cpu/arm920t/wmt/pmc.h b/cpu/arm920t/wmt/pmc.h
new file mode 100755
index 0000000..238823d
--- /dev/null
+++ b/cpu/arm920t/wmt/pmc.h
@@ -0,0 +1,370 @@
+/*++
+Copyright (c) 2010 WonderMedia Technologies, Inc.
+
+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, see http://www.gnu.org/licenses/>.
+
+WonderMedia Technologies, Inc.
+10F, 529, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C.
+--*/
+
+#ifndef __PMC_H_
+#define __PMC_H_
+
+typedef struct _PMC_REG_ {
+ volatile unsigned int PM_Sts; /* [Rx00-03] Power Management Status Register */
+ volatile unsigned int PM_Sts1; /* [Rx04-07] Device clock update status 1 Register*/
+ volatile unsigned char Idle; /* [Rx08] IDEL Processor Request Register */
+ volatile unsigned char Resv9_0B[3]; /* [Rx09 - 0B] Reserved */
+ volatile unsigned short PU_Time_Ctrl; /* [Rx0C] Power-up Tme Control Register */
+ volatile unsigned char Resv0E_0F[2]; /* Reserved*/
+ volatile unsigned short Hib_Val; /* [Rx10 - Rx11] Hibernation Value Register */
+ volatile unsigned short Hib_Ctrl; /* [Rx12 - Rx13] Hibernation Control Register*/
+ volatile unsigned int Wakeup_Sts; /* [Rx14-17]Wake up Status register*/
+ volatile unsigned int PM_Sts2; /* [Rx18-1B] Power Management Status Register*/
+ volatile unsigned int Wakeup_Event_Enable; /* [Rx1C-1F] Wake-up Event Enable Register*/
+ volatile unsigned int Wakeup_Event_Type; /* [Rx20-23] Wake-up Event Type Register*/
+ volatile unsigned int Wakeup_CardDet_Event_Type;/* [Rx24-27] Card Detect Wake-up Event Type Register*/
+ volatile unsigned int CardDet_Sts_Int;/* [Rx28-2B] Card Detect Status And Card Detect Interrupt Register*/
+ volatile unsigned int CardReader_Debounce_Int_Type;/* [Rx2C-2F] Card Reader Attachment Debounce Control and Interrupt Type Register*/
+ volatile unsigned int Hib_Scratch0; /* [Rx30-33] Hibernate Scratch Pad Register0 */
+ volatile unsigned int Hib_Scratch1; /* [Rx34-37] Hibernate Scratch Pad Register1 */
+ volatile unsigned int Hib_Scratch2; /* [Rx38-3B] Hibernate Scratch Pad Register2 */
+ volatile unsigned int Hib_Scratch3; /* [Rx3c-3F] Hibernate Scratch Pad Register3 */
+ volatile unsigned int Hib_Scratch4; /* [Rx40-43] Hibernate Scratch Pad Register4*/
+ volatile unsigned int Hib_Scratch5; /* [Rx44-47] Hibernate Scratch Pad Register5*/
+ volatile unsigned int Hib_Scratch6; /* [Rx48-4B] Hibernate Scratch Pad Register6*/
+ volatile unsigned int Hib_Scratch7; /* [Rx4c-4F] Hibernate Scratch Pad Register7*/
+ volatile unsigned int Reset_Sts; /* [Rx50-53] Reset Status Register */
+ volatile unsigned int PB_Control; /* [Rx54-57] Power Button Control Register; */
+ volatile unsigned int AXI_LowPwr_Control; /* [Rx58-5B] AXI Low Power Interface Control Register;*/
+ volatile unsigned int Resv5c_5F[1];
+ volatile unsigned int SW_Reset_Req; /* [Rx60-63] Software Reset Request Register */
+ volatile unsigned int Resv64_7F[0x7];
+ volatile unsigned int PM_Div_Upt2_sts; /* [Rx80-83] Device clock update status 2 Register*/
+ volatile unsigned int PM_Div_Upt3_sts; /* [Rx84-87] Device clock update status 3 Register*/
+ volatile unsigned char Resv88_93[0xC];
+ volatile unsigned int RTC_Clk_Exist_Monitor; /* [Rx94-97] RTC clock exist monitor Register*/
+ volatile unsigned char Resv98_FF[0x68];
+ volatile unsigned int OS_Timer_Match0; /* [Rx100-Rx103] OS Timer Match Register0 */
+ volatile unsigned int OS_Timer_Match1; /* [Rx104-Rx107] OS Timer Match Registe1 */
+ volatile unsigned int OS_Timer_Match2; /* [Rx108-Rx10B] OS Timer Match Register2 */
+ volatile unsigned int OS_Timer_Match3; /* [Rx10C-Rx10F] OS Timer Match Register3 */
+ volatile unsigned int OS_Timer_Count; /* [Rx110-113] OS Timer Counter Register */
+ volatile unsigned int OS_Timer_Sts; /* [Rx114-117] OS Timer Status Register */
+ volatile unsigned int OS_Timer_WatchDog_Enable; /* [Rx118-Rx11B] */
+ volatile unsigned int OS_Timer_Int_Enable; /* [Rx11C-Rx11F] */
+ volatile unsigned int OS_Timer_Ctrl; /* [Rx120-Rx123] OS Timer Control Register */
+ volatile unsigned int OS_Timer_Access_Sts; /* [Rx124-Rx127] OS Timer Access Status Register */
+ volatile unsigned int Resv128_1FB[0x35];
+ volatile unsigned char Resv1FC_1FF[4];
+ volatile unsigned int PLLA; /* [Rx200-203] PLLA Multiplier and */
+ /* Range Values Register */
+ volatile unsigned int PLLB; /* [Rx204-207] PLLB Multiplier and */
+ /* Range Values Register */
+ volatile unsigned int PLLC; /* [Rx208-20B] PLLC Multiplier and */
+ /* Range Values Register */
+ volatile unsigned int PLLD; /* [Rx20C-20F] PLLD Multiplier and */
+ /* Range Values Register */
+ volatile unsigned int PLLE; /* [Rx210-213] PLLE Multiplier and Range Values Register*/
+ volatile unsigned int PLLF; /* [Rx214-217] PLLF Multiplier and Range Values Register*/
+ volatile unsigned int PLL_25; /* [Rx218-21B] PLL_25 Multiplier and Range Values Register*/
+ volatile unsigned int PLL_AUD; /* [Rx21C-21F] PLL_AUD Multiplier and Range Values Register*/
+ volatile unsigned int PLL_Rdy_Sts; /* [Rx220-223] PLL Ready Status Register*/
+ volatile unsigned int Resv224_24F[0x0B];
+ volatile unsigned int Clock_Enable0; /* [Rx250-253] Clock Enable 0 Register*/
+ volatile unsigned int Clock_Enable1; /* [Rx254-257] Clock Enable 1 Register*/
+ volatile unsigned int Clock_Enable2; /* [Rx258-25B] Clock Enable 2 Register*/
+ volatile unsigned int Clock_Enable3; /* [Rx25C-25F] Clock Enable 3 Register*/
+ volatile unsigned int Resv260_2FF[0x28];
+ volatile unsigned char ARM_Clock_Divisor; /* [Rx300] ARM Clock Divisor Register*/
+ volatile unsigned char ARM_Clock_HiPulse;
+ volatile unsigned char Resv302_303[2];
+ volatile unsigned char AHB_Clock_Divisor; /* [Rx304] AHB Clock Divisor Value Register */
+ volatile unsigned char Resv305_30B[7];
+ volatile unsigned char L2C_Clock_Divisor; /* [Rx30C] Clock Divisor Value L2C Register*/
+ volatile unsigned char L2C_Clock_HiPulse;
+ volatile unsigned char Resv30E_30F[2];
+ volatile unsigned char DDR_Clock_Divisor; /* [Rx310] DDR Memory Controller Clock */
+ volatile unsigned char Resv311_313[3];
+ volatile unsigned char SF_Clock_Divisor; /* [Rx314] Serial Flash Memory Controller */
+ volatile unsigned char SF_Clock_HiPulse; /* [Rx315] */
+ volatile unsigned char Resv316_317[2];
+ volatile unsigned char NF_Clock_Divisor; /* [Rx318] NF Clock Divisor Value Register*/
+ volatile unsigned char NF_Clock_HiPulse; /* [Rx319]*/
+ volatile unsigned char Resv31A_31B[2];
+ volatile unsigned char NOR_Clock_Divisor; /* [Rx31C] NOR Clock Divisor Value Register*/
+ volatile unsigned char NOR_Clock_HiPulse; /* [Rx31D]*/
+ volatile unsigned char Resv31E_31F[2];
+ volatile unsigned char APB_Clock_Divisor; /* [Rx320] APB Clock Divisor Value Register*/
+ volatile unsigned char Resv321_32F[15];
+ volatile unsigned char SD_Clock_Divisor; /* [Rx330] SD/MMC Clock Divisor Value Reigster*/
+ volatile unsigned char SD_Clock_HiPulse; /* [Rx331]*/
+ volatile unsigned char Resv332_333[2];
+ volatile unsigned char SD1_Clock_Divisor; /* [Rx334] SD/MMC1 Clock Divisor Value Reigster*/
+ volatile unsigned char SD1_Clock_HiPulse; /* [Rx335]*/
+ volatile unsigned char Resv336_337[2];
+ volatile unsigned char SD2_Clock_Divisor; /* [Rx338] SD/MMC2 Clock Divisor Value Reigster*/
+ volatile unsigned char SD2_Clock_HiPulse; /* [Rx339]*/
+ volatile unsigned char Resv33A_33B[2];
+ volatile unsigned char Resv33C_33F[4];
+ volatile unsigned char SPI0_Clock_Divisor; /* [Rx340] SPI0 Clock Divisor Value Register*/
+ volatile unsigned char SPI0_Clock_HiPulse; /* [Rx341] SPI0 Clock High Pulse is the Wide Pulse Register*/
+ volatile unsigned char Resv342_343[2];
+ volatile unsigned char SPI1_Clock_Divisor; /* [Rx344] SPI1 Clock Divisor Value Register*/
+ volatile unsigned char SPI1_Clock_HiPulse; /* [Rx345] SPI1 Clock High Pulse is the Wide Pulse Register*/
+ volatile unsigned char Resv346_34F[10];
+ volatile unsigned char PWM_Clock_Divisor; /* [Rx350] PWM Clock Divisor Register*/
+ volatile unsigned char PWM_Clock_HiPulse; /* [Rx351] PWM Clock High Pulse is the Wide Pulse Register*/
+ volatile unsigned char Resv352_353[2];
+ volatile unsigned char PCM_Clock_Divisor; /* [Rx354] PCM Clock Divisor Value Register*/
+ volatile unsigned char PCM_Clock_HiPulse; /* [Rx355] PCM Clock High Pulse is the Wide Pulse Register*/
+ volatile unsigned char Resv356_357[2];
+ volatile unsigned char NA0_Clock_Divisor; /* [Rx358]*/
+ volatile unsigned char NA0_Clock_HiPulse; /* [Rx359] NA0 Clock High Pulse is the Wide Pulse Register*/
+ volatile unsigned char Resv35A_35B[2];
+ volatile unsigned char NA12_Clock_Divisor; /* [Rx35C]*/
+ volatile unsigned char NA12_Clock_HiPulse; /* [Rx35D] NA12 Clock High Pulse is the Wide Pulse Register*/
+ volatile unsigned char Resv35E_367[10];
+ volatile unsigned char VDU_Clock_Divisor; /* [Rx368]*/
+ volatile unsigned char VDU_Clock_HiPulse; /* [Rx369] VDU Clock High Pulse is the Wide Pulse Register*/
+ volatile unsigned char Resv36A_36B[2];
+ volatile unsigned char DVOTV2_Clock_Divisor;/* [Rx36C]*/
+ volatile unsigned char DVOTV2_Clock_HiPulse;/* [Rx36D] DVOTV2 Clock High Pulse is the Wide Pulse Register*/
+ volatile unsigned char Resv36E_373[6];
+ volatile unsigned char AUD_Clock_Divisor; /* [Rx374] AUD Clock Divisor Value Register*/
+ volatile unsigned char AUD_Clock_HiPulse; /* [Rx375] AUD Clock High Pulse is the Wide Pulse Register*/
+ volatile unsigned char Resv376_377[2];
+ volatile unsigned char Ring1_Clock_Divisor; /* [Rx378] Ring OSC 1st divider Register*/
+ volatile unsigned char Resv379_37B[3];
+ volatile unsigned char Ring2_Clock_Divisor; /* [Rx37C] Ring OSC 2st divider Register*/
+ volatile unsigned char Resv37D_387[11];
+ volatile unsigned char MALI_Clock_Divisor; /* [Rx388]*/
+ volatile unsigned char MALI_Clock_HiPulse; /* [Rx389] MALI Clock High Pulse is the Wide Pulse Register*/
+ volatile unsigned char Resv38A_38F[6];
+ volatile unsigned char HDMI_I2C_Clock_Divisor;/* [Rx390]*/
+ volatile unsigned char HDMI_I2C_Clock_HiPulse;/* [Rx391] HDMI Clock High Pulse is the Wide Pulse Register*/
+ volatile unsigned char Resv392_393[2];
+ volatile unsigned char GENET_Clock_Divisor; /* [Rx394] GENET Clock Divisor Value Register*/
+ volatile unsigned char GENET_Clock_HiPulse; /* [Rx395]*/
+ volatile unsigned char Resv396_39F[10];
+ volatile unsigned char I2C0_Clock_Divisor; /* [Rx3A0]*/
+ volatile unsigned char I2C0_Clock_HiPulse; /* [Rx3A1] I2C0 Clock High Pulse is the Wide Pulse Register*/
+ volatile unsigned char Resv3A2_3A3[2];
+ volatile unsigned char I2C1_Clock_Divisor; /* [Rx3A4]*/
+ volatile unsigned char I2C1_Clock_HiPulse; /* [Rx3A5] I2C1 Clock High Pulse is the Wide Pulse Register*/
+ volatile unsigned char Resv3A6_3AF[10];
+ volatile unsigned char L2C_AXI_Clock_Divisor; /* [Rx3B0]*/
+ volatile unsigned char L2C_AXI_Clock_HiPulse; /* [Rx3B1] L2C_AXI Clock High Pulse is the Wide Pulse Register*/
+ volatile unsigned char Resv3B2_3BF[14];
+ volatile unsigned char L2C_PAXI_Clock_Divisor;/* [Rx3C0]*/
+ volatile unsigned char L2C_PAXI_Clock_HiPulse;/* [Rx3C1] L2C_PAXI Clock High Pulse is the Wide Pulse Register*/
+ volatile unsigned char Resv3C2_3E3[18];
+ volatile unsigned char Hz24M_Clock_Divisor; /* [Rx3C0]*/
+ volatile unsigned char Hz24M_Clock_HiPulse; /* [Rx3C1] 24MHZ Clock High Pulse is the Wide Pulse Register*/
+ volatile unsigned char Resv3E6_3EF[10];
+ volatile unsigned char L2C_RAM_Clock_Divisor; /* [Rx3F0]*/
+ volatile unsigned char L2C_RAM_Clock_HiPulse; /* [Rx3F1] L2C_RAM Clock High Pulse is the Wide Pulse Register*/
+ volatile unsigned char Resv3F2_4FF[0x10E];
+ volatile unsigned char PS_Control; /* [Rx500] 1.1.1.85 CARD, SD, CF Power Switch Control Register*/
+ volatile unsigned char Resv501[0xFF];
+ volatile unsigned int MALI_PWR_Shut_Off_CTRL_STS; /* [Rx600-603] mali power shut off control and status Register*/
+ volatile unsigned int C_M_PWR_Shut_Off_CTRL_STS; /* [Rx604-607] C&M power shut off control and status Register*/
+ volatile unsigned char Resv608_64F[0x48];
+ volatile unsigned int AXI_TO_AHB_Bridge_Pwr_Ctrl; /* [Rx650-653] AXI to AHB bridge power control and status Register*/
+ volatile unsigned int PAXI_TO_AHB_Bridge_Pwr_Ctrl;/* [Rx654-657] AXI to AHB bridge power control and status Register*/
+} PMC_REG, *PPMC_REG;
+
+/*
+ * (URRDR) Receive Data Regiser Description
+ */
+#define URRDR_PER 0x100 /* Parity Error. This bit is the same as URISR[8] */
+#define URRDR_FER 0x200 /* Frame Error. This bit is the same as URISR[9] */
+
+/*
+ * PMCS_REG PM (Current) Status Register bits definitions.
+ */
+#define PMCS_NORTC BIT0 /* RTC Clock Logic Disabled */
+#define PMCS_IDLE BIT1 /* IDLE Operation Active */
+#define PMCS_HIBER BIT2 /* Hibernation Operation Active */
+#define PMCS_ANY_CLK_DIV BIT4 /* Updating Any Clock Divisor */
+#define PMCS_ANY_PLL_MUL BIT5 /* Updating Any PLL Multiplier */
+#define PMCS_ZAC2 BIT8 /* Updating ZAC2_MA Clock Divisor */
+#define PMCS_AHB BIT9 /* Updating AHB Clock Divisor */
+#define PMCS_DSP BIT10 /* Updating DSP Clock Divisor */
+#define PMCS_LCD BIT11 /* Updating LCD Clock Divisor */
+#define PMCS_MC BIT12 /* Updating Memory Controller Clock Divisor */
+#define PMCS_CFC BIT13 /* Updating Compact Flash Controller Clock Divisor */
+#define PMCS_USB BIT14 /* Updating USB Clock Divisor */
+#define PMCS_PCM BIT15 /* Updating Pulse Code Modulation Clock Divisor */
+#define PMCS_PLLA BIT16 /* Updating PLL A Multiplier Value */
+#define PMCS_PLLB BIT17 /* Updating PLL B Multiplier Value */
+#define PMCS_PLLC BIT18 /* Updating PLL C Multiplier Value */
+#define PMCS_SF BIT19 /* Updating Serial Flash Memory Cntrlr Divisor */
+#define PMCS_PATA BIT21 /* Updating PATA Clock Divisor */
+#define PMCS_SDMMC BIT22 /* Updating SD/MMC Clock Divisor */
+#define PMCS_MSC BIT23 /* Updating MS/MSPRO Clock Divisor */
+#define PMCS_LPC BIT24 /* Updating LPC Memory Cntrlr Clock Divisor */
+#define PMCS_NAND BIT25 /* Updating NAND Clock Divisor */
+#define PMCS_SPI BIT26 /* Updating SPI Clock Divisor */
+#define PMCS_PLLD BIT27 /* Updating PLL D Multiplier Value */
+#define PMCS_BUSY 0xfffffffe
+
+/*
+ * PMIR_REG PM Idle processor Request Register bit function.
+ */
+#define PMIR_IDLE /* IDLE Processor Request Bit */
+
+
+/*
+ * PMHC_REG PM Hibernation Control Register bits functions.
+ */
+#define PMHC_SLEEP 0x03 /* A Power-on Hibernation Mode */
+#define PMHC_SUSPEND 0x01 /* A Power-off Hibernation Mode */
+#define PMHC_SHUTDOWN 0x05 /* A Power-off Hibernation Mode */
+#define PMHC_25M_OSCLR BIT8 /* 25MHz Oscillator Enable */
+
+/*
+ * PMWS_REG PM Wake-up Status register bits definitions.
+ */
+#define PMWS_WAKEMASK 0xFF /* General Purpose Wake-up Status */
+#define PMWS_PWRBUTTON BIT14 /* Power Button Wake-up Status */
+#define PMWS_RTC BIT15 /* RTC Wake-up Status */
+
+/*
+ * PMWE_REG PM Wake-up event Enable Register bits functions.
+ */
+#define PMWE_WAKEMASK 0xFF /* General Purpose Wake-up Enable */
+#define PMWE_WAKEUP(x) (BIT0 << ((x) & 0x7)) /* Genaral Wake-up 0-7 Enable */
+#define PMWE_RTC BIT15 /* RTC Wake-up Enable */
+
+/*
+ * PMWT_REG PM Wake-up event Type Register bits functions.
+ */
+#define PMWT_ZERO 0x00 /* Wake-up signal is a zero */
+#define PMWT_ONE 0x01 /* Wake-up signal is a one */
+#define PMWT_FALLING 0x02 /* Wake-up signal generates a falling edge */
+#define PMWT_RISING 0x03 /* Wake-up signal generates a rising edge */
+#define PMWT_EDGE 0x04 /* Wake-up signal generates an edge */
+
+#define PMWT_TYPEMASK 0xFF /* Wake-up event Type Mask */
+
+/* General Purpose Wake-up 0 Type bits */
+#define PMWT_WAKEUP0(x) (((x) & PMWT_TYPEMASK) << 0)
+/* General Purpose Wake-up 1 Type bits */
+#define PMWT_WAKEUP1(x) (((x) & PMWT_TYPEMASK) << 4)
+/* General Purpose Wake-up 2 Type bits */
+#define PMWT_WAKEUP2(x) (((x) & PMWT_TYPEMASK) << 8)
+/* General Purpose Wake-up 3 Type bits */
+#define PMWT_WAKEUP3(x) (((x) & PMWT_TYPEMASK) << 12)
+/* General Purpose Wake-up 4 Type bits */
+#define PMWT_WAKEUP4(x) (((x) & PMWT_TYPEMASK) << 16)
+/* General Purpose Wake-up 5 Type bits */
+#define PMWT_WAKEUP5(x) (((x) & PMWT_TYPEMASK) << 20)
+/* General Purpose Wake-up 6 Type bits */
+#define PMWT_WAKEUP6(x) (((x) & PMWT_TYPEMASK) << 24)
+/* General Purpose Wake-up 7 Type bits */
+#define PMWT_WAKEUP7(x) (((x) & PMWT_TYPEMASK) << 28)
+/* Max wakeup source number */
+#define PMWT_WAKEUPMASK 0x07
+
+#define PMWT_WAKEUP(src, type) ((type & PMWT_TYPEMASK) << ((src & PMWT_WAKEUPMASK) * 4))
+
+/*
+ * PMRS_REG PM Reset Status Register bits definitions.
+ */
+#define PMRS_PMR BIT0 /* Power Managment Reset */
+#define PMRS_IOR BIT1 /* I/O normal power Reset */
+#define PMRS_HBR BIT2 /* HiBernation Reset */
+#define PMRS_WDR BIT3 /* WatchDog Reset */
+#define PMRS_SWR BIT4 /* SoftWare Reset */
+#define PMRS_SHR BIT5 /* Shutdown Reset */
+#define PMRS_PGR BIT6 /* Power good reset */
+/* Bits 7-31: Reserved */
+
+/*
+ * PMPB_REG PM Power Button Control Register
+ */
+#define PMPB_SOFTPWR BIT0 /* Soft Power Enable */
+/* Bits 1-31: Reserved */
+
+/*
+ * PMSR_REG PM Software Reset request Register bit function.
+ */
+#define PMSR_SWR BIT0 /* SoftWare Reset request */
+/* Bits 1-31: Reserved */
+
+/*
+ * PMPATA_REG PM PATA Interface Drive Strength Register (8-bit Register)
+ */
+#define PMPATA_ONETHIRD 0x00 /* One-third Drive Strength */
+#define PMPATA_ONEHALF 0x01 /* One-half Drive Strength */
+#define PMPATA_TWOTHIRD 0x02 /* Two-third Drive Strength */
+#define PMPATA_FULL 0x03 /* Full Drive Strength */
+#define PMSR_SWR BIT0 /* SoftWare Reset request */
+/* Bits 2-7: Reserved */
+
+/*
+ * OSTS_REG OS Timer Status Register bits definitions.
+ */
+#define OSTS_M0 BIT0 /* OS Timer 0 Match detected */
+#define OSTS_M1 BIT1 /* OS Timer 1 Match detected */
+#define OSTS_M2 BIT2 /* OS Timer 2 Match detected */
+#define OSTS_M3 BIT3 /* OS Timer 3 Match detected */
+/* Bits 4-31: Reserved */
+
+/*
+ * OSTW_REG OS Timer Watchdog enable Register bit function.
+ */
+#define OSTW_WE BIT0 /* OS Timer Channel 0 Watchdog Enable */
+/* Bits 1-31: Reserved */
+
+/*
+ * OSTI_REG OS Timer Interrupt enable Register bits functions.
+ */
+#define OSTI_E0 BIT0 /* OS Timer Channel 0 Interrupt Enable */
+#define OSTI_E1 BIT1 /* OS Timer Channel 0 Interrupt Enable */
+#define OSTI_E2 BIT2 /* OS Timer Channel 0 Interrupt Enable */
+#define OSTI_E3 BIT3 /* OS Timer Channel 0 Interrupt Enable */
+
+/* Bits 4-31: Reserved */
+/*
+ * OSTC_REG OS Timer Control Register bits functions.
+ */
+#define OSTC_ENABLE BIT0 /* OS Timer Enable bit */
+#define OSTC_RDREQ BIT1 /* OS Timer Read Count Request bit */
+/* Bits 2-31: Reserved */
+
+/*
+ * OSTA_REG OS Timer Access status Register bits definitions.
+ */
+#define OSTA_MWA0 BIT0 /* OS Timer Match 0 Write Active */
+#define OSTA_MWA1 BIT1 /* OS Timer Match 1 Write Active */
+#define OSTA_MWA2 BIT2 /* OS Timer Match 2 Write Active */
+#define OSTA_MWA3 BIT3 /* OS Timer Match 3 Write Active */
+#define OSTA_CWA BIT4 /* OS Timer Count Write Active */
+#define OSTA_RCA BIT5 /* OS Timer Read Count Active */
+/* Bits 6-31: Reserved */
+
+/*
+ * PMMISC_REG PM Miscellaneous Clock Controls Register
+ */
+#define PMMISC_24MHZ BIT0 /* 24MHz Clock Source */
+/* Bits 1-31: Reserved */
+
+/*
+ * Miscellaneous definitions
+ */
+#define __OST_BASE 0xD8130100 /* OS Timers base address */
+#define OST_MAX_CHANNEL 4 /* Four channels OS Timer */
+/* #define PMC_MAX_WAKEUP 9 // Wakeup source number */
+/* // 8 general purpose + 1 RTC */
+
+#endif /* __PMC_H_ */
diff --git a/cpu/arm920t/wmt/proto.h b/cpu/arm920t/wmt/proto.h
new file mode 100755
index 0000000..d0b9ef7
--- /dev/null
+++ b/cpu/arm920t/wmt/proto.h
@@ -0,0 +1,92 @@
+/*++
+Copyright (c) 2010 WonderMedia Technologies, Inc.
+
+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, see http://www.gnu.org/licenses/>.
+
+WonderMedia Technologies, Inc.
+10F, 529, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C.
+--*/
+
+#ifndef __PROTO_H__
+#define __PROTO_H__
+
+#if !defined(__TTYPE_H__)
+#include "ttype.h"
+#endif
+#if !defined(__ADAPTER_H__)
+#include "adapter.h"
+#endif
+
+#define HW_8021PQ_TAG TCR0_VETAG
+#define HW_IP_CHECKSUM TCR0_IPCK
+#define HW_UDP_CHECKSUM TCR0_UDPCK
+#define HW_TCP_CHECKSUM TCR0_TCPCK
+
+/*--------------------- Export Definitions -------------------------*/
+/*
+ * Protocol buffer ring
+ */
+typedef struct tagSProtocolBuffer {
+
+ UINT uProtoIndex; /* protocol index */
+
+ int idxRxBufHead;
+ int idxRxBufTail;
+ PBYTE apbyRxBuffer[CB_MAX_RD_NUM];
+ UINT auRxBufLength[CB_MAX_RD_NUM];
+ BOOL abRxBufOccupied[CB_MAX_RD_NUM];
+
+ /* for pingpong test */
+ BYTE abyDstAddr[U_ETHER_ADDR_LEN];
+ BYTE abySrcAddr[U_ETHER_ADDR_LEN];
+ DWORD dwSerialNo;
+ BYTE byDataSeed;
+
+} SProtocolBuffer, DEF * PSProtocolBuffer;
+
+
+/*--------------------- Export Classes ----------------------------*/
+
+/*--------------------- Export Variables --------------------------*/
+extern SProtocolBuffer sg_aGProBuf[MAX_NET_DEVICE];
+
+/*--------------------- Export Functions --------------------------*/
+#ifdef __cplusplus
+extern "C" { /* Assume C declarations for C++ */
+#endif /* __cplusplus */
+
+
+BOOL GPRObDriverSend(PSAdapterInfo pAdapter, PBYTE pbyPacket, UINT uPktLen, BYTE byTxQue);
+BOOL GPRObDriverSendEx(PSAdapterInfo pAdapter, BYTE byTxQue, WORD wVID,
+ BYTE byPri, BYTE byHwOpt, PBYTE pbyPacket, UINT uPktLen);
+BOOL GPRObProtocolReceive(PSAdapterInfo pAdapter, PBYTE *ppbyPacket, PUINT puPktLen);
+VOID GPROvProtocolReturnPacket(PSAdapterInfo pAdapter);
+
+BOOL GPRObProtocolConstruct(PSAdapterInfo pAdapter);
+VOID GPROvProtocolDestruct(PSAdapterInfo pAdapter);
+
+VOID GPROvPrepareTxPacketEx(PSAdapterInfo pAdapter, BYTE byTxQue, UINT uIdx, UINT uNumSeg);
+
+VOID GPROvDoTransmitSinglePacket(PSAdapterInfo pAdapter, BYTE byTxQue);
+
+VOID GPROvDoTransmitEx(PSAdapterInfo pAdapter, BYTE byTxQue);
+
+/* VOID vSetBit(PDWORD pdwTD0); */
+
+#ifdef __cplusplus
+} /* End of extern "C" { */
+#endif /* __cplusplus */
+
+#endif /* __PROTO_H__ */
+
+
+
diff --git a/cpu/arm920t/wmt/read me.txt b/cpu/arm920t/wmt/read me.txt
new file mode 100755
index 0000000..ec68441
--- /dev/null
+++ b/cpu/arm920t/wmt/read me.txt
@@ -0,0 +1,29 @@
+Date :2007/01/25
+Function :U-boot ethernet driver
+1.eth_init() :ok!have fixed the bug of reallocation of memory
+2.eth_tx() :ok!
+3.eth_rx() :ok!
+3.mac_halt() :ok!equal adapteshutdown()
+4.Mii_read() :not finished yet!
+5.Mii_write():not finished yet!
+6.Original file in mac are moved to wmt and makefile is modifed
+7.output message is omitted
+-------------------------------------------------------------------------------------------
+Date :2007/01/25
+Function :U-boot ethernet driver
+1.eth_init() :ok!have fixed the bug of reallocation of memory
+2.eth_tx() :ok!
+3.eth_rx() :ok!
+3.mac_halt() :ok!equal adapteshutdown()
+4.Mii_read() :not finished yet!
+5.Mii_write():not finished yet!
+--------------------------------------------------------------------------------------------
+Date :2007/01/24
+Function :U-boot ethernet driver
+1.eth_init() :ok!but it will reallocate memory and cause procedure not to go further
+2.eth_tx() :ok!
+3.eth_rx() :ok!
+3.mac_halt() :ok!do nothing!because halt will be processed before eth_init()
+4.Mii_read() :not finished yet!
+5.Mii_write():not finished yet!
+ \ No newline at end of file
diff --git a/cpu/arm920t/wmt/sdc.h b/cpu/arm920t/wmt/sdc.h
new file mode 100755
index 0000000..b42dee5
--- /dev/null
+++ b/cpu/arm920t/wmt/sdc.h
@@ -0,0 +1,508 @@
+/*++
+Copyright (c) 2010 WonderMedia Technologies, Inc.
+
+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, see http://www.gnu.org/licenses/>.
+
+WonderMedia Technologies, Inc.
+10F, 529, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C.
+--*/
+
+#ifndef __SDC_H__
+#define __SDC_H__
+
+#define SD_FALSE 0
+#define SD_TRUE 1
+
+//SD command definition
+
+#define GO_IDLE_STATE 0
+#define SEND_OP_COND 1 //for MMC
+#define ALL_SEND_CID 2
+#define SEND_RELATIVE_ADDR 3
+#define SET_RELATIVE_ADDR 3 //for MMC1
+#define SET_DSR 4
+#define SELECT_DESELECT_CARD 7
+#define SEND_IF_COND 8 //for SD2.0 2006/01/20 janshiue
+#define SEND_EXT_CSD 8 //for MMC
+#define SEND_CSD 9
+#define SEND_CID 10
+//#define READ_DAT_UNTIL_STOP 11
+#define STOP_TRANSMISSION 12
+#define SEND_STATUS 13
+//#define SET_BUS_WIDTH_REGISTER 14
+#define GO_INACTIVE_STATE 15
+#define SET_BLOCKLEN 16
+#define READ_SINGLE_BLOCK 17
+#define READ_MULTIPLE_BLOCK 18
+//#define WRITE_DAT_UNTIL_STOP 20
+#define WRITE_SINGLE_BLOCK 24
+#define WRITE_MULTIPLE_BLOCK 25
+//#define PROGRAM_CID 26
+#define PROGRAM_CSD 27
+#define SET_WRITE_PROT 28
+#define CLR_WRITE_PROT 29
+#define SEND_WRITE_PROT 30
+#define ERASE_START 32
+#define ERASE_END 33
+//#define UNTAG_SECTOR 34
+//#define TAG_ERASE_GROUP_START 35
+//#define TAG_ERASE_GROUP_END 36
+//#define UNTAG_ERASE_GROUP 37
+#define ERASE_GO 38
+//for SPI mode
+#define READ_OCR 58 //for SPI
+#define CRC_ON_OFF 59
+#define APP_CMD 55
+//APP command
+#define SET_BUS_WIDTH 6
+#define SD_STATUS 13
+#define SD_NUM_WR_BLOCKS 22
+#define SD_WR_BLK_ERASE_COUNT 23
+#define SD_APP_OP_COND 41
+#define SD_SET_CLR_CARD_DETECT 42
+#define SD_SEND_SCR 51
+
+#define SWITCH_MMC 6
+// SD Response types
+#define R0 0 // NONE response
+#define R1 1 // Basic response format
+#define R2 2 // R2 response. Used by ALL_SEND_CID(CMD2),
+ // SEND_CID(CMD10) and SEND_CSD(CMD9)
+#define R3 3 // R3 response. Used by SEND_APP_OP_COND(ACMD41)
+#define R6 6 // R6 response. Used by SEND_RELATIVE_ADDR(CMD3)
+#define R1b 9
+
+//bit definition for SD controller register
+
+// 0x0 Control register
+#define FIFO_RESET 0x08
+#define CMD_START 0x01
+#define CMD_READ 0x00
+#define CMD_WRITE 0x04
+#define CMD_SWRITE 0x10
+#define CMD_SREAD 0x20
+#define CMD_MWRITE 0x30
+#define CMD_MREAD 0x40
+
+//0x08 BusMode register
+#define SOFT_RESET 0x80
+#define SD_POWER 0x40
+#define SPI_CS 0x20
+#define SD_OFF 0x10
+#define FOURBIT_MODE 0x02
+#define ONEBIT_MODE 0xFD
+#define SPI_MODE 0x01
+#define SD_MODE 0x00
+#define EIGHTBIT_MODE 0x04
+
+//0x0C BlkLen
+#define INT_ENABLE 0x80
+#define DATA3_CD 0x40
+#define GPI_CD 0x20
+#define CD_POL_HIGH 0x10
+#define CRCERR_ABORT 0x08 //abort multiple-blk-transfer when CRC-Err
+
+
+//0x24 IntMask0
+#define DI_INT_EN 0x80
+#define CD_INT_EN 0x40
+#define BLK_TRAN_DONE_INT_EN 0x20
+#define MBLK_TRAN_DONE_INT_EN 0x10
+
+//0x25 IntMask0
+#define WCRC_ERR_INT_EN 0x80
+#define RCRC_ERR_INT_EN 0x40
+#define RESCRC_ERR_INT_EN 0x20
+#define DATA_TOUT_INT_EN 0x10
+#define MBLK_AUTO_STOP_INT_EN 0x08
+#define CMD_RES_TOUT_INT_EN 0x04
+#define CMD_RES_TRAN_DONE_INT_EN 0x02
+
+//0x28 Status0 register
+#define DEVICE_INS 0x80
+#define CARD_DETECT 0x40
+#define BLK_DONE 0x20
+#define MBLK_DONE 0x10
+#define CD_GPI 0x08
+#define CD_DATA3 0x04
+#define Write_Protect 0x02
+
+
+//0x29 Status1 register
+#define WCRC_ERR 0x80
+#define RCRC_ERR 0x40
+#define RSP_CRC_ERR 0x20
+#define DATA_TIMEOUT 0x10
+#define AUTOSTOP_DONE 0x08
+#define RSP_TIMEOUT 0x04
+#define CMDRSP_DONE 0x02
+#define SDIO_INT 0x01
+
+//0x2A Status2 register
+#define DIS_FORCECLK 0x80
+#define DATARSP_BUSY 0x20
+#define CMD_RES_BUSY 0x10
+
+//0x30 Clock register
+#define Clk_375 0x00
+#define Clk_10 0x01
+#define Clk_12 0x02
+#define Clk_15 0x03
+#define Clk_20 0x04
+#define Clk_24 0x05
+#define Clk_30 0x06
+#define Clk_40 0x07
+#define Clk_48 0x08
+
+#define SD_Clk_Auto 0
+#define SD_Clk_15MHz 1
+#define SD_Clk_20MHz 2
+#define SD_Clk_25MHz 3
+#define SD_Clk_33MHz 4
+#define SD_Clk_40MHz 5
+#define SD_Clk_44MHz 6
+#define SD_Clk_50MHz 7
+#define SD_Clk_400KHz 8
+
+
+//0x34 Extension Control register
+#define ArgShift 0x02
+#define AutoStop 0x01
+
+//return sdstatus
+#define CMD_OK 0x00
+#define CMDRSP_TOUT 0x01
+#define RSP_CRCERR 0x02
+#define APPCMD_FAIL 0x03
+#define DATA_TOUT 0x04
+#define WRITE_CRCERR 0x05
+#define READ_CRCERR 0x06
+#define TYPE_UNKNOWN 0x07
+#define NOCARD_INSERT 0x08
+#define POWER_FAIL 0x09
+#define READ_CID_ERR 0x0a
+#define READ_RCA_ERR 0x0b
+#define SET_RCA_ERR 0x0c
+#define READ_CSD_ERR 0x0d
+#define SELECT_CARD_ERR 0x0e
+#define READ_SCR_ERR 0x0f
+#define SET_BUSWIDTH_ERR 0x10
+#define SET_BLKLEN_ERR 0x11
+#define STOP_FAIL 0x12
+#define MBLK_FAIL 0x13
+#define TURE_T 0x14
+#define FALSE_F 0x15
+
+#define SWITCH_ERR 0x14
+#define SD1_0 0x00
+#define SD1_1 0x01
+#define SD2_0 0x02
+
+#define MMC1_12 0x00
+#define MMC1_4 0x01
+#define MMC2_02 0x02
+#define MMC3_123 0x03
+#define MMC4_01 0x04
+
+#define HostCapacitySupport 0x40
+#define StandardCapacity 0x00
+#define HighCapacity 0x01
+
+#define MMC_BLOCK_SIZE 512
+#define CFG_MMC_BASE 0xF0000000
+
+//SD DMA channel control registers -- CTR
+
+/* Reserved [07:05] */
+#define SD_DMA_CTR_SW_REQ_EN 0x10 /* [04:04] */
+#define SD_DMA_CTR_SW_REQ_DIS 0x00
+
+/* Reserved [03:01] */
+#define SD_DMA_CTR_CH_EN 0x01 /* [00:00] */
+#define SD_DMA_CTR_CH_DIS 0x00 /* [00:00] */
+
+//SD DMA channel status registers -- CSR
+#define SD_DMA_CSR_DMA_REQ 0x80 /* [07:07] */
+/* Reserved [06:04] */
+#define SD_DMA_CSR_FIFO_EMPTY_INT 0x08 /* [03:03] */
+#define SD_DMA_CSR_FIFO_EMPTY_INT_WRITE_CLEAR 0x08 /* [03:03] */
+#define SD_DMA_CSR_AHB_BUS_ERR 0x04 /* [02:02] */
+#define SD_DMA_CSR_AHB_BUS_ERR_WRITE_CLEAR 0x04 /* [02:02] */
+/* For USB use [01:01] */
+#define SD_DMA_CSR_TC 0x01 /* [00:00] */
+#define SD_DMA_CSR_TC_WRITE_CLEAR 0x01
+
+#define SD_DMA_CSR_ALL_SET_CLEAR 0x0F
+
+//SD DMA global control registers -- GCR
+
+/* Reserved [31:25] */
+#define SD_DMA_GCR_MANUAL_FLUSH_EN 0x01000000 /* [24:24] */
+#define SD_DMA_GCR_MANUAL_FLUAH_DIS 0x00000000 /* [24:24] */
+/* Reserved [23:17] */
+#define SD_DMA_GCR_FLUSH_FIFO 0x00010000 /* [16:16] */
+#define SD_DMA_GCR__FLUSH_SELF_CLEAR 0x00000000 /* [16:16] */
+/* Reserved [15:9] */
+#define SD_DMA_GCR_GINT_EN 0x00000100 /* [08:08] */
+#define SD_DMA_GCR_GINT_DIS 0x00000000 /* [08:08] */
+/* Reserved [07:01] */
+#define SD_DMA_GCR_GDMA_EN 0x00000001 /* [00:00] */
+#define SD_DMA_GCR_GDMA_DIS 0x00000000 /* [00:00] */
+
+/*
+ * SD PDMA
+ */
+#define SD_PDMA_BASE_ADDR 0xD800A100
+#define SD_DESC_BASE_ADDR 0x00d00000
+struct _SD_PDMA_REG_ {
+ volatile unsigned long DMA_GCR; /* Rx00 */
+ volatile unsigned long DMA_IER; /* Rx04 */
+ volatile unsigned long DMA_ISR; /* Rx08 */
+ volatile unsigned long *DMA_DESPR; /* Rx0C */
+ volatile unsigned long DMA_RBR; /* Rx10 */
+ volatile unsigned long DMA_DAR; /* Rx14 */
+ volatile unsigned long DMA_BAR; /* Rx18 */
+ volatile unsigned long DMA_CPR; /* Rx1C */
+ volatile unsigned long DMA_CCR; /* RX20 */
+ volatile unsigned long resv[5]; /* RX2C-3C */
+};
+//} SD_PDMA_REG, *PSD_PDMA_REG;
+
+/*
+ * SD PDMA - DMA_GCR : DMA Global Control Register
+ */
+#define SD_PDMA_GCR_DMA_EN 0x00000001 /* [0] -- DMA controller enable */
+#define SD_PDMA_GCR_SOFTRESET 0x00000100 /* [8] -- Software rest */
+
+/*
+ * SD PDMA - DMA_IER : DMA Interrupt Enable Register
+ */
+#define SD_PDMA_IER_INT_EN 0x00000001 /* [0] -- DMA interrupt enable */
+/*
+ * SD PDMA - DMA_ISR : DMA Interrupt Status Register
+ */
+#define SD_PDMA_IER_INT_STS 0x00000001 /* [0] -- DMA interrupt status */
+/*
+ * SD PDMA - DMA_DESPR : DMA Descriptor base address Pointer Register
+ */
+
+/*
+ * SD PDMA - DMA_RBR : DMA Residual Bytes Register
+ */
+#define SD_PDMA_RBR_End 0x80000000 /* [0] -- DMA interrupt status */
+#define SD_PDMA_RBR_Format 0x40000000 /* [0] -- DMA interrupt status */
+/*
+ * SD PDMA - DMA_DAR : DMA Data Address Register
+ */
+
+/*
+ * SD PDMA - DMA_BAR : DMA Rbanch Address Register
+ */
+
+/*
+ * SD PDMA - DMA_CPR : DMA Command Pointer Register
+ */
+
+/*
+ * SD PDMA - DMA_CCR : DMAContext Control Register for Channel 0
+ */
+#define SD_PDMA_READ 0x00
+#define SD_PDMA_WRITE 0x01
+#define SD_PDMA_CCR_RUN 0x00000080
+#define SD_PDMA_CCR_IF_to_peripheral 0x00000000
+#define SD_PDMA_CCR_peripheral_to_IF 0x00400000
+#define SD_PDMA_CCR_EvtCode 0x0000000f
+#define SD_PDMA_CCR_Evt_no_status 0x00000000
+#define SD_PDMA_CCR_Evt_ff_underrun 0x00000001
+#define SD_PDMA_CCR_Evt_ff_overrun 0x00000002
+#define SD_PDMA_CCR_Evt_desp_read 0x00000003
+#define SD_PDMA_CCR_Evt_data_rw 0x00000004
+#define SD_PDMA_CCR_Evt_early_end 0x00000005
+#define SD_PDMA_CCR_Evt_success 0x0000000f
+
+/*
+ * PDMA Descriptor short
+ */
+struct _SD_PDMA_DESC_S{
+ unsigned long volatile ReqCount:16; /* bit 0 -15 -Request count */
+ unsigned long volatile i:1; /* bit 16 -interrupt */
+ unsigned long volatile reserve:13; /* bit 17-29 -reserved */
+ unsigned long volatile format:1; /* bit 30 -The descriptor format */
+ unsigned long volatile end:1; /* bit 31 -End flag of descriptor list*/
+ unsigned long volatile *DataBufferAddr; /* bit 31 -Data Buffer address */
+};//__attribute__((packed)); /*mvl tool chain can't uas __attribute__((packed))*/
+
+/*
+ * PDMA Descriptor long
+ */
+struct _SD_PDMA_DESC_L{
+ unsigned long volatile ReqCount:16; /* bit 0 -15 -Request count */
+ unsigned long volatile i:1; /* bit 16 -interrupt */
+ unsigned long volatile reserve:13; /* bit 17-29 -reserved */
+ unsigned long volatile format:1; /* bit 30 -The descriptor format */
+ unsigned long volatile end:1; /* bit 31 -End flag of descriptor list*/
+ unsigned long volatile *DataBufferAddr; /* bit 31-0 -Data Buffer address */
+ unsigned long volatile *BranchAddr; /* bit 31-2 -Descriptor Branch address */
+ unsigned long volatile reserve0; /* bit 31-0 -reserved */
+};//__attribute__((packed));
+
+//SD card related information
+typedef struct sd_info_s {
+ unsigned char RCAHi;
+ unsigned char RCALo;
+ unsigned long SDCard_Size;
+ unsigned char MMC_Card;
+ unsigned char SD_Card;
+ unsigned char SD_IO_Card;
+ unsigned char InitOK;
+ unsigned char CardStateChange;
+ unsigned char CardInsert;
+ unsigned char CardRemove;
+ unsigned char SDVersion;
+ unsigned char CardCapacityStatus;
+ unsigned char MMCMaxClockRate;
+ unsigned char HighSpeedSupport;
+ unsigned char MMCVersion;
+ unsigned char ocr[4];
+ unsigned char cid[16];
+ unsigned char csd[16];
+ unsigned char ext_csd[512];
+ unsigned char scr[8];
+ unsigned char CtrlID;
+ unsigned long RCA;
+ unsigned long strapping;
+} sd_info_t;
+
+/*SDMMC control registers.*/
+typedef struct{
+ volatile unsigned char ctlr; /*Control Register*/
+ volatile unsigned char cmdi; /*Command Index Register*/
+ volatile unsigned char respt; /*Response Type Register*/
+ volatile unsigned char Reserved1; /*Reserved1*/
+ volatile unsigned char cmdarg0; /*Command Argument Register 0x03*/
+ volatile unsigned char cmdarg1; /*Command Argument Register 0x04*/
+ volatile unsigned char cmdarg2; /*Command Argument Register 0x05*/
+ volatile unsigned char cmdarg3; /*Command Argument Register 0x06*/
+ volatile unsigned char busm; /*Bus Mode Register*/
+ volatile unsigned char Reserved2[3]; /*Reserved2*/
+ volatile unsigned short blklen; /*Block Length Register*/
+ volatile unsigned short blkcnt; /*Block Count Register*/
+ volatile unsigned char resr[16]; /*Response Register*/
+ volatile unsigned short cbc; /*Current Block Count*/
+ volatile unsigned short Reserved3; /*Reserved3*/
+ volatile unsigned char imr0; /*Interrupt Mask Register 0*/
+ volatile unsigned char imr1; /*Interrupt Mask Register 1*/
+ volatile unsigned char Reserved4[2]; /*Reserved3*/
+ volatile unsigned char str0; /*SD Status Register 0*/
+ volatile unsigned char str1; /*SD Status Register 1*/
+ volatile unsigned char str2; /*SD Status Register 2*/
+ volatile unsigned char str3; /*SD Status Register 3 (SPI Data Error)*/
+ volatile unsigned char rtor; /*Response Time Out Register*/
+ volatile unsigned char Reserved5[3]; /*Reserved4*/
+ volatile unsigned long Reserved6; /*Reserved5*/
+ volatile unsigned char extctl; /*Extend Control Register*/
+ volatile unsigned char Reserved7[3]; /*Reserved6*/
+ volatile unsigned short sblklen; /*Shadowed Block Length Register*/
+ volatile unsigned short Reserved8; /*Reserved7*/
+ volatile unsigned short timeval; /*Timer Value Register*/
+}
+WMT_SDMMC_REG, *PWMT_SDMMC_REG;
+
+
+
+/*GPIO*/
+typedef struct _GPIO_REG_
+{
+ volatile unsigned long CTRL_KPAD_MPGTS_ROM; // [Rx00] GPIO Enable Control Register for Kpad, Mpeg-TS, CEN_SEEROM
+ volatile unsigned long CTRL_DVI; // [Rx04] GPIO Enable Control Register for DVI Signal
+ volatile unsigned long CTRL_CF; // [Rx08] GPIO Enable Control Register for CF
+ volatile unsigned long CTRL_NF; // [Rx0C] GPIO Enable Control Register for NF
+ volatile unsigned long CTRL_PCIAD; // [Rx10] GPIO Enable Control for PCI AD BUS
+ volatile unsigned long CTRL_PCI; // [Rx14] GPIO Eanble Control for Non PCI AD BUS
+ volatile unsigned long CTRL_LCD_SPDIF; // [Rx18] GPIO Enable Control for LCD, SPDIF
+ volatile unsigned long RESV_1C; // [Rx1C]
+
+ volatile unsigned long OC_KPAD_MPGTS_ROM; // [Rx20] GPIO Output Control Register for Kpad, Mpeg-TS, CEN_SEEROM
+ volatile unsigned long OC_DVI; // [Rx24] GPIO Output Control Register for DVI Signal
+ volatile unsigned long OC_CF; // [Rx28] GPIO Output Control Register for CF
+ volatile unsigned long OC_NF; // [Rx2C] GPIO Output Control Register for NF
+ volatile unsigned long OC_PCIAD; // [Rx30] GPIO Output Control Register for PCI AD BUS
+ volatile unsigned long OC_PCI; // [Rx34] GPIO Output Control Register for Non PCI AD BUS
+ volatile unsigned long OC_LCD_SPDIF; // [Rx38] GPIO Output Control Register for LCD, SPDIF
+ volatile unsigned long RESV_3C; // [Rx3C]
+
+ volatile unsigned long OD_KPAD_MPGTS_ROM; // [Rx40] GPIO Output Data Register for Kpad, Mpeg-TS, CEN_SEEROM
+ volatile unsigned long OD_DVI; // [Rx44] GPIO Output Data Register for DVI Signal
+ volatile unsigned long OD_CF; // [Rx44] GPIO Output Data Register for CF
+ volatile unsigned long OD_NF; // [Rx4C] GPIO Output Data Register for NF
+ volatile unsigned long OD_PCIAD; // [Rx50] GPIO Output Data Register for PCIAD
+ volatile unsigned long OD_PCI; // [Rx54] GPIO Output Data Register for Non PCI AD BUS
+ volatile unsigned long OD_LCD_SPDIF; // [Rx58] GPIO Output Data Register for LCD, SPDIF
+ volatile unsigned long RESV_5C; // [Rx5C]
+
+ volatile unsigned long ID_KPAD_MPGTS_ROM; // [Rx60] GPIO Input Data Register for Kpad, Mpeg-TS, CEN_SEEROM
+ volatile unsigned long ID_DVI; // [Rx64] GPIO Input Data Register for DVI Signal
+ volatile unsigned long ID_CF; // [Rx68] GPIO Input Data Register for CF
+ volatile unsigned long ID_NF; // [Rx6C] GPIO Input Data Register for NF
+ volatile unsigned long ID_PCIAD; // [Rx70] GPIO Input Data Register for PCIAD
+ volatile unsigned long ID_PCI; // [Rx74] GPIO Input Data Register for Non PCI AD BUS
+ volatile unsigned long ID_LCD_SPDIF; // [Rx78] GPIO Input Data Register for LCD, SPDIF
+ volatile unsigned long RESV_7C; // [Rx7C]
+
+ volatile unsigned long RESV_80[0x20]; // [Rx80-RxFF]
+
+ volatile unsigned long STRAP_STS1; // [Rx100] Strapping Option Status Register1
+ volatile unsigned long STRAP_STS2; // [Rx104] Strapping Option Status Register2
+ volatile unsigned long AHB_CTRL; // [Rx108] AHB Control Register
+ volatile unsigned long RESV_10C[0x3D]; // [Rx10C-Rx1FF]
+
+ volatile unsigned long PIN_MULTI; // [Rx200] Pin Multiplexing
+ volatile unsigned long RESV_204[0x3]; // [Rx204-Rx20F]
+ volatile unsigned long PCI_DELAY_TEST; // [Rx210]
+ volatile unsigned long PCI_RESET; // [Rx214]
+ volatile unsigned long RESV_218[2]; // [Rx218 - Rx21F]
+ volatile unsigned long PCI_1X_DELAY; // [Rx220]
+ volatile unsigned long PCI_2X_DELAY; // [Rx224]
+ volatile unsigned long PCI_2X_RELAY_INVERT; // [Rx228]
+ volatile unsigned long RESV_22C[0x35]; // [Rx22C - Rx2FF]
+
+ volatile unsigned long INT_REQ_TYPE; // [Rx300] GPIO Interrupt Request Type Register
+ volatile unsigned long INT_REQ_STS; // [Rx304] GPIO Interrupt Request Status Register
+ volatile unsigned long RESV_308[0x3E]; // [Rx308-Rx3FF]
+
+ volatile unsigned long IDE_IO_DRV; // [Rx400] IDE I/O Drive Strength Register
+ volatile unsigned long MS_IO_DRV; // [Rx404] MS I/O Drive Strength and Slew Rate Register
+ volatile unsigned long PCI_IO_DRV; // [Rx408] PCI Bus I/O Drive Strength and Slew Rate Register
+ volatile unsigned long SD_IO_DRV; // [Rx40C] SD I/O Drive Strength and Slwe Rate Register
+ volatile unsigned long VID_IO_DRV; // [Rx410] VID Clock I/O Drive Strength and Slew Rate Register
+ volatile unsigned long SPI_IO_DRV; // [Rx414] SPI I/O Drive Strength and Slew Rate Register
+ volatile unsigned long CF_IO_DRV; // [Rx418] CF I/O Drive Strength and Slew Rate Register
+ volatile unsigned long LPC_IO_DRV; // [Rx41C] LPC I/O Drive Strength and Slew Rate Register
+ volatile unsigned long NF_IO_DRV; // [Rx420] NAND I/O Drive Strength and Slew Rate Register
+ volatile unsigned long MISC_IO_DRV; // [Rx424] MISC I/O Drive Strength and Slew Rate Register
+}GPIO_REG, * PGPIO_REG;
+
+
+typedef struct root_dir {
+ char MagicHeader[32];
+ char filename1[16];
+ unsigned int filesize1;
+ char resv1[12];
+ char filename2[16];
+ unsigned int filesize2;
+ char resv2[12];
+ char filename3[16];
+ unsigned int filesize3;
+ char resv3[12];
+} root_dir;
+
+
+#endif
diff --git a/cpu/arm920t/wmt/serial.c b/cpu/arm920t/wmt/serial.c
new file mode 100755
index 0000000..5777507
--- /dev/null
+++ b/cpu/arm920t/wmt/serial.c
@@ -0,0 +1,264 @@
+/*++
+Copyright (c) 2010 WonderMedia Technologies, Inc.
+
+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, see http://www.gnu.org/licenses/>.
+
+WonderMedia Technologies, Inc.
+10F, 529, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C.
+--*/
+
+/*
+ * serial.c - serial support for the WMT evaluation board
+ */
+
+#include <common.h>
+
+#ifdef CFG_WMT_SERIAL
+
+#include <asm/arch/hardware.h>
+#include "uart.h"
+#include "gpio.h"
+extern int bootcmdflag;
+extern int showinfoflag;
+
+DECLARE_GLOBAL_DATA_PTR;
+
+PUART_REG pUart_Reg = (PUART_REG)BA_UART0;
+PGPIO_REG pGpioReg = (PGPIO_REG)BA_GPIO;
+
+/*
+ * Function purpose:
+ * UART initialization
+ */
+int serial_init(void)
+{
+ /* Switch the Uart's pin from default GPIO into uart function pins for UART0/UART1 */
+ pGpioReg->CTRL_UR_LPC_SF &= ~(GPIO_UR0_ALL | GPIO_UR1_ALL);
+
+ serial_setbrg();
+
+ return 0;
+}
+
+/*
+ * Function purpose:
+ * Output character data through UART
+ */
+#ifdef CONFIG_USB_TTY
+unsigned int do_puts=0;
+#endif
+void
+serial_putc(const char c)
+{
+ if (bootcmdflag == 1 || showinfoflag == 1) {
+#ifdef CONFIG_USB_TTY
+ char tmp[2];
+
+ tmp[0] = c;
+ tmp[1] = 0;
+
+ if(( c != '\r' )&&(do_puts == 0))
+ {
+ usbtty_putc(c);
+ }
+#endif
+ while (1) {
+ if ((pUart_Reg->URUSR & URUSR_TXDBSY) == 0) /* TX data not busy */
+ break;
+ }
+
+ pUart_Reg->URTDR = c;
+ if (c == '\n')
+ serial_putc('\r');
+}
+}
+
+/*
+ * Function purpose:
+ * Output string data through UART
+ */
+void
+serial_puts(const char *s)
+{
+#ifdef CONFIG_USB_TTY
+ int tmp=0;
+
+ do_puts = 1;
+#endif
+ while (*s)
+ {
+ serial_putc(*s++);
+#ifdef CONFIG_USB_TTY
+ tmp++;
+#endif
+}
+#ifdef CONFIG_USB_TTY
+ do_puts = 0;
+ usbtty_puts ((const char *)((int)s-tmp));
+#endif
+}
+/*
+ * Function purpose:
+ * Require character data from UART
+ */
+int
+serial_getc(void)
+{
+#ifdef CONFIG_USB_TTY
+ int tmp=0;
+ char c;
+
+ while (1)
+ {
+ if(pUart_Reg->URUSR & URUSR_RXDRDY)
+ {
+ tmp++;
+ break;
+ }
+ if(c = usbtty_getc())
+ break;
+ }
+
+ return tmp?(pUart_Reg->URRDR&0xff):c;
+#else
+ while (!(pUart_Reg->URUSR & URUSR_RXDRDY));
+
+ return pUart_Reg->URRDR&0xff;
+#endif
+}
+
+/*
+ * Function purpose:
+ * return RXDRDY status bit in Uart status register
+ */
+int
+serial_tstc(void)
+{
+#ifdef CONFIG_USB_TTY
+ return (((pUart_Reg->URUSR & URUSR_RXDRDY)||usbtty_getc()) ? 1 : 0);
+#else
+ return ((pUart_Reg->URUSR & URUSR_RXDRDY) ? 1 : 0);
+#endif
+}
+
+/*
+ * Function purpose:
+ * Uart baud rate setting and initialization
+ * Note:
+ * Relative settings according to UART/IrDA
+ * Programmer Guide Revision 0.13
+ */
+void
+serial_setbrg(void)
+{
+ DECLARE_GLOBAL_DATA_PTR;
+ unsigned long TmpDiv = 0;
+ unsigned long TmpBkr = 0;
+
+ switch (gd->baudrate) {
+ /*
+ case BR_921K6:
+ TmpDiv = UART_BR_921K6;
+ TmpBkr = UART_BK_921K6;
+ break;
+
+ case BR_460K8:
+ TmpDiv = UART_BR_460K8;
+ TmpBkr = UART_BK_460K8;
+ break;
+
+ case BR_230K4:
+ TmpDiv = UART_BR_230K4;
+ TmpBkr = UART_BK_230K4;
+ break;
+ */
+
+ case BR_57K6:
+ TmpDiv = UART_BR_57K6;
+ TmpBkr = UART_BK_57K6;
+ break;
+ /*
+ case BR_28K8:
+ TmpDiv = UART_BR_28K8;
+ TmpBkr = UART_BK_28K8;
+ break;
+
+ case BR_14K4:
+ TmpDiv = UART_BR_14K4;
+ TmpBkr = UART_BK_14K4;
+ break;
+
+ case BR_7K2:
+ TmpDiv = UART_BR_7K2;
+ TmpBkr = UART_BK_7K2;
+ break;
+
+ case BR_3K6:
+ TmpDiv = UART_BR_3K6;
+ TmpBkr = UART_BK_3K6;
+ break;
+ */
+
+ case BR_38K4:
+ TmpDiv = UART_BR_38K4;
+ TmpBkr = UART_BK_38K4;
+ break;
+
+ case BR_19K2:
+ TmpDiv = UART_BR_19K2;
+ TmpBkr = UART_BK_19K2;
+ break;
+
+ case BR_9K6:
+ TmpDiv = UART_BR_9K6;
+ TmpBkr = UART_BK_9K6;
+ break;
+
+ case BR_115K2:
+ default:
+ TmpDiv = UART_BR_115K2;
+ TmpBkr = UART_BK_115K2;
+ break;
+ }
+
+ pUart_Reg->URDIV = TmpDiv;
+ pUart_Reg->URBKR = TmpBkr;
+
+ /* Disable TX,RX */
+ pUart_Reg->URLCR = 0;
+
+ /* Disable all interrupt */
+ pUart_Reg->URIER = 0;
+
+ /* Clear all interrupt status until all zeros */
+ /*
+ while (pUart_Reg->URISR) {
+ pUart_Reg->URISR = pUart_Reg->URISR;
+ }
+ */
+
+ /* Reset Tx,Rx Fifo until all zeros */
+ while (pUart_Reg->URFCR) {
+ /* Reset TX,RX Fifo */
+ pUart_Reg->URFCR = URFCR_TXFRST | URFCR_RXFRST;
+ }
+
+ /* Disable Fifo */
+ pUart_Reg->URFCR &= (~URFCR_FIFOEN);
+
+ /* 8-N-1 */
+ pUart_Reg->URLCR |= (URLCR_DLEN8B & ~URLCR_STBLEN2b & ~URLCR_PYTEN);
+
+ /* Enable TX,RX */
+ pUart_Reg->URLCR |= URLCR_RXEN | URLCR_TXEN;
+}
+
+#endif /* CFG_WMT_SERIAL */
diff --git a/cpu/arm920t/wmt/setup.h b/cpu/arm920t/wmt/setup.h
new file mode 100755
index 0000000..a4267af
--- /dev/null
+++ b/cpu/arm920t/wmt/setup.h
@@ -0,0 +1,108 @@
+/*++
+Copyright (c) 2010 WonderMedia Technologies, Inc.
+
+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, see http://www.gnu.org/licenses/>.
+
+WonderMedia Technologies, Inc.
+10F, 529, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C.
+--*/
+
+#ifndef __SETUP_H__
+#define __SETUP_H__
+
+#if !defined(__TTYPE_H__)
+#include "ttype.h"
+#endif
+#if !defined(__ADAPTER_H__)
+#include "adapter.h"
+#endif
+
+/*--------------------- Export Definitions -------------------------*/
+#define DIAG_AUTO_NONE 0
+#define DIAG_AUTO_DIAG 1
+#define DIAG_AUTO_2CTEST 2
+#define DIAG_AUTO_PINGPONG 3
+#define DIAG_AUTO_PHYTEST 4
+
+typedef struct CmdParaSet {
+
+ /* command-line auto-function number, default = 0 (no auto-function), diagnositic test = 1, */
+ /* network test = 2 */
+ UINT uCmdFuncNum;
+ /* function execution frequency, default = 0 (forever) */
+ ULONG ulTestFreq;
+ /* specify auto-test NIC number */
+ UINT uCardNum;
+ /* init NIC with forced mode, default = 0 (Auto mode), 1=10H, 2=10F, 3=100H, 4=100F */
+ UINT uForceMode;
+ /* shared IRQ support, default = TRUE */
+ BOOL bSharedIRQ;
+
+ /* 2-card network test with specified transmit packet size */
+ /* 0 = increased packet size, 1 = Random packet size */
+ /* 60 - 1514 = packet size */
+ UINT uPktSize;
+
+ /* test cable link status in diagnostic, default = TRUE */
+ BOOL bTstCable;
+
+ /* Connect to Altima-PHY slave RxNoReply exampt count, default = 0 */
+ UINT uAltimaSlaveRxNoReply;
+
+ /* Internal/external loopback test, default = FALSE */
+ BOOL bExtLoopback;
+
+ /* [1.34], Gigabit mode external loopback test, default = FALSE */
+ BOOL bExtLoopbackGiga;
+
+ /* RAMBIST test, default = TRUE */
+ BOOL bRAMBISTTest;
+
+ /* FIFO test, default = FALSE */
+ BOOL bFIFOTest;
+
+ /* IOL test flag, default = FALSE */
+ BOOL bIOLTest;
+
+ /* EEPROM checksum checking flag, default = FALSE */
+ BOOL bEEPROMCheck;
+
+ /* ForceMode loop flag, default = FALSE */
+ BOOL bForceModeLoop;
+
+ /* [1.33], Random data of packets for 2-card test, default = FALSE (normal content filling) */
+ BOOL bRandomPktData;
+
+ /* [1.33], Control transmission traffic for 2-card test, default = FALSE (normal load) */
+ BOOL bHeavyLoad;
+
+} SCmdParaSet, DEF * PSCmdParaSet;
+
+/*--------------------- Export Classes ----------------------------*/
+
+/*--------------------- Export Variables --------------------------*/
+
+/*--------------------- Export Functions --------------------------*/
+
+#ifdef __cplusplus
+extern "C" { /* Assume C declarations for C++ */
+#endif /* __cplusplus */
+
+void SETUPvSetupMenu(PSAdapterInfo pAdapter, SCmdParaSet sCmdPara);
+ULONG SETUPuSetupSilence(PSAdapterInfo pAdapter[], SCmdParaSet sCmdPara);
+void SETUPvGetStringForRealTimeMedia(PTSTR pszString, PSAdapterInfo pAdapter);
+
+#ifdef __cplusplus
+} /* End of extern "C" { */
+#endif /* __cplusplus */
+
+#endif /* __SETUP_H__ */
diff --git a/cpu/arm920t/wmt/tascii.h b/cpu/arm920t/wmt/tascii.h
new file mode 100755
index 0000000..6924306
--- /dev/null
+++ b/cpu/arm920t/wmt/tascii.h
@@ -0,0 +1,145 @@
+/*++
+Copyright (c) 2010 WonderMedia Technologies, Inc.
+
+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, see http://www.gnu.org/licenses/>.
+
+WonderMedia Technologies, Inc.
+10F, 529, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C.
+--*/
+
+#ifndef __TASCII_H__
+#define __TASCII_H__
+
+/*--------------------- Export Definitions -------------------------*/
+
+/*
+ * CONTROL ASCII CODE
+ */
+#define MC_NULL 0x00 /* null char */
+#define MC_SOH 0x01 /* Ctrl+A : */
+#define MC_STX 0x02 /* Ctrl+B : */
+#define MC_ETX 0x03 /* Ctrl+C : */
+#define MC_EOT 0x04 /* Ctrl+D : end of text */
+#define MC_ENQ 0x05 /* Ctrl+E : */
+#define MC_ACK 0x06 /* Ctrl+F : */
+
+#define MC_BELL 0x07 /* Ctrl+G : bell sound */
+#define MC_BACKSPACE 0x08 /* Ctrl+H : backspace */
+#define MC_TAB 0x09 /* Ctrl+I : harizontal tab */
+#define MC_LINEFEED 0x0A /* Ctrl+J : line feed */
+/* EOL(end of line for UNIX) */
+#define MC_VTAB 0x0B /* Ctrl+K : vertical tab */
+#define MC_FORMFEED 0x0C /* Ctrl+L : form feed */
+#define MC_ENTER 0x0D /* Ctrl+M : carriage return */
+
+#define MC_SO 0x0E /* Ctrl+N : */
+#define MC_SI 0x0F /* Ctrl+O : */
+#define MC_DLE 0x10 /* Ctrl+P : */
+
+#define MC_XON 0x11 /* Ctrl+Q : device control 1 */
+/* xon */
+#define MC_DC2 0x12 /* Ctrl+R : */
+#define MC_XOFF 0x13 /* Ctrl+S : device conteol 3 */
+/* xoff */
+#define MC_DC4 0x14 /* Ctrl+T : */
+#define MC_NAK 0x15 /* Ctrl+U : */
+#define MC_SYN 0x16 /* Ctrl+V : */
+#define MC_ETB 0x17 /* Ctrl+W : */
+#define MC_CAN 0x18 /* Ctrl+X : */
+#define MC_EM 0x19 /* Ctrl+Y : */
+
+#define MC_SUB 0x1A /* Ctrl+Z : */
+/* EOF(end of file for MSDOS) */
+#define MC_ESCAPE 0x1B /* Ctrl+[ : escape */
+
+#define MC_FS 0x1C /* Ctrl+\ : */
+#define MC_GS 0x1D /* Ctrl+] : */
+#define MC_RS 0x1E /* Ctrl+^ : */
+#define MC_US 0x1F /* Ctrl+_ : */
+
+/*
+ * PRINTABLE ASCII CODE
+ */
+#define MC_SPACE 0x20 /* space char */
+
+#define MC_0 0x30 /* 0 */
+#define MC_1 0x31 /* 1 */
+#define MC_2 0x32 /* 2 */
+#define MC_3 0x33 /* 3 */
+#define MC_4 0x34 /* 4 */
+#define MC_5 0x35 /* 5 */
+#define MC_6 0x36 /* 6 */
+#define MC_7 0x37 /* 7 */
+#define MC_8 0x38 /* 8 */
+#define MC_9 0x39 /* 9 */
+
+#define MC_A 0x41 /* A */
+#define MC_B 0x42 /* B */
+#define MC_C 0x43 /* C */
+#define MC_D 0x44 /* D */
+#define MC_E 0x45 /* E */
+#define MC_F 0x46 /* F */
+#define MC_G 0x47 /* G */
+#define MC_H 0x48 /* H */
+#define MC_I 0x49 /* I */
+#define MC_J 0x4A /* J */
+#define MC_K 0x4B /* K */
+#define MC_L 0x4C /* L */
+#define MC_M 0x4D /* M */
+#define MC_N 0x4E /* N */
+#define MC_O 0x4F /* O */
+#define MC_P 0x50 /* P */
+#define MC_Q 0x51 /* Q */
+#define MC_R 0x52 /* R */
+#define MC_S 0x53 /* S */
+#define MC_T 0x54 /* T */
+#define MC_U 0x55 /* U */
+#define MC_V 0x56 /* V */
+#define MC_W 0x57 /* W */
+#define MC_X 0x58 /* X */
+#define MC_Y 0x59 /* Y */
+#define MC_Z 0x5A /* Z */
+
+#define MC_a 0x61 /* a */
+#define MC_b 0x62 /* b */
+#define MC_c 0x63 /* c */
+#define MC_d 0x64 /* d */
+#define MC_e 0x65 /* e */
+#define MC_f 0x66 /* f */
+#define MC_g 0x67 /* g */
+#define MC_h 0x68 /* h */
+#define MC_i 0x69 /* i */
+#define MC_j 0x6A /* j */
+#define MC_k 0x6B /* k */
+#define MC_l 0x6C /* l */
+#define MC_m 0x6D /* m */
+#define MC_n 0x6E /* n */
+#define MC_o 0x6F /* o */
+#define MC_p 0x70 /* p */
+#define MC_q 0x71 /* q */
+#define MC_r 0x72 /* r */
+#define MC_s 0x73 /* s */
+#define MC_t 0x74 /* t */
+#define MC_u 0x75 /* u */
+#define MC_v 0x76 /* v */
+#define MC_w 0x77 /* w */
+#define MC_x 0x78 /* x */
+#define MC_y 0x79 /* y */
+#define MC_z 0x7A /* z */
+
+/*--------------------- Export Classes ----------------------------*/
+
+/*--------------------- Export Variables --------------------------*/
+
+/*--------------------- Export Functions --------------------------*/
+
+#endif /* __TASCII_H__ */
diff --git a/cpu/arm920t/wmt/tbit.h b/cpu/arm920t/wmt/tbit.h
new file mode 100755
index 0000000..39db55d
--- /dev/null
+++ b/cpu/arm920t/wmt/tbit.h
@@ -0,0 +1,69 @@
+/*++
+Copyright (c) 2010 WonderMedia Technologies, Inc.
+
+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, see http://www.gnu.org/licenses/>.
+
+WonderMedia Technologies, Inc.
+10F, 529, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C.
+--*/
+
+
+#ifndef __TBIT_H__
+#define __TBIT_H__
+
+#if !defined(__TTYPE_H__)
+#include "ttype.h"
+#endif
+
+/*--------------------- Export Definitions -------------------------*/
+
+/*--------------------- Export Types ------------------------------*/
+
+/*--------------------- Export Macros ------------------------------*/
+
+/* test single bit on */
+#define BITbIsBitOn(tData, tTestBit) \
+ (((tData) & (tTestBit)) != 0)
+
+/* test single bit off */
+#define BITbIsBitOff(tData, tTestBit) \
+ (((tData) & (tTestBit)) == 0)
+
+#define BITbIsAllBitsOn(tData, tTestBit) \
+ (((tData) & (tTestBit)) == (tTestBit))
+
+#define BITbIsAllBitsOff(tData, tTestBit) \
+ (((tData) & (tTestBit)) == 0)
+
+#define BITbIsAnyBitsOn(tData, tTestBit) \
+ (((tData) & (tTestBit)) != 0)
+
+#define BITbIsAnyBitsOff(tData, tTestBit) \
+ (((tData) & (tTestBit)) != (tTestBit))
+
+/*--------------------- Export Classes ----------------------------*/
+
+/*--------------------- Export Variables --------------------------*/
+
+/*--------------------- Export Functions --------------------------*/
+#ifdef __cplusplus
+extern "C" { /* Assume C declarations for C++ */
+#endif /* __cplusplus */
+
+
+BYTE BITbyReverseB(BYTE byData);
+
+
+#ifdef __cplusplus
+} /* End of extern "C" { */
+#endif /* __cplusplus */
+
+#endif /* __TBIT_H__ */
diff --git a/cpu/arm920t/wmt/tconvert.c b/cpu/arm920t/wmt/tconvert.c
new file mode 100755
index 0000000..0c00273
--- /dev/null
+++ b/cpu/arm920t/wmt/tconvert.c
@@ -0,0 +1,262 @@
+/*++
+Copyright (c) 2010 WonderMedia Technologies, Inc.
+
+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, see http://www.gnu.org/licenses/>.
+
+WonderMedia Technologies, Inc.
+10F, 529, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C.
+--*/
+
+/* #include <string.h> */
+/* #include <stdlib.h> */
+
+#if !defined(__UASSERT_H__)
+#include "uassert.h"
+#endif
+#if !defined(__TASCII_H__)
+#include "tascii.h"
+#endif
+#if !defined(__TCONVERT_H__)
+#include "tconvert.h"
+#endif
+
+/*--------------------- Static Definitions -------------------------*/
+
+/*--------------------- Static Classes ----------------------------*/
+
+/*--------------------- Static Variables --------------------------*/
+
+/*--------------------- Static Functions --------------------------*/
+
+/*--------------------- Export Variables --------------------------*/
+
+void CVTvBy6ToStr12(PBYTE pbyEtherAddr, const PTSTR pszResult)
+{
+ int ii;
+ UINT uDigit;
+ PBYTE pbyResult = (PBYTE)pszResult;
+
+ for (ii = 0; ii < 6; ii++) {
+ /* each time we convert one byte to two digits */
+
+ /* the 16^^1 portion */
+ uDigit = pbyEtherAddr[ii] / 16;
+
+ if (uDigit < 10)
+ *pbyResult = (BYTE)(MC_0 + uDigit);
+ else
+ *pbyResult = (BYTE)(MC_A + uDigit - 10);
+ pbyResult++;
+
+ /* the 16^^0 portion */
+ uDigit = pbyEtherAddr[ii] % 16;
+ if (uDigit < 10)
+ *pbyResult = (BYTE)(MC_0 + uDigit);
+ else
+ *pbyResult = (BYTE)(MC_A + uDigit - 10);
+ pbyResult++;
+ }
+ *pbyResult = 0;
+}
+
+void CVTvStr12ToBy6(const PCTSTR pszSrc, PBYTE pbyEtherAddr)
+{
+ int ii;
+ PBYTE pbySrc = (PBYTE)pszSrc;
+
+ /* before conversion, make it all uppercase */
+ /* strupr((PTSTR)pbySrc); */
+
+ for (ii = 0; ii < 6; ii++) {
+ /* each time we convert two digits to one byte */
+
+ /* the 16^^1 portion */
+ if (MC_0 <= *pbySrc && *pbySrc <= MC_9)
+ pbyEtherAddr[ii] = (BYTE)((*pbySrc - MC_0) * 16);
+ else
+ pbyEtherAddr[ii] = (BYTE)((*pbySrc - MC_A + 10) * 16);
+ pbySrc++;
+
+ /* the 16^^0 portion */
+ if (MC_0 <= *pbySrc && *pbySrc <= MC_9)
+ pbyEtherAddr[ii] += (BYTE)(*pbySrc - MC_0);
+ else
+ pbyEtherAddr[ii] += (BYTE)(*pbySrc - MC_A + 10);
+ pbySrc++;
+ }
+}
+
+/*
+ * Description:
+ *
+ * Parameters:
+ *
+ */
+void CVTvHexToAsc(PBYTE pbyValue, const PTSTR pszResult, UINT cbByte)
+{
+ int ii;
+ UINT uDigit;
+ PBYTE pbyResult = (PBYTE)pszResult;
+
+
+ for (ii = cbByte - 1; ii >= 0; ii--) {
+ /* each time we convert one byte to two digits */
+
+ /* the 16^^1 portion */
+ uDigit = pbyValue[ii] / 16;
+
+ if (uDigit < 10)
+ *pbyResult = (BYTE)(MC_0 + uDigit);
+ else
+ *pbyResult = (BYTE)(MC_A + uDigit - 10);
+ pbyResult++;
+
+ /* the 16^^0 portion */
+ uDigit = pbyValue[ii] % 16;
+ if (uDigit < 10)
+ *pbyResult = (BYTE)(MC_0 + uDigit);
+ else
+ *pbyResult = (BYTE)(MC_A + uDigit - 10);
+ pbyResult++;
+ }
+ *pbyResult = 0;
+}
+
+/*
+ * Description:
+ *
+ * Parameters:
+ *
+ */
+void CVTvAscToHex(const PCTSTR pszSrc, PBYTE pbyValue, UINT cbByte)
+{
+ int ii;
+ PBYTE pbySrc = (PBYTE)pszSrc;
+ PBYTE pbyHi2Lo;
+ UINT cbDigit;
+ UINT cbAscByte;
+
+ /* before conversion, make it all uppercase */
+ /* strupr((PTSTR)pbySrc); */
+ /* conversion from highest byte to lowerest byte */
+ pbyHi2Lo = pbyValue + cbByte - 1;
+
+ cbDigit = _tcslen((PTSTR)pbySrc);
+
+ /* # of bytes is (# of hex digits + 1) / 2 */
+ cbAscByte = (cbDigit + 1) / 2;
+
+ /* pre padding zero */
+ if (cbByte > cbAscByte) {
+ for (ii = 0; ii < (cbByte - cbAscByte); ii++) {
+ *pbyHi2Lo = 0;
+ pbyHi2Lo--;
+ }
+ } else {
+ /* if # of bytes of ascii string is greater than cbByte, */
+ /* only cbByte will be done */
+ cbAscByte = cbByte;
+ }
+
+ /* pre padding half byte */
+ if ((cbDigit % 2) != 0) {
+ if (MC_0 <= *pbySrc && *pbySrc <= MC_9)
+ *pbyHi2Lo = (BYTE)(*pbySrc - MC_0);
+ else
+ *pbyHi2Lo = (BYTE)(*pbySrc - MC_A + 10);
+ pbySrc++;
+ pbyHi2Lo--;
+ /* # of bytes we want to do should minus 1 */
+ cbAscByte--;
+ }
+
+ for (ii = 0; (ii < cbAscByte) && (pbySrc != _T('\0')); ii++) {
+ if (MC_0 <= *pbySrc && *pbySrc <= MC_9)
+ *pbyHi2Lo = (BYTE)((*pbySrc - MC_0) * 16);
+ else
+ *pbyHi2Lo = (BYTE)((*pbySrc - MC_A + 10) * 16);
+ pbySrc++;
+
+ if (MC_0 <= *pbySrc && *pbySrc <= MC_9)
+ *pbyHi2Lo += (BYTE)(*pbySrc - MC_0);
+ else
+ *pbyHi2Lo += (BYTE)(*pbySrc - MC_A + 10);
+ pbySrc++;
+ pbyHi2Lo--;
+ }
+}
+
+void CVTvIP4ToStr15(PBYTE pbyIPAddr, const PTSTR pszResult)
+{
+ int ii;
+ BYTE uNetAddr;
+ TCHAR IPStr[4];
+ PTSTR pbyResult = pszResult;
+
+ for (ii = 0; ii < 4; ii++) {
+ uNetAddr = pbyIPAddr[ii];
+
+ if (uNetAddr < 0x0A) {
+ /* pad two '0' if lower than 10 */
+ strncpy(pbyResult, "00", 2);
+ strncpy(pbyResult+2, IPStr, 1);
+ } else if (uNetAddr < 0x064) {
+ /* pad '0' if lower than 100 */
+ strncpy(pbyResult, "0", 1);
+ strncpy(pbyResult+1, IPStr, 2);
+ } else {
+ /* if > 100 , no padding needs to be performed */
+ strncpy(pbyResult, IPStr, 3);
+ }
+
+ pbyResult += 3;
+ if (ii == 3)
+ break;
+ *pbyResult = '.';
+ pbyResult++;
+ }
+
+ *pbyResult = '\0';
+}
+
+void CVTvStr15ToIP4(const PCTSTR pszSrc, PBYTE pbyIPAddr)
+{
+ int ii, jj;
+ PBYTE pbySrc = (PBYTE)pszSrc;
+ TCHAR IPStr[16];
+ PBYTE pbyIPStr = (PBYTE)IPStr;
+
+ ii = 0;
+ while (TRUE) {
+ /* reset digit counter */
+ jj = 0;
+ pbyIPStr = (PBYTE)IPStr;
+ while ((*pbySrc != '.') && (*pbySrc != '\0')) {
+ *pbyIPStr = *pbySrc;
+ pbyIPStr++;
+ pbySrc++;
+ jj++;
+ }
+
+ *pbyIPStr = '\0';
+ if (jj > 3)
+ /* more than 3 digits */
+ pbyIPAddr[ii] = 0xFF;
+ else
+ /* pbyIPAddr[ii]=(BYTE)atoi(IPStr); */
+
+ if (*pbySrc == '\0')
+ break;
+ ii++;
+ pbySrc++; /* skip "." */
+ }
+}
diff --git a/cpu/arm920t/wmt/tconvert.h b/cpu/arm920t/wmt/tconvert.h
new file mode 100755
index 0000000..db638f6
--- /dev/null
+++ b/cpu/arm920t/wmt/tconvert.h
@@ -0,0 +1,55 @@
+/*++
+Copyright (c) 2010 WonderMedia Technologies, Inc.
+
+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, see http://www.gnu.org/licenses/>.
+
+WonderMedia Technologies, Inc.
+10F, 529, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C.
+--*/
+
+#ifndef __TCONVERT_H__
+#define __TCONVERT_H__
+
+#if !defined(__TTYPE_H__)
+#include "ttype.h"
+#endif
+#if !defined(__TTCHAR_H__)
+#include "ttchar.h"
+#endif
+
+/*--------------------- Export Definitions -------------------------*/
+
+/*--------------------- Export Types ------------------------------*/
+
+/*--------------------- Export Macros ------------------------------*/
+
+/*--------------------- Export Classes ----------------------------*/
+
+/*--------------------- Export Variables --------------------------*/
+
+/*--------------------- Export Functions --------------------------*/
+#ifdef __cplusplus
+extern "C" { /* Assume C declarations for C++ */
+#endif /* __cplusplus */
+
+void CVTvBy6ToStr12(PBYTE pbyEtherAddr, const PTSTR pszResult);
+void CVTvStr12ToBy6(const PCTSTR pszSrc, PBYTE pbyEtherAddr);
+void CVTvHexToAsc(PBYTE pbyValue, const PTSTR pszResult, UINT cbByte);
+void CVTvAscToHex(const PCTSTR pszSrc, PBYTE pbyValue, UINT cbByte);
+void CVTvIP4ToStr15(PBYTE pbyIPAddr, const PTSTR pszResult);
+void CVTvStr15ToIP4(const PCTSTR pszSrc, PBYTE pbyIPAddr);
+
+#ifdef __cplusplus
+} /* End of extern "C" { */
+#endif /* __cplusplus */
+
+#endif /* __TCONVERT_H__ */
diff --git a/cpu/arm920t/wmt/tcrc.c b/cpu/arm920t/wmt/tcrc.c
new file mode 100755
index 0000000..718e217
--- /dev/null
+++ b/cpu/arm920t/wmt/tcrc.c
@@ -0,0 +1,139 @@
+/*++
+Copyright (c) 2010 WonderMedia Technologies, Inc.
+
+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, see http://www.gnu.org/licenses/>.
+
+WonderMedia Technologies, Inc.
+10F, 529, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C.
+--*/
+
+#if !defined(__TBIT_H__)
+#include "tbit.h"
+#endif
+#if !defined(__TCRC_H__)
+#include "tcrc.h"
+#endif
+
+/*--------------------- Static Definitions -------------------------*/
+
+/*--------------------- Static Classes ----------------------------*/
+
+/*--------------------- Static Variables --------------------------*/
+/* 32-bit CRC table */
+static const DWORD s_adwCrc32Table[256] = {
+ 0x00000000L, 0x77073096L, 0xEE0E612CL, 0x990951BAL,
+ 0x076DC419L, 0x706AF48FL, 0xE963A535L, 0x9E6495A3L,
+ 0x0EDB8832L, 0x79DCB8A4L, 0xE0D5E91EL, 0x97D2D988L,
+ 0x09B64C2BL, 0x7EB17CBDL, 0xE7B82D07L, 0x90BF1D91L,
+ 0x1DB71064L, 0x6AB020F2L, 0xF3B97148L, 0x84BE41DEL,
+ 0x1ADAD47DL, 0x6DDDE4EBL, 0xF4D4B551L, 0x83D385C7L,
+ 0x136C9856L, 0x646BA8C0L, 0xFD62F97AL, 0x8A65C9ECL,
+ 0x14015C4FL, 0x63066CD9L, 0xFA0F3D63L, 0x8D080DF5L,
+ 0x3B6E20C8L, 0x4C69105EL, 0xD56041E4L, 0xA2677172L,
+ 0x3C03E4D1L, 0x4B04D447L, 0xD20D85FDL, 0xA50AB56BL,
+ 0x35B5A8FAL, 0x42B2986CL, 0xDBBBC9D6L, 0xACBCF940L,
+ 0x32D86CE3L, 0x45DF5C75L, 0xDCD60DCFL, 0xABD13D59L,
+ 0x26D930ACL, 0x51DE003AL, 0xC8D75180L, 0xBFD06116L,
+ 0x21B4F4B5L, 0x56B3C423L, 0xCFBA9599L, 0xB8BDA50FL,
+ 0x2802B89EL, 0x5F058808L, 0xC60CD9B2L, 0xB10BE924L,
+ 0x2F6F7C87L, 0x58684C11L, 0xC1611DABL, 0xB6662D3DL,
+ 0x76DC4190L, 0x01DB7106L, 0x98D220BCL, 0xEFD5102AL,
+ 0x71B18589L, 0x06B6B51FL, 0x9FBFE4A5L, 0xE8B8D433L,
+ 0x7807C9A2L, 0x0F00F934L, 0x9609A88EL, 0xE10E9818L,
+ 0x7F6A0DBBL, 0x086D3D2DL, 0x91646C97L, 0xE6635C01L,
+ 0x6B6B51F4L, 0x1C6C6162L, 0x856530D8L, 0xF262004EL,
+ 0x6C0695EDL, 0x1B01A57BL, 0x8208F4C1L, 0xF50FC457L,
+ 0x65B0D9C6L, 0x12B7E950L, 0x8BBEB8EAL, 0xFCB9887CL,
+ 0x62DD1DDFL, 0x15DA2D49L, 0x8CD37CF3L, 0xFBD44C65L,
+ 0x4DB26158L, 0x3AB551CEL, 0xA3BC0074L, 0xD4BB30E2L,
+ 0x4ADFA541L, 0x3DD895D7L, 0xA4D1C46DL, 0xD3D6F4FBL,
+ 0x4369E96AL, 0x346ED9FCL, 0xAD678846L, 0xDA60B8D0L,
+ 0x44042D73L, 0x33031DE5L, 0xAA0A4C5FL, 0xDD0D7CC9L,
+ 0x5005713CL, 0x270241AAL, 0xBE0B1010L, 0xC90C2086L,
+ 0x5768B525L, 0x206F85B3L, 0xB966D409L, 0xCE61E49FL,
+ 0x5EDEF90EL, 0x29D9C998L, 0xB0D09822L, 0xC7D7A8B4L,
+ 0x59B33D17L, 0x2EB40D81L, 0xB7BD5C3BL, 0xC0BA6CADL,
+ 0xEDB88320L, 0x9ABFB3B6L, 0x03B6E20CL, 0x74B1D29AL,
+ 0xEAD54739L, 0x9DD277AFL, 0x04DB2615L, 0x73DC1683L,
+ 0xE3630B12L, 0x94643B84L, 0x0D6D6A3EL, 0x7A6A5AA8L,
+ 0xE40ECF0BL, 0x9309FF9DL, 0x0A00AE27L, 0x7D079EB1L,
+ 0xF00F9344L, 0x8708A3D2L, 0x1E01F268L, 0x6906C2FEL,
+ 0xF762575DL, 0x806567CBL, 0x196C3671L, 0x6E6B06E7L,
+ 0xFED41B76L, 0x89D32BE0L, 0x10DA7A5AL, 0x67DD4ACCL,
+ 0xF9B9DF6FL, 0x8EBEEFF9L, 0x17B7BE43L, 0x60B08ED5L,
+ 0xD6D6A3E8L, 0xA1D1937EL, 0x38D8C2C4L, 0x4FDFF252L,
+ 0xD1BB67F1L, 0xA6BC5767L, 0x3FB506DDL, 0x48B2364BL,
+ 0xD80D2BDAL, 0xAF0A1B4CL, 0x36034AF6L, 0x41047A60L,
+ 0xDF60EFC3L, 0xA867DF55L, 0x316E8EEFL, 0x4669BE79L,
+ 0xCB61B38CL, 0xBC66831AL, 0x256FD2A0L, 0x5268E236L,
+ 0xCC0C7795L, 0xBB0B4703L, 0x220216B9L, 0x5505262FL,
+ 0xC5BA3BBEL, 0xB2BD0B28L, 0x2BB45A92L, 0x5CB36A04L,
+ 0xC2D7FFA7L, 0xB5D0CF31L, 0x2CD99E8BL, 0x5BDEAE1DL,
+ 0x9B64C2B0L, 0xEC63F226L, 0x756AA39CL, 0x026D930AL,
+ 0x9C0906A9L, 0xEB0E363FL, 0x72076785L, 0x05005713L,
+ 0x95BF4A82L, 0xE2B87A14L, 0x7BB12BAEL, 0x0CB61B38L,
+ 0x92D28E9BL, 0xE5D5BE0DL, 0x7CDCEFB7L, 0x0BDBDF21L,
+ 0x86D3D2D4L, 0xF1D4E242L, 0x68DDB3F8L, 0x1FDA836EL,
+ 0x81BE16CDL, 0xF6B9265BL, 0x6FB077E1L, 0x18B74777L,
+ 0x88085AE6L, 0xFF0F6A70L, 0x66063BCAL, 0x11010B5CL,
+ 0x8F659EFFL, 0xF862AE69L, 0x616BFFD3L, 0x166CCF45L,
+ 0xA00AE278L, 0xD70DD2EEL, 0x4E048354L, 0x3903B3C2L,
+ 0xA7672661L, 0xD06016F7L, 0x4969474DL, 0x3E6E77DBL,
+ 0xAED16A4AL, 0xD9D65ADCL, 0x40DF0B66L, 0x37D83BF0L,
+ 0xA9BCAE53L, 0xDEBB9EC5L, 0x47B2CF7FL, 0x30B5FFE9L,
+ 0xBDBDF21CL, 0xCABAC28AL, 0x53B39330L, 0x24B4A3A6L,
+ 0xBAD03605L, 0xCDD70693L, 0x54DE5729L, 0x23D967BFL,
+ 0xB3667A2EL, 0xC4614AB8L, 0x5D681B02L, 0x2A6F2B94L,
+ 0xB40BBE37L, 0xC30C8EA1L, 0x5A05DF1BL, 0x2D02EF8DL
+};
+
+/*--------------------- Static Functions --------------------------*/
+
+/*--------------------- Export Variables --------------------------*/
+
+/*--------------------- Export Functions --------------------------*/
+DWORD
+CRCdwCrc32(
+ PBYTE pbyData,
+ UINT cbByte,
+ DWORD dwCrcSeed
+ )
+{
+ DWORD dwCrc;
+
+ dwCrc = dwCrcSeed;
+ while (cbByte--) {
+ dwCrc = s_adwCrc32Table[(BYTE)((dwCrc ^ (*pbyData)) & 0xFF)] ^ (dwCrc >> 8);
+ pbyData++;
+ }
+
+ return dwCrc;
+}
+
+DWORD
+CRCdwGetCrc32(
+ PBYTE pbyData,
+ UINT cbByte
+ )
+{
+ return ~CRCdwCrc32(pbyData, cbByte, 0xFFFFFFFFL);
+}
+
+DWORD
+CRCdwGetCrc32Ex(
+ PBYTE pbyData,
+ UINT cbByte,
+ DWORD dwPreCRC
+ )
+{
+ return CRCdwCrc32(pbyData, cbByte, dwPreCRC);
+}
diff --git a/cpu/arm920t/wmt/tcrc.h b/cpu/arm920t/wmt/tcrc.h
new file mode 100755
index 0000000..9f3d4a5
--- /dev/null
+++ b/cpu/arm920t/wmt/tcrc.h
@@ -0,0 +1,57 @@
+/*++
+Copyright (c) 2010 WonderMedia Technologies, Inc.
+
+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, see http://www.gnu.org/licenses/>.
+
+WonderMedia Technologies, Inc.
+10F, 529, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C.
+--*/
+
+#ifndef __TCRC_H__
+#define __TCRC_H__
+
+#if !defined(__TTYPE_H__)
+#include "ttype.h"
+#endif
+
+/*--------------------- Export Definitions -------------------------*/
+
+/*--------------------- Export Types ------------------------------*/
+
+/*--------------------- Export Macros ------------------------------*/
+
+/*--------------------- Export Classes ----------------------------*/
+
+/*--------------------- Export Variables --------------------------*/
+
+/*--------------------- Export Functions --------------------------*/
+#ifdef __cplusplus
+extern "C" { /* Assume C declarations for C++ */
+#endif /* __cplusplus */
+
+DWORD CRCdwCrc32(PBYTE pbyData, UINT cbByte, DWORD dwCrcSeed);
+DWORD CRCdwGetCrc32(PBYTE pbyData, UINT cbByte);
+DWORD CRCdwGetCrc32Ex(PBYTE pbyData, UINT cbByte, DWORD dwPreCRC);
+
+/*
+DWORD CRCdwCrc(PBYTE pbyData, UINT cbByte, DWORD dwCrcSeed);
+DWORD CRCdwGetCrc(PBYTE pbyData, UINT cbByte);
+DWORD CRCdwGetCrcEx(PBYTE pbyData, UINT cbByte, DWORD dwPreCRC);
+*/
+
+WORD CRCwCrc16(WORD wCRC, BYTE *cp, int len);
+
+#ifdef __cplusplus
+} /* End of extern "C" { */
+#endif /* __cplusplus */
+
+#endif /* __TCRC_H__ */
diff --git a/cpu/arm920t/wmt/tether.h b/cpu/arm920t/wmt/tether.h
new file mode 100755
index 0000000..fdae4e4
--- /dev/null
+++ b/cpu/arm920t/wmt/tether.h
@@ -0,0 +1,188 @@
+/*++
+Copyright (c) 2010 WonderMedia Technologies, Inc.
+
+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, see http://www.gnu.org/licenses/>.
+
+WonderMedia Technologies, Inc.
+10F, 529, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C.
+--*/
+
+
+#ifndef __TETHER_H__
+#define __TETHER_H__
+
+#if !defined(__TTYPE_H__)
+#include "ttype.h"
+#endif
+
+/*--------------------- Export Definitions -------------------------*/
+/*
+ * constants
+ */
+#define U_ETHER_ADDR_LEN 6 /* Ethernet address length */
+#define U_TYPE_LEN 2
+#define U_CRC_LEN 4
+#define U_HEADER_LEN (U_ETHER_ADDR_LEN * 2 + U_TYPE_LEN)
+#define U_ETHER_ADDR_STR_LEN (U_ETHER_ADDR_LEN * 2 + 1) /* Ethernet address string length */
+#define MIN_DATA_LEN 46 /* min data length */
+#define MAX_DATA_LEN 1500 /* max data length */
+
+#define MIN_PACKET_LEN (MIN_DATA_LEN + U_HEADER_LEN) /* 60, min total packet length (tx) */
+#define MAX_PACKET_LEN (MAX_DATA_LEN + U_HEADER_LEN) /* 1514, max total packet length (tx) */
+#define MAX_JUMBO_PKT_LEN 9040
+
+#define MAX_LOOKAHEAD_SIZE MAX_PACKET_LEN
+
+#define U_MULTI_ADDR_LEN 8 /* multicast address length */
+
+/*
+ * wType field in the SEthernetHeader
+ *
+ * NOTE....
+ * in network byte order, high byte is going first
+ */
+#define TYPE_PKT_IP 0x0008
+#define TYPE_PKT_ARP 0x0608
+#define TYPE_PKT_RARP 0x3580
+#define TYPE_PKT_IPX 0x3781
+
+#define TYPE_PKT_PING_M_REQ 0x1180 /* master reguest */
+#define TYPE_PKT_PING_S_GNT 0x2280 /* slave grant */
+#define TYPE_PKT_PING_M 0x7780 /* pingpong master packet */
+#define TYPE_PKT_PING_S 0x8880 /* pingpong slave packet */
+#define TYPE_PKT_DISCONN_M 0x9980 /* pingpong master disconnect packet */
+#define TYPE_PKT_WOL_M_REQ 0x3380 /* WOL waker request */
+#define TYPE_PKT_WOL_S_GNT 0x4480 /* WOL sleeper grant */
+
+/*
+ * wFrameCtl field in the S802_11Header
+ *
+ * NOTE....
+ * in network byte order, high byte is going first
+ */
+
+#define FC_TODS 0x0100
+#define FC_FROMDS 0x0200
+#define FC_MOREFRAG 0x0400
+#define FC_RETRY 0x0800
+#define TYPE_802_11_DATA 0x0008
+#define TYPE_802_11_MASK 0x000C
+#define TYPE_802_11_RTS 0x00B4
+
+#define TYPE_802_11_CONTROL 0x0004
+#define TYPE_802_11_MGMT 0x0000
+
+#define U_WMAC_HEADER_LEN 24
+/*--------------------- Export Types ------------------------------*/
+
+/*
+ * Ethernet packet
+ */
+typedef struct tagSEthernetHeader {
+ BYTE abyDstAddr[U_ETHER_ADDR_LEN];
+ BYTE abySrcAddr[U_ETHER_ADDR_LEN];
+ WORD wType;
+} SEthernetHeader, DEF * PSEthernetHeader;
+
+/*
+ * 802_3 packet
+ */
+typedef struct tagS802_3Header {
+ BYTE abyDstAddr[U_ETHER_ADDR_LEN];
+ BYTE abySrcAddr[U_ETHER_ADDR_LEN];
+ WORD wLen;
+} S802_3Header, DEF * PS802_3Header;
+
+typedef struct tagS802_2LCCHeader {
+ BYTE abyDstAddr[U_ETHER_ADDR_LEN];
+ BYTE abySrcAddr[U_ETHER_ADDR_LEN];
+ WORD wLen;
+ BYTE byDSAP;
+ BYTE bySSAP;
+ BYTE byCtrl;
+} S802_2LCCHeader, DEF * PS802_2LCCHeader;
+
+typedef struct tagS802_3SNAPHeader {
+ BYTE abyDstAddr[U_ETHER_ADDR_LEN];
+ BYTE abySrcAddr[U_ETHER_ADDR_LEN];
+ WORD wLen;
+ BYTE byDSAP;
+ BYTE bySSAP;
+ BYTE byCtrl;
+ BYTE Org[3];
+ WORD wType;
+} S802_2SNAPHeader, DEF * PS802_2SNAPHeader;
+
+typedef struct tagMACCtrlFrameHeader {
+ BYTE abyDstAddr[U_ETHER_ADDR_LEN];
+ BYTE abySrcAddr[U_ETHER_ADDR_LEN];
+ WORD wType;
+ WORD wOpCode;
+ WORD wPauseTimer;
+ BYTE abyReserved[42];
+} SMACCtrlFrameHeader, DEF * PSMACCtrlFrameHeader;
+
+/*
+ * 802_11 packet
+ */
+typedef struct tagS802_11Header {
+ WORD wFrameCtl;
+ WORD wDurationID;
+ BYTE abyAddr1[U_ETHER_ADDR_LEN];
+ BYTE abyAddr2[U_ETHER_ADDR_LEN];
+ BYTE abyAddr3[U_ETHER_ADDR_LEN];
+ WORD wSeqCtl;
+#ifdef DS2DS
+ BYTE abyAddr4[U_ETHER_ADDR_LEN];
+#endif
+ DWORD dwIV;
+} S802_11Header, DEF * PS802_11Header;
+
+/*--------------------- Export Macros ------------------------------*/
+/* Frame type macro */
+
+#define IS_MULTICAST_ADDRESS(pbyEtherAddr) \
+ ((*(PBYTE)(pbyEtherAddr) & 0x01) == 1)
+
+#define IS_BROADCAST_ADDRESS(pbyEtherAddr) ( \
+ (*(PDWORD)(pbyEtherAddr) == 0xFFFFFFFFL) && \
+ (*(PWORD)((PBYTE)(pbyEtherAddr) + 4) == 0xFFFF) \
+)
+
+#define IS_NULL_ADDRESS(pbyEtherAddr) ( \
+ (*(PDWORD)(pbyEtherAddr) == 0L) && \
+ (*(PWORD)((PBYTE)(pbyEtherAddr) + 4) == 0) \
+)
+
+#define IS_ETH_ADDRESS_EQUAL(pbyAddr1, pbyAddr2) ( \
+ (*(PDWORD)(pbyAddr1) == *(PDWORD)(pbyAddr2)) && \
+ (*(PWORD)((PBYTE)(pbyAddr1) + 4) == \
+ *(PWORD)((PBYTE)(pbyAddr2) + 4)) \
+)
+
+/*--------------------- Export Classes ----------------------------*/
+
+/*--------------------- Export Variables --------------------------*/
+
+/*--------------------- Export Functions --------------------------*/
+#ifdef __cplusplus
+extern "C" { /* Assume C declarations for C++ */
+#endif /* __cplusplus */
+
+BYTE ETHbyGetHashIndexByCrc32(PBYTE pbyMultiAddr);
+/* BYTE ETHbyGetHashIndexByCrc(PBYTE pbyMultiAddr); */
+BOOL ETHbIsBufferCrc32Ok(PBYTE pbyBuffer, UINT cbFrameLength);
+
+#ifdef __cplusplus
+} /* End of extern "C" { */
+#endif /* __cplusplus */
+
+#endif /* __TETHER_H__ */
diff --git a/cpu/arm920t/wmt/tmacro.h b/cpu/arm920t/wmt/tmacro.h
new file mode 100755
index 0000000..23755c1
--- /dev/null
+++ b/cpu/arm920t/wmt/tmacro.h
@@ -0,0 +1,133 @@
+/*++
+Copyright (c) 2010 WonderMedia Technologies, Inc.
+
+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, see http://www.gnu.org/licenses/>.
+
+WonderMedia Technologies, Inc.
+10F, 529, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C.
+--*/
+
+
+#ifndef __TMACRO_H__
+#define __TMACRO_H__
+
+#if !defined(__TTYPE_H__)
+#include "ttype.h"
+#endif
+
+/****** Common helper macros ***********************************************/
+
+#if !defined(LONIBBLE)
+#define LONIBBLE(b) ((BYTE)(b) & 0x0F)
+#endif
+#if !defined(HINIBBLE)
+#define HINIBBLE(b) ((BYTE)(((WORD)(b) >> 4) & 0x0F))
+#endif
+
+#if !defined(LOBYTE)
+#define LOBYTE(w) ((BYTE)(w))
+#endif
+#if !defined(HIBYTE)
+#define HIBYTE(w) ((BYTE)(((WORD)(w) >> 8) & 0xFF))
+#endif
+
+#if !defined(LOWORD)
+#define LOWORD(d) ((WORD)(d))
+#endif
+#if !defined(HIWORD)
+#define HIWORD(d) ((WORD)((((DWORD)(d)) >> 16) & 0xFFFF))
+#endif
+
+#define LODWORD(q) ((q).u.dwLowDword)
+#define HIDWORD(q) ((q).u.dwHighDword)
+
+#define MAKEBYTE(ln, hn) ((BYTE)(((BYTE)(ln) & 0x0F) | ((BYTE)(hn) << 4)))
+#if !defined(MAKEWORD)
+#define MAKEWORD(lb, hb) ((WORD)(((BYTE)(lb)) | (((WORD)((BYTE)(hb))) << 8)))
+#endif
+#if !defined(MAKEDWORD)
+#define MAKEDWORD(lw, hw) ((DWORD)(((WORD)(lw)) | (((DWORD)((WORD)(hw))) << 16)))
+#endif
+#define MAKEQWORD(ld, hd, pq) {pq->u.dwLowDword = ld; pq->u.dwHighDword = hd; }
+
+#if !defined(MAKELONG)
+#define MAKELONG(low, high) ((LONG)(((WORD)(low)) | (((DWORD)((WORD)(high))) << 16)))
+#endif
+
+#if !defined(REVDWORD)
+#define REVDWORD(d) (MAKEDWORD(MAKEWORD(HIBYTE(HIWORD(d)), LOBYTE(HIWORD(d))), \
+ MAKEWORD(HIBYTE(LOWORD(d)), LOBYTE(LOWORD(d)))))
+#endif
+
+#ifndef NOMINMAX
+#ifndef max
+#define max(a, b) (((a) > (b)) ? (a) : (b))
+#endif
+#ifndef min
+#define min(a, b) (((a) < (b)) ? (a) : (b))
+#endif
+#endif /* NOMINMAX */
+
+/****** Misc macros ********************************************************/
+
+/* get the field offset in the type(struct, class, ...) */
+#define OFFSET(type, field) ((int)(&((type NEAR*)1)->field)-1)
+
+/* string equality shorthand */
+#define STR_EQ(x, y) (strcmp(x, y) == 0)
+#define STR_NE(x, y) (strcmp(x, y) != 0)
+
+
+/* calculate element # of array */
+#define ELEMENT_NUM(array) (sizeof(array) / sizeof(array[0]))
+#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
+
+/* null statement */
+#define NULL_FUNC()
+
+/* Since not all compilers support structure assignment, the ASSIGN()
+ * macro is used. This controls how it's actually implemented.
+ */
+#ifdef NOSTRUCTASSIGN /* Version for old compilers that don't support it */
+#define ASSIGN(a, b) memcpy((char *)&(a), (char *)&(b), sizeof(b);
+#else /* Version for compilers that do */
+#define ASSIGN(a, b) ((a) = (b))
+#endif
+
+/* Wrap Around */
+#define ADD_ONE_WITH_WRAP_AROUND(uVar, uModulo) { \
+ if ((uVar) >= ((uModulo) - 1)) \
+ (uVar) = 0; \
+ else \
+ (uVar)++; \
+}
+
+#define ADD_N_WITH_WRAP_AROUND(uVar, uNum, uModulo) { \
+ if (((uVar) + (uNum)) > ((uModulo) - 1)) \
+ (uVar) = (uVar) + (uNum) - (uModulo); \
+ else \
+ (uVar) += (uNum); \
+}
+
+#define SUB_ONE_WITH_WRAP_AROUND(uVar, uModulo) { \
+ if ((uVar) <= 0) \
+ (uVar) = ((uModulo) - 1); \
+ else \
+ (uVar)--; \
+}
+
+#if defined(__WATCOMC__)
+#define RANDOM(_x_) (UINT)(((UINT)rand()*(_x_)) / (UINT)(RAND_MAX+1))
+#else
+#define RANDOM(_x_) random(_x_)
+#endif
+
+#endif /* __TMACRO_H__ */
diff --git a/cpu/arm920t/wmt/tmem.h b/cpu/arm920t/wmt/tmem.h
new file mode 100755
index 0000000..dfe8315
--- /dev/null
+++ b/cpu/arm920t/wmt/tmem.h
@@ -0,0 +1,99 @@
+/*++
+Copyright (c) 2010 WonderMedia Technologies, Inc.
+
+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, see http://www.gnu.org/licenses/>.
+
+WonderMedia Technologies, Inc.
+10F, 529, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C.
+--*/
+
+#ifndef __MEM_H__
+#define __MEM_H__
+
+#if !defined(__TTYPE_H__)
+#include "ttype.h"
+#endif
+
+#include "gmacif.h"
+#include "pcinet.h"
+
+/*--------------------- Export Definitions -------------------------*/
+/* memory allocation map from RAW(allocated) memory -> ALIGNED memory */
+typedef struct tagSAllocMap {
+ /* this dwRawSize value must assign */
+ DWORD dwRawSize; /* allocated size of the memory block */
+ DWORD dwRawVAddr; /* allocated virtual address of the memory block */
+ QWORD qwRawPAddr; /* allocated physical address of the memory block */
+ DWORD dwSize; /* aligned size (exactly) */
+ DWORD dwVAddr; /* aligned virtual address */
+ DWORD dwPAddr; /* aligned physical address */
+ PVOID pvHandle; /* handle to do system-call */
+} SAllocMap, *PSAllocMap;
+
+#define malloc GMEMvAllocate
+/* #define memset MEMvSet */
+/*--------------------- Export Types ------------------------------*/
+
+/*--------------------- Export Macros ------------------------------*/
+#define freemem() \
+{ \
+ g_pvGBufferIndex = (PVOID)GMEMORY_BUFFER_START;\
+ g_IO_point = PCI_base_addr; \
+ g_Mem_point = PCI_base_addr+PCI_io_range ; \
+}
+/*--------------------- Export Classes ----------------------------*/
+#define MEMvFree(a, b)
+#define MEMvFreeShared(a)
+#define free(a);
+/*--------------------- Export Variables --------------------------*/
+extern PVOID g_pvGBufferIndex;
+/*--------------------- Export Functions --------------------------*/
+#ifdef __cplusplus
+extern "C" { /* Assume C declarations for C++ */
+#endif /* __cplusplus */
+
+VOID
+MEMvAlign(
+ PSAllocMap pamMem,
+ UINT uBoundary
+ );
+
+PVOID
+GMEMvAllocate(
+ UINT uCount
+ );
+
+VOID
+GMEMvAllocateShared(
+ PSAllocMap pamMem
+ );
+
+VOID
+MEMvCopy(
+ PVOID pvDst,
+ PVOID pvSrc,
+ UINT uCount
+ );
+
+VOID
+MEMvSet(
+ PVOID pvDst,
+ BYTE byPattern,
+ UINT uCount
+ );
+
+
+#ifdef __cplusplus
+} /* End of extern "C" { */
+#endif /* __cplusplus */
+
+#endif /* __MEM_H__ */
diff --git a/cpu/arm920t/wmt/tpci.h b/cpu/arm920t/wmt/tpci.h
new file mode 100755
index 0000000..66a3100
--- /dev/null
+++ b/cpu/arm920t/wmt/tpci.h
@@ -0,0 +1,94 @@
+/*++
+Copyright (c) 2010 WonderMedia Technologies, Inc.
+
+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, see http://www.gnu.org/licenses/>.
+
+WonderMedia Technologies, Inc.
+10F, 529, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C.
+--*/
+
+#ifndef __TPCI_H__
+#define __TPCI_H__
+
+#if !defined(__TTYPE_H__)
+#include "ttype.h"
+#endif
+
+/*--------------------- Export Definitions -------------------------*/
+#define MAX_PCI_BUS 256 /* max. # of PCI bus that we support */
+#define MAX_PCI_DEVICE 32 /* max. # of PCI devices */
+
+/*
+ * Registers in the PCI configuration space
+ */
+#define PCI_REG_VENDOR_ID 0x00
+#define PCI_REG_DEVICE_ID 0x02
+#define PCI_REG_COMMAND 0x04
+#define PCI_REG_STATUS 0x06
+#define PCI_REG_REV_ID 0x08
+#define PCI_REG_CLASS_CODE 0x09
+#define PCI_REG_CACHELINE_SIZE 0x0C
+#define PCI_REG_LAT_TIMER 0x0D
+#define PCI_REG_HDR_TYPE 0x0E
+#define PCI_REG_BIST 0x0F
+
+#define PCI_REG_BAR0 0x10
+#define PCI_REG_BAR1 0x14
+#define PCI_REG_BAR2 0x18
+#define PCI_REG_CARDBUS_CIS_PTR 0x28
+
+#define PCI_REG_SUB_VEN_ID 0x2C
+#define PCI_REG_SUB_SYS_ID 0x2E
+#define PCI_REG_EXP_ROM_BAR 0x30
+#define PCI_REG_CAP 0x34
+
+#define PCI_REG_INT_LINE 0x3C
+#define PCI_REG_INT_PIN 0x3D
+#define PCI_REG_MIN_GNT 0x3E
+#define PCI_REG_MAX_LAT 0x3F
+
+#define PCI_REG_MAX_SIZE 0x100 /* maximun total PCI registers */
+
+/* added by kevin */
+#define PCI_base_addr 0xc0000000
+#define PCI_io_range 0x10000
+#define PCI_memory_range 0x400000
+#define PCI_io_page 0x100 /* 256 byte */
+#define PCI_memory_page 0x1000 /* 4k */
+#define PCI_invalid 0xffffffff
+#define PCI_IO_ENABLE 0x1
+
+/*--------------------- Export Types ------------------------------*/
+
+/*--------------------- Export Macros ------------------------------*/
+
+/* macro MAKE Bus Dev Fun ID into WORD */
+#define MAKE_BDF_TO_WORD(byBusId, byDevId, byFunId) \
+ MAKEWORD(((((BYTE)(byDevId)) & 0x1F) << 3) + (((BYTE)(byFunId)) & 0x07), (byBusId))
+
+#define GET_BUSID(wBusDevFunId) \
+ HIBYTE(wBusDevFunId)
+
+#define GET_DEVID(wBusDevFunId) \
+ (LOBYTE(wBusDevFunId) >> 3)
+
+#define GET_FUNID(wBusDevFunId) \
+ (LOBYTE(wBusDevFunId) & 0x07)
+
+
+/*--------------------- Export Classes ----------------------------*/
+
+/*--------------------- Export Variables --------------------------*/
+
+/*--------------------- Export Functions --------------------------*/
+
+#endif /* __TPCI_H__ */
diff --git a/cpu/arm920t/wmt/ttchar.h b/cpu/arm920t/wmt/ttchar.h
new file mode 100755
index 0000000..3265227
--- /dev/null
+++ b/cpu/arm920t/wmt/ttchar.h
@@ -0,0 +1,245 @@
+/*++
+Copyright (c) 2010 WonderMedia Technologies, Inc.
+
+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, see http://www.gnu.org/licenses/>.
+
+WonderMedia Technologies, Inc.
+10F, 529, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C.
+--*/
+
+#ifndef __TTCHAR_H__
+#define __TTCHAR_H__
+
+#include <stddef.h>
+
+#if !defined(__TTYPE_H__)
+#include "ttype.h"
+#endif
+
+/*--------------------- Export Definitions -------------------------*/
+
+/*
+ * UNICODE (Wide Character) types
+ */
+typedef wchar_t WCHAR; /* wc, 16-bit UNICODE character */
+
+typedef WCHAR * PWCHAR;
+
+typedef WCHAR * PWCH;
+typedef WCHAR * LPWCH;
+typedef CONST WCHAR * PCWCH;
+typedef CONST WCHAR * LPCWCH;
+
+typedef WCHAR * PWSTR;
+typedef WCHAR * NWPSTR;
+typedef WCHAR * LPWSTR;
+typedef CONST WCHAR * PCWSTR;
+typedef CONST WCHAR * LPCWSTR;
+
+/*
+ * ANSI (Multi-byte Character) types
+ */
+#ifdef _MBCS
+
+typedef CHAR * PCHAR;
+
+typedef CHAR * PCH;
+typedef CHAR * LPCH;
+typedef CONST CHAR * PCCH;
+typedef CONST CHAR * LPCCH;
+
+typedef CHAR * PSTR;
+typedef CHAR * NPSTR;
+typedef CHAR * LPSTR;
+typedef CONST CHAR * PCSTR;
+typedef CONST CHAR * LPCSTR;
+
+#endif /* _MBCS */
+
+/*
+ * Neutral ANSI(SBCS,MBCS)/UNICODE types and macros
+ */
+#ifdef _UNICODE
+
+#ifndef _TCHAR_DEFINED
+typedef WCHAR TCHAR;
+typedef WCHAR * PTCHAR;
+typedef WCHAR TBYTE;
+typedef WCHAR * PTBYTE;
+#define _TCHAR_DEFINED
+#endif /* !_TCHAR_DEFINED */
+
+typedef LPWSTR PTCH;
+typedef LPWSTR LPTCH;
+typedef LPWSTR PTSTR;
+typedef LPWSTR LPTSTR;
+typedef LPCWSTR PCTSTR;
+typedef LPCWSTR LPCTSTR;
+
+#define __TEXT(quote) L##quote
+
+/* String functions */
+
+#define _tcscat wcscat
+#define _tcschr wcschr
+#define _tcscpy wcscpy
+#define _tcscspn wcscspn
+#define _tcslen wcslen
+#define _tcsncat wcsncat
+#define _tcsncpy wcsncpy
+#define _tcspbrk wcspbrk
+#define _tcsrchr wcsrchr
+#define _tcsspn wcsspn
+#define _tcsstr wcsstr
+#define _tcstok wcstok
+
+#define _tcsdup _wcsdup
+#define _tcsnset _wcsnset
+#define _tcsrev _wcsrev
+#define _tcsset _wcsset
+
+#define _tcscmp wcscmp
+#define _tcsicmp _wcsicmp
+#define _tcsnccmp wcsncmp
+#define _tcsncmp wcsncmp
+#define _tcsncicmp _wcsnicmp
+#define _tcsnicmp _wcsnicmp
+
+#define _tcscoll wcscoll
+#define _tcsicoll _wcsicoll
+#define _tcsnccoll _wcsncoll
+#define _tcsncoll _wcsncoll
+#define _tcsncicoll _wcsnicoll
+#define _tcsnicoll _wcsnicoll
+
+/* ctype functions */
+
+#define _istalnum iswalnum
+#define _istalpha iswalpha
+#define _istascii iswascii
+#define _istcntrl iswcntrl
+#define _istdigit iswdigit
+#define _istgraph iswgraph
+#define _istlower iswlower
+#define _istprint iswprint
+#define _istpunct iswpunct
+#define _istspace iswspace
+#define _istupper iswupper
+#define _istxdigit iswxdigit
+
+#define _totupper towupper
+#define _totlower towlower
+
+#else /* !_UNICODE */
+
+/* ++++++++++++++++++++ SBCS and MBCS ++++++++++++++++++++ */
+
+#ifdef _MBCS
+/* ++++++++++++++++++++ MBCS ++++++++++++++++++++ */
+/* there are no definitons here, now. */
+/* TBD.... */
+
+#else /* !_MBCS */
+
+/* ++++++++++++++++++++ SBCS ++++++++++++++++++++ */
+
+#ifndef _TCHAR_DEFINED
+typedef char TCHAR;
+typedef char *PTCHAR;
+typedef unsigned char TBYTE;
+typedef unsigned char *PTBYTE;
+#define _TCHAR_DEFINED
+#endif /* !_TCHAR_DEFINED */
+
+typedef PCH PTCH;
+typedef LPCH LPTCH;
+typedef PSTR PTSTR;
+typedef LPSTR LPTSTR;
+typedef PCSTR PCTSTR;
+typedef LPCSTR LPCTSTR;
+
+#define __TEXT(quote) quote
+
+/* String functions */
+
+#define _tcscat strcat
+#define _tcscpy strcpy
+#define _tcslen strlen
+#define _tcsxfrm strxfrm
+#define _tcsdup _strdup
+
+/* String functions */
+
+#define _tcschr strchr
+#define _tcscspn strcspn
+#define _tcsncat strncat
+#define _tcsncpy strncpy
+#define _tcspbrk strpbrk
+#define _tcsrchr strrchr
+#define _tcsspn strspn
+#define _tcsstr strstr
+#define _tcstok strtok
+
+#define _tcsnset _strnset
+#define _tcsrev _strrev
+#define _tcsset _strset
+
+#define _tcscmp strcmp
+#define _tcsicmp _stricmp
+#define _tcsnccmp strncmp
+#define _tcsncmp strncmp
+#define _tcsncicmp _strnicmp
+#define _tcsnicmp _strnicmp
+
+#define _tcscoll strcoll
+#define _tcsicoll _stricoll
+#define _tcsnccoll _strncoll
+#define _tcsncoll _strncoll
+#define _tcsncicoll _strnicoll
+#define _tcsnicoll _strnicoll
+
+/* ctype functions */
+
+#define _istascii isascii
+#define _istcntrl iscntrl
+#define _istxdigit isxdigit
+
+/* ctype functions */
+
+#define _istalnum isalnum
+#define _istalpha isalpha
+#define _istdigit isdigit
+#define _istgraph isgraph
+#define _istlower islower
+#define _istprint isprint
+#define _istpunct ispunct
+#define _istspace isspace
+#define _istupper isupper
+
+#define _totupper toupper
+#define _totlower tolower
+
+#endif /* !_MBCS */
+
+#endif /* !_UNICODE */
+
+/* Generic text macros to be used with string literals and character constants.
+ Will also allow symbolic constants that resolve to same. */
+#define _T(x) __TEXT(x)
+
+/*--------------------- Export Classes ----------------------------*/
+
+/*--------------------- Export Variables --------------------------*/
+
+/*--------------------- Export Functions --------------------------*/
+
+#endif /* __TTCHAR_H__ */
diff --git a/cpu/arm920t/wmt/ttype.h b/cpu/arm920t/wmt/ttype.h
new file mode 100755
index 0000000..68ea47c
--- /dev/null
+++ b/cpu/arm920t/wmt/ttype.h
@@ -0,0 +1,181 @@
+/*++
+Copyright (c) 2010 WonderMedia Technologies, Inc.
+
+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, see http://www.gnu.org/licenses/>.
+
+WonderMedia Technologies, Inc.
+10F, 529, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C.
+--*/
+
+#include <common.h>
+#ifndef __TTYPE_H__
+#define __TTYPE_H__
+
+/******* Common definitions and typedefs ***********************************/
+#ifndef VOID
+#define VOID void
+#endif
+
+#ifndef CONST
+#define CONST const
+#endif
+
+#ifndef STATIC
+#define STATIC static
+#endif
+
+#if !defined(TRUE)
+#define TRUE 1
+#endif
+#if !defined(FALSE)
+#define FALSE 0
+#endif
+
+#if !defined(SUCCESS)
+#define SUCCESS 0
+#endif
+#if !defined(FAILED)
+#define FAILED -1
+#endif
+
+typedef int BOOL;
+
+/****** Simple typedefs ***************************************************/
+typedef char CHAR;
+typedef signed short SHORT;
+typedef signed int INT;
+typedef signed long LONG;
+
+typedef unsigned char UCHAR;
+typedef unsigned short USHORT;
+typedef unsigned int UINT;
+typedef unsigned long ULONG;
+
+#ifndef BYTE
+#define BYTE unsigned char
+#endif
+
+#ifndef WORD
+#define WORD unsigned short
+#endif
+
+#ifndef DWORD
+#define DWORD unsigned long
+#endif
+
+/* QWORD is for those situation that we want */
+/* an 8-byte-aligned 8 byte long structure */
+/* which is NOT really a floating point number. */
+typedef union tagUQuadWord {
+ struct {
+ DWORD dwLowDword;
+ DWORD dwHighDword;
+ } u;
+ double DoNotUseThisField;
+} UQuadWord;
+typedef UQuadWord QWORD; /* 64-bit */
+
+#define U8 unsigned char
+#define U16 unsigned short
+#define USHORT unsigned short
+#define UINT unsigned int
+
+/* flat memory model */
+#if !defined(FAR)
+#define FAR
+#endif
+#if !defined(NEAR)
+#define NEAR
+#endif
+#if !defined(DEF)
+#define DEF
+#endif
+#if !defined(CALLBACK)
+#define CALLBACK
+#endif
+
+/****** Common pointer types ***********************************************/
+typedef signed char *PI8;
+typedef signed short *PI16;
+typedef signed long *PI32;
+
+typedef unsigned char *PU8;
+typedef unsigned short *PU16;
+typedef unsigned long *PU32;
+
+/* boolean pointer */
+typedef int *PBOOL;
+
+typedef int *PINT;
+typedef const int *PCINT;
+
+typedef unsigned int *PUINT;
+typedef const unsigned int *PCUINT;
+
+typedef long *PLONG;
+
+typedef BYTE * PBYTE;
+typedef const BYTE * PCBYTE;
+
+typedef WORD * PWORD;
+typedef const WORD * PCWORD;
+
+typedef DWORD *PDWORD;
+typedef const DWORD *PCDWORD;
+
+typedef QWORD * PQWORD;
+typedef const QWORD * PCQWORD;
+
+/* typedef void *PVOID; */
+typedef void DEF * PVOID;
+typedef void NEAR * NPVOID;
+typedef void FAR * LPVOID;
+
+/*
+ * ANSI (Single-byte Character) types
+ */
+typedef char DEF * PCH;
+typedef char NEAR * NPCH;
+typedef char FAR * LPCH;
+typedef const char DEF * PCCH;
+typedef const char NEAR * NPCCH;
+typedef const char FAR * LPCCH;
+
+typedef char DEF * PSTR;
+typedef char NEAR * NPSTR;
+typedef char FAR * LPSTR;
+typedef const char DEF * PCSTR;
+typedef const char NEAR * NPCSTR;
+typedef const char FAR * LPCSTR;
+
+/*
+typedef char *PCH;
+typedef const char *PCCH;
+
+typedef char *PSTR;
+typedef const char *PCSTR;
+*/
+
+/****** Misc definitions, types ********************************************/
+
+/* parameter prefix */
+#ifndef IN
+#define IN
+#endif
+
+#ifndef OUT
+#define OUT
+#endif
+
+typedef void *HANDLE;
+#define MAX_NET_DEVICE 4
+
+#endif /* __TTYPE_H__ */
diff --git a/cpu/arm920t/wmt/uart.h b/cpu/arm920t/wmt/uart.h
new file mode 100755
index 0000000..52ad0f3
--- /dev/null
+++ b/cpu/arm920t/wmt/uart.h
@@ -0,0 +1,290 @@
+/*
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * Copyright (c) 2008 WonderMedia Technologies, Inc.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ *
+ * WonderMedia Technologies, Inc.
+ * 10F, 529, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C.
+ */
+
+#ifndef __UART_H_
+#define __UART_H_
+
+typedef struct _UART_REG_ {
+ volatile unsigned long URTDR; /* Transmit data register */
+ volatile unsigned long URRDR; /* Receive data register */
+ volatile unsigned long URDIV; /* UART clock divisor & Bard rate divisor */
+ volatile unsigned long URLCR; /* Line control register */
+ volatile unsigned long URICR; /* IrDA control register */
+ volatile unsigned long URIER; /* Interrupt enable register */
+ volatile unsigned long URISR; /* Interrupt status register */
+ volatile unsigned long URUSR; /* Status register */
+ volatile unsigned long URFCR; /* Fifo control register */
+ volatile unsigned long URFIDX; /* Fifo index register */
+ volatile unsigned long URBKR; /* Break signal count value register */
+ volatile unsigned long URTOD; /* UART time out divisor register */
+ volatile unsigned long Resv30_FFF[0x3F4]; /* 0x0030 - 0x0FFF Reserved */
+ volatile unsigned char TXFifo[32]; /* 0x1000 - 0x101F 16x8 bit asynchronous Fifo */
+ volatile unsigned char RXFifo[32]; /* 0x1020 - 0x103F 16x10 bit asynchronous Fifo */
+} UART_REG, *PUART_REG;
+
+/*
+ * (URRDR) Receive Data Regiser Description
+ */
+#define URRDR_PER 0x100 /* Parity Error. This bit is the same as URISR[8] */
+#define URRDR_FER 0x200 /* Frame Error. This bit is the same as URISR[9] */
+
+/*
+ * (URLCR) UART Line Control Register Description
+ */
+#define URLCR_TXEN 0x1 /* Transmit Enable */
+#define URLCR_RXEN 0x2 /* Receive Enable */
+#define URLCR_DLEN8B 0x4 /* Data length 8 bit mode enable */
+#define URLCR_STBLEN2b 0x8 /* 2 Stop bit enable */
+#define URLCR_PYTEN 0x10 /* Parity Enable */
+#define URLCR_PTYODD 0x20 /* Even Parity mode selected */
+#define URLCR_RTS 0x40 /* Request To Send. */
+/* Software control RTS modem signal, used when IrDA is disabled. */
+#define URLCR_LPBEN 0x80 /* Loop Back enable */
+#define URLCR_DMAEN 0x100 /* DMA enable */
+/* 0 : Disable DMA mode */
+/* 1 : Enable UART DMA mode. The UART must be configured in Fifo mode */
+/* if DMA is enabled. */
+#define URLCR_BKINIT 0x200 /* BlueTooth break signal initiation */
+#define URLCR_PSLVERR 0x400 /* Enable APB interface Error Response */
+
+/*
+ * (URICR) IrDA Control Register Description
+ */
+#define URICR_IREN 0x1 /* Infrared Enable */
+
+/*
+ * (URIER) UART Interrupt Enable Register Description
+ */
+#define URIER_TXDE 0x1 /* Enable TX Data Register Empty Interrupt */
+#define URIER_RXDF 0x2 /* Enable RX Data Register Full Interrupt */
+#define URIER_TXFAE 0x4 /* Enable TX Fifo Almost Empty Interrupt(Threshold) */
+#define URIER_TXFE 0x8 /* Enable TX Fifo Empty Interrupt */
+#define URIER_RXFAF 0x10 /* Enable Rx Fifo Almost Full Interrupt(Threshold) */
+#define URIER_RXFF 0x20 /* Enable Rx Fifo Full Interrupt */
+#define URIER_TXDUDR 0x40 /* Enable for TX Under Run Interrupt */
+#define URIER_RXDOVER 0x80 /* Enable for Rx Over Run Interrupt */
+#define URIER_PER 0x100 /* Enable for Parity Error Interrupt */
+#define URIER_FER 0x200 /* Enable for Frame Error Interrupt */
+#define URIER_MODM 0x400 /* Enable for Modem control signal - CTS interrupt */
+#define URIER_RXTOUT 0x800 /* Enable for Receive TimeOut Interrupt */
+#define URIER_BK 0x1000 /* Enable for Break Signal Done Interrupt */
+#define URIER_ERR 0x2000 /* Enable for APB Error Respone Interrupt */
+
+/*
+ * (URISR) UART Interrupt Status Register Description
+ */
+#define URISR_TXDE 0x1 /* TX Data Register Empty */
+#define URISR_RXDF 0x2 /* RX Data Register Full */
+#define URISR_TXFAE 0x4 /* TX Fifo Almost Empty(Threshold) */
+#define URISR_TXFE 0x8 /* TX Fifo Empty */
+#define URISR_RXFAF 0x10 /* Rx Fifo Almost Full (Threshold) */
+#define URISR_RXFF 0x20 /* Rx Fifo Full */
+#define URISR_TXDUDR 0x40 /* TX Under Run */
+#define URISR_RXDOVER 0x80 /* Rx Over Run */
+#define URISR_PER 0x100 /* Parity Error */
+#define URISR_FER 0x200 /* Frame Error */
+#define URISR_MODM 0x400 /* Modem control signal */
+#define URISR_RXTOUT 0x800 /* Receive TimeOut */
+#define URISR_BK 0x1000 /* Break Signal Done */
+#define URISR_ERR 0x2000 /* APB Error Respone */
+
+/*
+ * (URUSR) UART Status Register Description
+ */
+#define URUSR_TXON 0x1 /* Transmitter On */
+#define URUSR_TXDBSY 0x2 /* Transmitter Busy */
+#define URUSR_RXON 0x4 /* Receiver On */
+#define URUSR_RXDRDY 0x8 /* Receiver Ready */
+#define URUSR_CTS 0x10 /* Clear To Send Current status of CTS signal */
+
+/*
+ * (URFCR) UART Fifo Control Register Description
+ */
+#define URFCR_FIFOEN 0x1 /* Fifo Enable */
+#define URFCR_TRAIL 0x2 /* RX Fifo Trailing data flush */
+#define URFCR_TXFRST 0x4 /* TX Fifo Reset */
+#define URFCR_RXFRST 0x8 /* Rx Fifo Reset */
+#define URFCR_TXFLV_0 0x0000
+#define URFCR_TXFLV_1 0x0010
+#define URFCR_TXFLV_2 0x0020
+#define URFCR_TXFLV_3 0x0030
+#define URFCR_TXFLV_4 0x0040
+#define URFCR_TXFLV_5 0x0050
+#define URFCR_TXFLV_6 0x0060
+#define URFCR_TXFLV_7 0x0070
+#define URFCR_TXFLV_8 0x0080
+#define URFCR_TXFLV_9 0x0090
+#define URFCR_TXFLV_10 0x00A0
+#define URFCR_TXFLV_11 0x00B0
+#define URFCR_TXFLV_12 0x00C0
+#define URFCR_TXFLV_13 0x00D0
+#define URFCR_TXFLV_14 0x00E0
+#define URFCR_TXFLV_15 0x00F0
+#define UFFCR_RXFLV_0 0x0000
+#define UFFCR_RXFLV_1 0x0100
+#define UFFCR_RXFLV_2 0x0200
+#define UFFCR_RXFLV_3 0x0300
+#define UFFCR_RXFLV_4 0x0400
+#define UFFCR_RXFLV_5 0x0500
+#define UFFCR_RXFLV_6 0x0600
+#define UFFCR_RXFLV_7 0x0700
+#define UFFCR_RXFLV_8 0x0800
+#define UFFCR_RXFLV_9 0x0900
+#define UFFCR_RXFLV_10 0x0A00
+#define UFFCR_RXFLV_11 0x0B00
+#define UFFCR_RXFLV_12 0x0C00
+#define UFFCR_RXFLV_13 0x0D00
+#define UFFCR_RXFLV_14 0x0E00
+#define UFFCR_RXFLV_15 0x0F00
+
+/*
+ * UART Controller Constant Definition
+ */
+#define UART_BR_921K6 0x10000 /* Uart Baud Rate Setting into 921.6KHz */
+#define UART_BR_460K8 0x10001 /* Uart Baud Rate Setting into 468.8KHz */
+#define UART_BR_230K4 0x10003 /* Uart Baud Rate Setting into 230.4KHz */
+#define UART_BR_115K2 0x10007 /* Uart Baud Rate Setting into 115.2KHz */
+#define UART_BR_57K6 0x1000F /* Uart Baud Rate Setting into 57.6KHz */
+#define UART_BR_38K4 0x2000F /* Uart Baud Rate Setting into 38.4KHz */
+#define UART_BR_28K8 0x1001F /* Uart Baud Rate Setting into 28.8KHz */
+#define UART_BR_19K2 0x2001F /* Uart Baud Rate Setting into 19.2KHz */
+#define UART_BR_14K4 0x1003F /* Uart Baud Rate Setting into 14.4KHz */
+#define UART_BR_9K6 0x2003F /* Uart Baud Rate Setting into 9.6KHz */
+#define UART_BR_7K2 0x1007F /* Uart Baud Rate Setting into 7.2KHz */
+#define UART_BR_3K6 0x100FF /* Uart Baud Rate Setting into 3.6KHz */
+
+#define UART_BK_921K6 3775 /* Uart Break Signal Count Setting into 921.6KHz */
+#define UART_BK_460K8 1920 /* Uart Break Signal Count Setting into 468.8KHz */
+#define UART_BK_230K4 944 /* Uart Break Signal Count Setting into 230.4KHz */
+#define UART_BK_115K2 472 /* Uart Break Signal Count Setting into 115.2KHz */
+#define UART_BK_57K6 236 /* Uart Break Signal Count Setting into 57.6KHz */
+#define UART_BK_38K4 157 /* Uart Break Signal Count Setting into 38.4KHz */
+#define UART_BK_28K8 118 /* Uart Break Signal Count Setting into 28.8KHz */
+#define UART_BK_19K2 79 /* Uart Break Signal Count Setting into 19.2KHz */
+#define UART_BK_14K4 59 /* Uart Break Signal Count Setting into 14.4KHz */
+#define UART_BK_9K6 39 /* Uart Break Signal Count Setting into 9.6KHz */
+#define UART_BK_7K2 30 /* Uart Break Signal Count Setting into 7.2KHz */
+#define UART_BK_3K6 15 /* Uart Break Signal Count Setting into 3.6KHz */
+
+#define BR_921K6 921600 /* 921.6KHz */
+#define BR_460K8 460800 /* 468.8KHz */
+#define BR_230K4 230400 /* 230.4KHz */
+#define BR_115K2 115200 /* 115.2KHz */
+#define BR_57K6 57600 /* 57.6KHz */
+#define BR_38K4 38400 /* 3.8.4KHz */
+#define BR_28K8 28800 /* 28.8KHz */
+#define BR_19K2 19200 /* 19.2KHz */
+#define BR_14K4 14400 /* 14.4KHz */
+#define BR_9K6 9600 /* 9.6KHz */
+#define BR_7K2 7200 /* 7.2KHz */
+#define BR_3K6 3600 /* 3.6KHz */
+
+/* #define UART_CLK_SOURCE 24000000 */
+
+/*
+ * UART Function Return Status Constant Definitions
+ */
+#define UR_SUCCESS 0x0 /* return success */
+#define UR_FAIL 0xFFFFFFFF /* return fail */
+#define UR_RXNOTRDY 0x2 /* return RX not Ready */
+#define UART0 0
+#define UART1 1
+
+/*
+ * UART Public functions declaration
+ *
+ * Defined in uart.c
+ */
+ulong
+init_uart(
+ uchar control_number,
+ ulong baud_rate
+ );
+
+ulong
+set_uart_DMA_mode(
+ uchar control_number
+ );
+
+ulong
+set_uart_fifo_mode(
+ uchar control_number
+ );
+
+ulong
+set_uart_reg_mode(
+ uchar control_number
+ );
+
+ulong
+get_ch_from_uart(
+ uchar control_number
+ );
+
+ulong
+write_ch_to_uart(
+ uchar control_number,
+ uchar ch
+ );
+
+ulong
+get_ch_from_uart_fifo(
+ uchar control_number
+ );
+
+ulong
+write_ch_to_uart_fifo(
+ uchar control_number,
+ uchar ch
+ );
+
+ulong
+uart_loopback_mode(
+ uchar control_number,
+ uchar enable
+ );
+
+/*
+ * Defined in the uartif.c
+ */
+void
+uart_initialization(
+ int FunctionNumber
+ );
+
+void uart_startio(void);
+
+void
+ugets(
+ char *p_dest,
+ int len
+ );
+
+void
+uputs(
+ char *str
+ );
+
+void
+uprintf(
+ char *format, ...
+ );
+
+#endif /* __UART_H_ */
diff --git a/cpu/arm920t/wmt/uassert.h b/cpu/arm920t/wmt/uassert.h
new file mode 100755
index 0000000..782704e
--- /dev/null
+++ b/cpu/arm920t/wmt/uassert.h
@@ -0,0 +1,79 @@
+/*++
+Copyright (c) 2010 WonderMedia Technologies, Inc.
+
+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, see http://www.gnu.org/licenses/>.
+
+WonderMedia Technologies, Inc.
+10F, 529, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C.
+--*/
+
+#ifndef __UASSERT_H__
+#define __UASSERT_H__
+
+#if !defined(__TTYPE_H__)
+#include "ttype.h"
+#endif
+
+/*--------------------- Export Definitions -------------------------*/
+
+/* if not define _DEBUG, then DBG_ASSERT will be null */
+#ifndef _DEBUG
+/* translate ASSERT(f) to empty space */
+#define DBG_ASSERT(f)
+#define DBG_ASSERT_VALID(f)
+#else /* _DEBUG */
+/* translate ASSERT(f) to c function call */
+#define DBG_ASSERT(f)
+#define DBG_ASSERT_VALID(p)
+#endif /* _DEBUG */
+
+/* if (_DEBUG) then (_DEBUG_LOUD) */
+#ifndef _DEBUG
+#define DBG_PRN(arg)
+#else /* _DEBUG */
+#define _DEBUG_LOUD
+#define DBG_PRN(arg) {DbgPrint("***** "); DbgPrint arg ; }
+#endif /* _DEBUG */
+
+#ifndef _DEBUG_LOUD
+#define DBG_PRN_LOUD(arg)
+#else /* _DEBUG_LOUD */
+#define DBG_PRN_LOUD(arg) {DbgPrint("##### "); DbgPrint arg ; }
+#endif /* _DEBUG_LOUD */
+
+#ifndef _DEBUG_PORT80
+#define DBG_IMM_PORT80(handle, value)
+#define DBG_PORT80(value)
+#else /* _DEBUG_PORT80 */
+#define DBG_IMM_PORT80(handle, value) NdisImmediateWritePortUchar(handle, 0x80, value);
+#define DBG_PORT80(value) NdisRawWritePortUchar(0x80, value);
+#endif /* _DEBUG_PORT80 */
+
+#ifndef _DEBUG_PORT80_ALWAYS
+#define DBG_PORT80_ALWAYS(value)
+#else /* _DEBUG_PORT80_ALWAYS */
+#define DBG_PORT80_ALWAYS(value) NdisRawWritePortUchar(0x80, value);
+#endif /* _DEBUG_PORT80_ALWAYS */
+
+#ifndef _DEBUG_BREAK
+#define DBG_BRK()
+#else /* _DEBUG_BREAK */
+#define DBG_BRK() { ASM{ int 3 } }
+#endif /* _DEBUG_BREAK */
+
+/*--------------------- Export Classes ----------------------------*/
+
+/*--------------------- Export Variables --------------------------*/
+
+/*--------------------- Export Functions --------------------------*/
+
+#endif /* __UASSERT_H__ */
diff --git a/cpu/arm920t/wmt/upc.h b/cpu/arm920t/wmt/upc.h
new file mode 100755
index 0000000..87373aa
--- /dev/null
+++ b/cpu/arm920t/wmt/upc.h
@@ -0,0 +1,94 @@
+/*++
+Copyright (c) 2010 WonderMedia Technologies, Inc.
+
+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, see http://www.gnu.org/licenses/>.
+
+WonderMedia Technologies, Inc.
+10F, 529, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C.
+--*/
+
+
+#ifndef __UPC_H__
+#define __UPC_H__
+
+#if !defined(__TTYPE_H__)
+#include "ttype.h"
+#endif
+
+/*--------------------- Export Definitions -------------------------*/
+#define INTERRUPT void
+typedef INTERRUPT(*PISR)(void);
+/*--------------------- Export Classes ----------------------------*/
+
+/*--------------------- Export Variables --------------------------*/
+
+/*--------------------- Export Functions --------------------------*/
+#if defined(__cplusplus)
+extern "C" { /* Assume C declarations for C++ */
+#endif /* __cplusplus */
+
+/* WMT Device do Memory-Mapped IO when in 32-bit environment */
+#define VNSvInPortB(dwIOAddress, pbyData) \
+do { \
+ volatile BYTE *pbyAddr = ((PBYTE)(dwIOAddress)); \
+ *(pbyData) = *pbyAddr; \
+} while (0)
+
+#define VNSvInPortW(dwIOAddress, pwData) \
+do { \
+ volatile WORD *pwAddr = ((PWORD)(dwIOAddress)); \
+ *(pwData) = *pwAddr; \
+} while (0)
+
+#define VNSvInPortD(dwIOAddress, pdwData) \
+do { \
+ volatile DWORD *pdwAddr = ((PDWORD)(dwIOAddress)); \
+ *(pdwData) = *pdwAddr; \
+} while (0)
+
+#define VNSvOutPortB(dwIOAddress, byData) \
+do { \
+ volatile BYTE *pbyTmp = (PBYTE)(dwIOAddress); \
+ *pbyTmp = (byData); \
+} while (0)
+
+#define VNSvOutPortW(dwIOAddress, wData) \
+do { \
+ volatile WORD *pwTmp = (PWORD)(dwIOAddress); \
+ *pwTmp = (wData); \
+} while (0)
+
+#define VNSvOutPortD(dwIOAddress, dwData) \
+do { \
+ volatile DWORD *pdwTmp = (PDWORD)(dwIOAddress); \
+ *pdwTmp = (dwData); \
+} while (0)
+
+#define PCAvDelayByIO(wDelayUnit) \
+do { \
+ BYTE byTemp; \
+ ULONG ii; \
+ for (ii = 0; ii < (wDelayUnit); ii++) \
+ VNSvInPortB(0x0, &byTemp); \
+} while (0)
+
+#define PCBvInPortB VNSvInPortB
+#define PCBvInPortW VNSvInPortW
+#define PCBvInPortD VNSvInPortD
+#define PCBvOutPortB VNSvOutPortB
+#define PCBvOutPortW VNSvOutPortW
+#define PCBvOutPortD VNSvOutPortD
+
+#if defined(__cplusplus)
+} /* End of extern "C" { */
+#endif /* __cplusplus */
+
+#endif /* __UPC_H__ */
diff --git a/cpu/arm920t/wmt/upci.h b/cpu/arm920t/wmt/upci.h
new file mode 100755
index 0000000..7eb2e9a
--- /dev/null
+++ b/cpu/arm920t/wmt/upci.h
@@ -0,0 +1,78 @@
+/*++
+Copyright (c) 2010 WonderMedia Technologies, Inc.
+
+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, see http://www.gnu.org/licenses/>.
+
+WonderMedia Technologies, Inc.
+10F, 529, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C.
+--*/
+
+#ifndef __UPCI_H__
+#define __UPCI_H__
+
+#if !defined(__UPCIX_H__)
+#include "upcix.h"
+#endif
+
+/*--------------------- Export Definitions -------------------------*/
+
+/*--------------------- Export Types ------------------------------*/
+
+/*--------------------- Export Macros ------------------------------*/
+
+#define PCIvReadConfigB(pvHandle, wBusDevFunId, byRegOffset, pbyData) \
+{ \
+ PCIXvReadB(wBusDevFunId, byRegOffset, pbyData); \
+}
+
+#define PCIvReadConfigW(pvHandle, wBusDevFunId, byRegOffset, pwData) \
+{ \
+ PCIXvReadW(wBusDevFunId, byRegOffset, pwData); \
+}
+
+#define PCIvReadConfigD(pvHandle, wBusDevFunId, byRegOffset, pdwData) \
+{ \
+ PCIXvReadD(wBusDevFunId, byRegOffset, pdwData); \
+}
+
+#define PCIvWriteConfigB(pvHandle, wBusDevFunId, byRegOffset, byData) \
+{ \
+ PCIXvWriteB(wBusDevFunId, byRegOffset, byData); \
+}
+
+#define PCIvWriteConfigW(pvHandle, wBusDevFunId, byRegOffset, wData) \
+{ \
+ PCIXvWriteW(wBusDevFunId, byRegOffset, wData); \
+}
+
+#define PCIvWriteConfigD(pvHandle, wBusDevFunId, byRegOffset, dwData) \
+{ \
+ PCIXvWriteD(wBusDevFunId, byRegOffset, dwData); \
+}
+
+#define PCIvReadConfigManyBytes(pvHandle, wBusDevFunId, byRegOffset, pbyBuffer, byCount) \
+{ \
+ PCIXvReadManyBytes(wBusDevFunId, byRegOffset, pbyBuffer, byCount); \
+}
+
+#define PCIbFindConfigDeviceInfo(dwDevVenID, pbyBusNum, pbySlotNum, pbyFuncNum, pbyRevId, \
+ pdwIoBase, pdwIoSpaceRange, pbyIrqNo) \
+ (PCIXbFindDeviceInfo(dwDevVenID, pbyBusNum, pbySlotNum, pbyFuncNum, pbyRevId, pdwIoBase, \
+ pdwIoSpaceRange, pbyIrqNo))
+
+/*--------------------- Export Classes ----------------------------*/
+
+/*--------------------- Export Variables --------------------------*/
+
+/*--------------------- Export Functions --------------------------*/
+
+#endif /* __UPCI_H__ */
diff --git a/cpu/arm920t/wmt/upcix.c b/cpu/arm920t/wmt/upcix.c
new file mode 100755
index 0000000..bee3903
--- /dev/null
+++ b/cpu/arm920t/wmt/upcix.c
@@ -0,0 +1,194 @@
+/*++
+Copyright (c) 2010 WonderMedia Technologies, Inc.
+
+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, see http://www.gnu.org/licenses/>.
+
+WonderMedia Technologies, Inc.
+10F, 529, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C.
+--*/
+
+#if !defined(__UASSERT_H__)
+#include "uassert.h"
+#endif
+#if !defined(__UPC_H__)
+#include "upc.h"
+#endif
+
+#if !defined(__TMACRO_H__)
+#include "tmacro.h"
+#endif
+#if !defined(__TPCI_H__)
+#include "tpci.h"
+#endif
+#if !defined(__UPCIX_H__)
+#include "upcix.h"
+#endif
+#if !defined(__TBIT_H__)
+#include "tbit.h"
+#endif
+
+/*--------------------- Static Definitions -------------------------*/
+
+/* PCI configuration space IO port */
+#define PCI_INDEX 0xC0000CF8
+#define PCI_DATA 0xC0000CFC
+
+/*--------------------- Static Classes ----------------------------*/
+
+/*--------------------- Static Variables --------------------------*/
+
+/*--------------------- Static Functions --------------------------*/
+
+/*--------------------- Export Variables --------------------------*/
+
+/*--------------------- Import Functions --------------------------*/
+
+VOID PCIXvReadB(WORD wBusDevFunId, BYTE byRegOffset, PBYTE pbyData)
+{
+ DWORD dwIndex;
+
+ dwIndex = wBusDevFunId;
+ dwIndex = 0x80000000L | (dwIndex << 8) | (byRegOffset & 0xFC);
+
+ PCBvOutPortD(PCI_INDEX, dwIndex);
+ PCBvInPortB(PCI_DATA + (byRegOffset % 4), pbyData);
+}
+
+VOID PCIXvReadW(WORD wBusDevFunId, BYTE byRegOffset, PWORD pwData)
+{
+ DWORD dwIndex;
+
+ /* must word alignment */
+ DBG_ASSERT((byRegOffset % 2) == 0);
+
+ dwIndex = wBusDevFunId;
+ dwIndex = 0x80000000L | (dwIndex << 8) | (byRegOffset & 0xFC);
+
+ PCBvOutPortD(PCI_INDEX, dwIndex);
+ PCBvInPortW(PCI_DATA + (byRegOffset % 4), pwData);
+}
+
+VOID PCIXvReadD(WORD wBusDevFunId, BYTE byRegOffset, PDWORD pdwData)
+{
+ DWORD dwIndex;
+
+ /* must dword alignment */
+ DBG_ASSERT((byRegOffset % 4) == 0);
+
+ dwIndex = wBusDevFunId;
+ dwIndex = 0x80000000L | (dwIndex << 8) | (byRegOffset & 0xFC);
+
+ PCBvOutPortD(PCI_INDEX, dwIndex);
+ PCBvInPortD(PCI_DATA, pdwData);
+}
+
+VOID PCIXvWriteB(WORD wBusDevFunId, BYTE byRegOffset, BYTE byData)
+{
+ DWORD dwIndex;
+
+ dwIndex = wBusDevFunId;
+ dwIndex = 0x80000000L | (dwIndex << 8) | (byRegOffset & 0xFC);
+
+ PCBvOutPortD(PCI_INDEX, dwIndex);
+ PCBvOutPortB(PCI_DATA + (byRegOffset % 4), byData);
+}
+
+VOID PCIXvWriteW(WORD wBusDevFunId, BYTE byRegOffset, WORD wData)
+{
+ DWORD dwIndex;
+
+ /* must word alignment */
+ DBG_ASSERT((byRegOffset % 2) == 0);
+
+ dwIndex = wBusDevFunId;
+ dwIndex = 0x80000000L | (dwIndex << 8) | (byRegOffset & 0xFC);
+
+ PCBvOutPortD(PCI_INDEX, dwIndex);
+ PCBvOutPortW(PCI_DATA + (byRegOffset % 4), wData);
+}
+
+VOID PCIXvWriteD(WORD wBusDevFunId, BYTE byRegOffset, DWORD dwData)
+{
+ DWORD dwIndex;
+
+ /* must dword alignment */
+ DBG_ASSERT((byRegOffset % 4) == 0);
+
+ dwIndex = wBusDevFunId;
+ dwIndex = 0x80000000L | (dwIndex << 8) | (byRegOffset & 0xFC);
+
+ PCBvOutPortD(PCI_INDEX, dwIndex);
+ PCBvOutPortD(PCI_DATA, dwData);
+}
+
+VOID PCIXvReadManyBytes(WORD wBusDevFunId, BYTE byRegOffset, PBYTE pbyBuffer, WORD wCount)
+{
+ WORD wIdx;
+ PBYTE pbyTmpBuf = pbyBuffer;
+
+ for (wIdx = 0; wIdx < wCount; wIdx++, pbyTmpBuf++)
+ PCIXvReadB(wBusDevFunId, (BYTE)(byRegOffset + wIdx), pbyTmpBuf);
+}
+
+BOOL PCIXbFindDeviceInfo(DWORD dwDevVenID, PBYTE pbyBusNum,
+ PBYTE pbySlotNum, PBYTE pbyFuncNum, PBYTE pbyRevId, PDWORD pdwIoBase,
+ PDWORD pdwIoSpaceRange, PBYTE pbyIrqNo)
+{
+ DWORD dwCurrDevVenID;
+ BYTE byBusNum = *pbyBusNum;
+ BYTE bySlotNum = *pbySlotNum;
+ BYTE byFuncNum = *pbyFuncNum;
+ BOOL bMultiFunc;
+ BYTE byData;
+ int i;
+
+ for (i = byBusNum; i < MAX_PCI_BUS; i++) {
+ byBusNum = (BYTE)i;
+
+ for ( ; bySlotNum < MAX_PCI_DEVICE; bySlotNum++) {
+ PCIXvReadB(MAKE_BDF_TO_WORD(byBusNum, bySlotNum, 0), PCI_REG_HDR_TYPE, &byData);
+ bMultiFunc = BITbIsAllBitsOn(byData, 0x80);
+
+ for ( ; byFuncNum < ((bMultiFunc) ? 8 : 1); byFuncNum++) {
+ PCIXvReadD(MAKE_BDF_TO_WORD(byBusNum, bySlotNum, byFuncNum),
+ PCI_REG_VENDOR_ID, &dwCurrDevVenID);
+
+ /* is this our device? */
+ if (dwCurrDevVenID == dwDevVenID) {
+ PCIXvReadB(MAKE_BDF_TO_WORD(byBusNum, bySlotNum, byFuncNum),
+ PCI_REG_REV_ID, pbyRevId);
+ PCIXvReadD(MAKE_BDF_TO_WORD(byBusNum, bySlotNum, byFuncNum),
+ PCI_REG_BAR0, pdwIoBase);
+ *pdwIoBase = (*pdwIoBase) & 0xFFFFFFFEUL;
+
+ /* IO space range: */
+ /* 43:0x80(128B), 65:0x100(256B) */
+ if (*pbyRevId < 0x40)
+ *pdwIoSpaceRange = 0x00000080L;
+ else
+ *pdwIoSpaceRange = 0x00000100L;
+
+ PCIXvReadB(MAKE_BDF_TO_WORD(byBusNum, bySlotNum, byFuncNum),
+ PCI_REG_INT_LINE, pbyIrqNo);
+ *pbyBusNum = byBusNum;
+ *pbySlotNum = bySlotNum;
+ *pbyFuncNum = byFuncNum;
+ return TRUE;
+ }
+ }
+ byFuncNum = 0;
+ }
+ bySlotNum = 0;
+ }
+
+ return FALSE;
+}
diff --git a/cpu/arm920t/wmt/upcix.h b/cpu/arm920t/wmt/upcix.h
new file mode 100755
index 0000000..ac62be7
--- /dev/null
+++ b/cpu/arm920t/wmt/upcix.h
@@ -0,0 +1,59 @@
+/*++
+Copyright (c) 2010 WonderMedia Technologies, Inc.
+
+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, see http://www.gnu.org/licenses/>.
+
+WonderMedia Technologies, Inc.
+10F, 529, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C.
+--*/
+
+#ifndef __UPCIX_H__
+#define __UPCIX_H__
+
+#if !defined(__TTYPE_H__)
+#include "ttype.h"
+#endif
+
+/*--------------------- Export Definitions -------------------------*/
+
+/*--------------------- Export Types ------------------------------*/
+
+/*--------------------- Export Macros ------------------------------*/
+
+/*--------------------- Export Classes ----------------------------*/
+
+/*--------------------- Export Variables --------------------------*/
+
+/*--------------------- Export Functions --------------------------*/
+
+#ifdef __cplusplus
+extern "C" { /* Assume C declarations for C++ */
+#endif /* __cplusplus */
+
+VOID PCIXvReadB(WORD wBusDevFunId, BYTE byRegOffset, PBYTE pbyData);
+VOID PCIXvReadW(WORD wBusDevFunId, BYTE byRegOffset, PWORD pwData);
+VOID PCIXvReadD(WORD wBusDevFunId, BYTE byRegOffset, PDWORD pdwData);
+VOID PCIXvWriteB(WORD wBusDevFunId, BYTE byRegOffset, BYTE byData);
+VOID PCIXvWriteW(WORD wBusDevFunId, BYTE byRegOffset, WORD wData);
+VOID PCIXvWriteD(WORD wBusDevFunId, BYTE byRegOffset, DWORD dwData);
+
+VOID PCIXvReadManyBytes(WORD wBusDevFunId, BYTE byRegOffset, PBYTE pbyBuffer, WORD wCount);
+
+BOOL PCIXbFindDeviceInfo(DWORD dwDevVenID, PBYTE pbyBusNum,
+ PBYTE pbySlotNum, PBYTE pbyFuncNum, PBYTE pbyRevId, PDWORD pdwIoBase,
+ PDWORD pdwIoSpaceRange, PBYTE pbyIrqNo);
+
+#ifdef __cplusplus
+} /* End of extern "C" { */
+#endif /* __cplusplus */
+
+#endif /* __UPCIX_H__ */
diff --git a/cpu/arm920t/wmt/version.h b/cpu/arm920t/wmt/version.h
new file mode 100755
index 0000000..560432f
--- /dev/null
+++ b/cpu/arm920t/wmt/version.h
@@ -0,0 +1,41 @@
+/*++
+Copyright (c) 2010 WonderMedia Technologies, Inc.
+
+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, see http://www.gnu.org/licenses/>.
+
+WonderMedia Technologies, Inc.
+10F, 529, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C.
+--*/
+
+#ifndef __VERSION_H__
+#define __VERSION_H__
+
+/*--------------------- Export Definitions -------------------------*/
+#define SZ_DRIVER_VERSION "1.34"
+#define SZ_DRIVER_BUILD_NUMBER "0045"
+
+#define SZ_ADAPTER_NAME "VIA Networking Velocity Family Gigabit Ethernet Adapter "
+#define SZ_CHIP3119A "VT6110 "
+#define SZ_CHIP3216A "VT6120/VT6122 "
+#define SZ_CHIP3216A64 "VT6121 "
+#define SZ_CHIP3286AQFP "VT6132 "
+#define SZ_CHIP3286AQFN "VT6130 "
+
+#define ADAPTER_NAME_LEN 65
+
+/*--------------------- Export Classes ----------------------------*/
+
+/*--------------------- Export Variables --------------------------*/
+
+/*--------------------- Export Functions --------------------------*/
+
+#endif /* __VERSION_H__ */
diff --git a/cpu/arm920t/wmt/vpci.c b/cpu/arm920t/wmt/vpci.c
new file mode 100755
index 0000000..76d2ef4
--- /dev/null
+++ b/cpu/arm920t/wmt/vpci.c
@@ -0,0 +1,170 @@
+/*++
+Copyright (c) 2010 WonderMedia Technologies, Inc.
+
+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, see http://www.gnu.org/licenses/>.
+
+WonderMedia Technologies, Inc.
+10F, 529, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C.
+--*/
+
+
+#if !defined(__UPC_H__)
+#include "upc.h"
+#endif
+#if !defined(__MAC_H__)
+#include "mac.h"
+#endif
+#if !defined(__VPCI_H__)
+#include "vpci.h"
+#endif
+
+#if !defined(__PCINET_H__)
+#include "pcinet.h"
+#endif
+
+/*--------------------- Static Definitions -------------------------*/
+
+/*--------------------- Static Classes ----------------------------*/
+
+/*--------------------- Static Variables --------------------------*/
+
+/*--------------------- Static Functions --------------------------*/
+
+/*--------------------- Export Variables --------------------------*/
+
+/*--------------------- Export Functions --------------------------*/
+VOID
+VPCIvInitialize(
+ DWORD dwIoBase,
+ BYTE byRevId
+ )
+{
+ /* PATCH.... turn this on to avoid retry forever */
+ VPCIvRegBitsOn(dwIoBase, PCI_REG_MODE2, MODE2_PCEROPT);
+ /* PATCH.... */
+ /* for some legacy BIOS and OS don't open BusM */
+ /* bit in PCI configuration space. So, turn it on. */
+ VPCIvRegBitsOn(dwIoBase, PCI_REG_COMMAND, COMMAND_BUSM);
+ /* PATCH.... turn this on to detect MII coding error */
+ VPCIvRegBitsOn(dwIoBase, PCI_REG_MODE3, MODE3_MIION);
+}
+
+VOID
+VPCIvReadB(
+ DWORD dwIoBase,
+ BYTE byRegOffset,
+ PBYTE pbyData
+ )
+{
+ DWORD dwPCICfgAddr;
+
+
+ dwPCICfgAddr = dwIoBase + PCI_CFG_SPACE_OFFSET;
+ VNSvInPortB(dwPCICfgAddr + byRegOffset, pbyData);
+}
+
+VOID
+VPCIvReadW(
+ DWORD dwIoBase,
+ BYTE byRegOffset,
+ PWORD pwData
+ )
+{
+ DWORD dwPCICfgAddr;
+
+
+ dwPCICfgAddr = dwIoBase + PCI_CFG_SPACE_OFFSET;
+ VNSvInPortW(dwPCICfgAddr + byRegOffset, pwData);
+}
+
+VOID
+VPCIvReadD(
+ DWORD dwIoBase,
+ BYTE byRegOffset,
+ PDWORD pdwData
+ )
+{
+ DWORD dwPCICfgAddr;
+
+
+ dwPCICfgAddr = dwIoBase + PCI_CFG_SPACE_OFFSET;
+ VNSvInPortD(dwPCICfgAddr + byRegOffset, pdwData);
+}
+
+VOID
+VPCIvRegBitsOn(
+ DWORD dwIoBase,
+ BYTE byRegOffset,
+ BYTE byBits
+ )
+{
+ BYTE byOrgData;
+
+
+ VPCIvReadB(dwIoBase, byRegOffset, &byOrgData);
+ VPCIvWriteB(dwIoBase, byRegOffset, (BYTE)(byOrgData | byBits));
+}
+
+VOID
+VPCIvRegBitsOff(
+ DWORD dwIoBase,
+ BYTE byRegOffset,
+ BYTE byBits
+ )
+{
+ BYTE byOrgData;
+
+
+ VPCIvReadB(dwIoBase, byRegOffset, &byOrgData);
+ VPCIvWriteB(dwIoBase, byRegOffset, (BYTE)(byOrgData & ~byBits));
+}
+
+VOID
+VPCIvWriteB(
+ DWORD dwIoBase,
+ BYTE byRegOffset,
+ BYTE byData
+ )
+{
+ DWORD dwPCICfgAddr;
+
+
+ dwPCICfgAddr = dwIoBase + PCI_CFG_SPACE_OFFSET;
+ VNSvOutPortB(dwPCICfgAddr + byRegOffset, byData);
+}
+
+VOID
+VPCIvWriteW(
+ DWORD dwIoBase,
+ BYTE byRegOffset,
+ WORD wData
+ )
+{
+ DWORD dwPCICfgAddr;
+
+
+ dwPCICfgAddr = dwIoBase + PCI_CFG_SPACE_OFFSET;
+ VNSvOutPortW(dwPCICfgAddr + byRegOffset, wData);
+}
+
+VOID
+VPCIvWriteD(
+ DWORD dwIoBase,
+ BYTE byRegOffset,
+ DWORD dwData
+ )
+{
+ DWORD dwPCICfgAddr;
+
+
+ dwPCICfgAddr = dwIoBase + PCI_CFG_SPACE_OFFSET;
+ VNSvOutPortD(dwPCICfgAddr + byRegOffset, dwData);
+}
diff --git a/cpu/arm920t/wmt/vpci.h b/cpu/arm920t/wmt/vpci.h
new file mode 100755
index 0000000..d075f11
--- /dev/null
+++ b/cpu/arm920t/wmt/vpci.h
@@ -0,0 +1,212 @@
+/*++
+Copyright (c) 2010 WonderMedia Technologies, Inc.
+
+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, see http://www.gnu.org/licenses/>.
+
+WonderMedia Technologies, Inc.
+10F, 529, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C.
+--*/
+
+
+#ifndef __VPCI_H__
+#define __VPCI_H__
+
+#if !defined(__TTYPE_H__)
+#include "ttype.h"
+#endif
+
+/*--------------------- Export Definitions -------------------------*/
+#define PCI_CFG_SPACE_OFFSET 0x0100 /* PCI Configuration Space appended after CSR */
+
+/*
+ * Registers in the PCI configuration space
+ */
+#define PCI_REG_VENDOR_ID 0x00
+#define PCI_REG_DEVICE_ID 0x02
+#define PCI_REG_COMMAND 0x04
+#define PCI_REG_STATUS 0x06
+#define PCI_REG_REV_ID 0x08
+#define PCI_REG_CLASS_CODE 0x09
+#define PCI_REG_CACHELINE_SIZE 0x0C
+#define PCI_REG_LAT_TIMER 0x0D
+#define PCI_REG_HDR_TYPE 0x0E
+#define PCI_REG_BIST 0x0F
+
+#define PCI_REG_BAR0 0x10
+#define PCI_REG_BAR1 0x14
+#define PCI_REG_BAR2 0x18
+#define PCI_REG_CARDBUS_CIS_PTR 0x28
+
+#define PCI_REG_SUB_VEN_ID 0x2C
+#define PCI_REG_SUB_SYS_ID 0x2E
+#define PCI_REG_EXP_ROM_BAR 0x30
+#define PCI_REG_CAP 0x34
+
+#define PCI_REG_INT_LINE 0x3C
+#define PCI_REG_INT_PIN 0x3D
+#define PCI_REG_MIN_GNT 0x3E
+#define PCI_REG_MAX_LAT 0x3F
+
+/*
+ * Registers in the PCI configuration space
+ */
+/* #define PCI_REG_MODE0 0x50 // ? */
+#define PCI_REG_MODE0 0x60
+#define PCI_REG_MODE1 0x61
+#define PCI_REG_MODE2 0x62
+#define PCI_REG_MODE3 0x63
+#define PCI_REG_DELAY_TIMER 0x64
+#define PCI_REG_FIFOTST 0x51
+/* #define PCI_REG_MODE2 0x52 // ? */
+/* #define PCI_REG_MODE3 0x53 // ? */
+/* #define PCI_REG_DELAY_TIMER 0x54 // ? */
+#define PCI_REG_FIFOCMD 0x56
+#define PCI_REG_FIFOSTA 0x57
+#define PCI_REG_BNRY 0x58
+#define PCI_REG_CURR 0x5A
+#define PCI_REG_FIFO_DATA 0x5C
+
+#define PCI_REG_MAX_SIZE 0x100 /* maximun total PCI registers */
+
+/*
+ * Registers for power management (offset)
+ */
+/* #define PCI_REG_PM_BASE 0x40 // ? */
+#define PCI_REG_PM_BASE 0x50
+#define PM_CAP_ID 0x00
+#define PM_NEXT_ITEM_PTR 0x01
+#define PM_PMC0 0x02
+#define PM_PMC1 0x03
+#define PM_PMCSR0 0x04
+#define PM_PMCSR1 0x05
+#define PM_CSR_BSE 0x06
+#define PM_DATA 0x07
+
+/*
+ * Bits in the COMMAND register
+ */
+#define COMMAND_BUSM 0x04
+
+/*
+ * Bits in the MODE0 register
+ */
+#define MODE0_QPKTDS 0x80
+
+/*
+ * Bits in the MODE2 register
+ */
+#define MODE2_PCEROPT 0x80 /* VT3065 only */
+#define MODE2_DISABT 0x40
+#define MODE2_MODE10T 0x02
+
+/*
+ * Bits in the MODE3 register
+ */
+#define MODE3_XONOPT 0x80
+#define MODE3_TPACEN 0x40
+#define MODE3_BACKOPT 0x20
+#define MODE3_DLTSEL 0x10
+#define MODE3_MIIDMY 0x08
+#define MODE3_MIION 0x04
+
+/*
+ * Bits in PMCSR0 register
+ */
+#define PMCSR0_PW_STAT1 0x02
+#define PMCSR0_PW_STAT0 0x01
+
+/*
+ * Bits in PMCSR1 register
+ */
+#define PMCSR1_PME_STATUS 0x80
+#define PMCSR1_PME_EN 0x01
+
+/*--------------------- Export Types ------------------------------*/
+
+/*--------------------- Export Macros ------------------------------*/
+
+/*--------------------- Export Classes ----------------------------*/
+
+/*--------------------- Export Variables --------------------------*/
+
+/*--------------------- Export Functions --------------------------*/
+
+#ifdef __cplusplus
+extern "C" { /* Assume C declarations for C++ */
+#endif /* __cplusplus */
+
+VOID
+VPCIvInitialize(
+ DWORD dwIoBase,
+ BYTE byRevId
+ );
+
+VOID
+VPCIvReadB(
+ DWORD dwIoBase,
+ BYTE byRegOffset,
+ PBYTE pbyData
+ );
+
+VOID
+VPCIvReadW(
+ DWORD dwIoBase,
+ BYTE byRegOffset,
+ PWORD pwData
+ );
+
+VOID
+VPCIvReadD(
+ DWORD dwIoBase,
+ BYTE byRegOffset,
+ PDWORD pdwData
+ );
+
+VOID
+VPCIvRegBitsOn(
+ DWORD dwIoBase,
+ BYTE byRegOffset,
+ BYTE byBits
+ );
+
+VOID
+VPCIvRegBitsOff(
+ DWORD dwIoBase,
+ BYTE byRegOffset,
+ BYTE byBits
+ );
+
+VOID
+VPCIvWriteB(
+ DWORD dwIoBase,
+ BYTE byRegOffset,
+ BYTE byData
+ );
+
+VOID
+VPCIvWriteW(
+ DWORD dwIoBase,
+ BYTE byRegOffset,
+ WORD wData
+ );
+
+VOID
+VPCIvWriteD(
+ DWORD dwIoBase,
+ BYTE byRegOffset,
+ DWORD dwData
+ );
+
+#ifdef __cplusplus
+} /* End of extern "C" { */
+#endif /* __cplusplus */
+
+#endif /* __VPCI_H__ */
diff --git a/cpu/arm920t/wmt/zde.c b/cpu/arm920t/wmt/zde.c
new file mode 100755
index 0000000..1009dfc
--- /dev/null
+++ b/cpu/arm920t/wmt/zde.c
@@ -0,0 +1,111 @@
+/*++
+Copyright (c) 2010 WonderMedia Technologies, Inc.
+
+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, see http://www.gnu.org/licenses/>.
+
+WonderMedia Technologies, Inc.
+10F, 529, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C.
+--*/
+
+#include <common.h>
+
+#ifdef CONFIG_ZDE_KERNEL_DEBUG
+
+#define SemiSWI 0x123456
+
+/*************************************************/
+/* Semihosting extension SWI Operating Numbers */
+/*************************************************/
+#define SYS_BOOTLOADOS 0x6002
+
+/*
+ * For manipulate CP15 cache and TLB control register. (R1)
+ */
+#define CR_M (1 << 0) /* MMU enable */
+#define CR_A (1 << 1) /* Alignment abort enable */
+#define CR_C (1 << 2) /* Dcache enable */
+#define CR_W (1 << 3) /* Write buffer enable */
+/* bit[4:7] are reserved */
+#define CR_S (1 << 8) /* System MMU protection */
+#define CR_R (1 << 9) /* ROM MMU protection */
+/* bit[10:11] are reserved */
+#define CR_I (1 << 12) /* Icache enable */
+#define CR_V (1 << 13) /* Vectors relocated to 0xffff0000 */
+/* bit[14:31] are reserved */
+
+typedef struct __semi_sys_bootloados {
+ unsigned int os_type; /* 0x0: normal application; 0x1: Linux */
+ unsigned int board_arch; /* 0x0: Reserved; 0x4A (vt8253C) just pass to kernel R1 */
+ unsigned int kernel_addr; /* kernel address 0xC0008000 */
+ unsigned int rootfs_addr; /* rootfs address 0xC8000000 */
+ unsigned int loading_type; /* 0x0: boot loader handle; 0x1: Host use JTAG download */
+ unsigned int vector_mask; /* 0x0: turn off all to clear all vector */
+ unsigned int is_semihosting; /* 0x0: disable; 0x1: enable */
+} semi_sys_bootloados_t;
+
+/*
+ * Function Name: do_SemiSWI()
+ * Purpose: put op code in r0, put value or pointer in r1, send swi
+ * Return Value: value in r0
+ */
+static inline int do_SemiSWI(int swi_op, void *arg)
+{
+ int value;
+ asm volatile ("mov r0, %1; mov r1, %2; swi %a3; mov %0, r0"
+ : "=r" (value) /* Outputs */
+ : "r" (swi_op), "r" (arg), "i" (SemiSWI) /* Inputs */
+ : "r0", "r1", "r2", "r3", "ip", "lr", "memory", "cc"
+ /* Clobbers r0 and r1, and lr if in supervisor mode */);
+
+ return value;
+}
+
+static void cp15_set_vector_low(void)
+{
+ volatile unsigned int ctrl;
+
+ asm volatile
+ (
+ "mrc p15, 0, %0, c1, c0, 0" : "=r" (ctrl)
+ );
+ ctrl &= ~CR_V;
+ asm volatile
+ (
+ "mcr p15, 0, %0, c1, c0, 0" : : "r" (ctrl)
+ );
+}
+
+/*
+ * Function Name: semi_cbootloados()
+ * Purpose: Send SWI SYS_BOOTLOADOS to notify converter
+ * that we have load kernel and/or ramdisk successfully
+ * Return Value: Void return
+ */
+void semi_bootloados(void)
+{
+ semi_sys_bootloados_t semi_sys_bootloados;
+
+ /* To support ZDE Linux kernel debugging, */
+ /* Ensure vector table is at 0x0 */
+ cp15_set_vector_low();
+
+ semi_sys_bootloados.os_type = 1;
+ semi_sys_bootloados.board_arch = 10002; /* 10002 mean vt3300 */
+ semi_sys_bootloados.kernel_addr = 0x00008000 ;
+ semi_sys_bootloados.rootfs_addr = 0x01000000 ;
+ semi_sys_bootloados.loading_type = 0;
+ semi_sys_bootloados.vector_mask = 0;
+ semi_sys_bootloados.is_semihosting = 0;
+
+ do_SemiSWI(SYS_BOOTLOADOS, &semi_sys_bootloados);
+}
+
+#endif /* CONFIG_ZDE_KERNEL_DEBUG */